ll-merge: make flag easier to populate
authorJonathan Nieder <jrnieder@gmail.com>
Thu, 5 Aug 2010 11:17:38 +0000 (06:17 -0500)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 Aug 2010 16:20:01 +0000 (09:20 -0700)
ll_merge() takes its options in a flag word, which has a few
advantages:

 - options flags can be cheaply passed around in registers, while
   an option struct passed by pointer cannot;

 - callers can easily pass 0 without trouble for no options,
   while an option struct passed by value would not allow that.

The downside is that code to populate and access the flag word can be
somewhat opaque.  Mitigate that with a few macros.

Cc: Avery Pennarun <apenwarr@gmail.com>
Cc: Bert Wesarg <bert.wesarg@googlemail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-merge.txt
ll-merge.c
ll-merge.h
merge-recursive.c

index 01a89d6d0be0675cc8dcd4272b5c4c69b702045f..a7e050bb7acb59764c851b09cd488b6620c0a2dd 100644 (file)
@@ -49,12 +49,15 @@ supports this.
 
 The `flag` parameter is a bitfield:
 
- - The least significant bit indicates whether this is an internal
-   merge to consolidate ancestors for a recursive merge.
+ - The `LL_OPT_VIRTUAL_ANCESTOR` bit indicates whether this is an
+   internal merge to consolidate ancestors for a recursive merge.
 
- - The next two bits allow local conflicts to be automatically
+ - The `LL_OPT_FAVOR_MASK` bits allow local conflicts to be automatically
    resolved in favor of one side or the other (as in 'git merge-file'
-   `--ours`/`--theirs`/`--union` for 01, 10, and 11, respectively).
+   `--ours`/`--theirs`/`--union`).
+   They can be populated by `create_ll_flag`, whose argument can be
+   `XDL_MERGE_FAVOR_OURS`, `XDL_MERGE_FAVOR_THEIRS`, or
+   `XDL_MERGE_FAVOR_UNION`.
 
 Everything else
 ---------------
index 5068fe069faeef07363407c622624264c5cf3a6c..290f764f564bdb3e046aa388d655210f3c9cb9f8 100644 (file)
@@ -46,7 +46,7 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
         * or common ancestor for an internal merge.  Still return
         * "conflicted merge" status.
         */
-       mmfile_t *stolen = (flag & 01) ? orig : src1;
+       mmfile_t *stolen = (flag & LL_OPT_VIRTUAL_ANCESTOR) ? orig : src1;
 
        result->ptr = stolen->ptr;
        result->size = stolen->size;
@@ -79,7 +79,7 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
 
        memset(&xmp, 0, sizeof(xmp));
        xmp.level = XDL_MERGE_ZEALOUS;
-       xmp.favor= (flag >> 1) & 03;
+       xmp.favor = ll_opt_favor(flag);
        if (git_xmerge_style >= 0)
                xmp.style = git_xmerge_style;
        if (marker_size > 0)
@@ -99,7 +99,8 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused,
                          int flag, int marker_size)
 {
        /* Use union favor */
-       flag = (flag & 1) | (XDL_MERGE_FAVOR_UNION << 1);
+       flag = (flag & LL_OPT_VIRTUAL_ANCESTOR) |
+              create_ll_flag(XDL_MERGE_FAVOR_UNION);
        return ll_xdl_merge(drv_unused, result, path_unused,
                            orig, NULL, src1, NULL, src2, NULL,
                            flag, marker_size);
@@ -342,7 +343,7 @@ int ll_merge(mmbuffer_t *result_buf,
        const char *ll_driver_name = NULL;
        int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
        const struct ll_merge_driver *driver;
-       int virtual_ancestor = flag & 01;
+       int virtual_ancestor = flag & LL_OPT_VIRTUAL_ANCESTOR;
 
        if (merge_renormalize) {
                normalize_file(ancestor, path);
index 57754cc8ca7b378a86b168a4fd6299fa3dfba045..5990271dce38a7f965264615d3e612f1b1210fd8 100644 (file)
@@ -5,6 +5,20 @@
 #ifndef LL_MERGE_H
 #define LL_MERGE_H
 
+#define LL_OPT_VIRTUAL_ANCESTOR        (1 << 0)
+#define LL_OPT_FAVOR_MASK      ((1 << 1) | (1 << 2))
+#define LL_OPT_FAVOR_SHIFT 1
+
+static inline int ll_opt_favor(int flag)
+{
+       return (flag & LL_OPT_FAVOR_MASK) >> LL_OPT_FAVOR_SHIFT;
+}
+
+static inline int create_ll_flag(int favor)
+{
+       return ((favor << LL_OPT_FAVOR_SHIFT) & LL_OPT_FAVOR_MASK);
+}
+
 int ll_merge(mmbuffer_t *result_buf,
             const char *path,
             mmfile_t *ancestor, const char *ancestor_label,
index 8a49844c909478f0e5bf379e62f22555767d0b4c..c0c9f0ccc46a7e0c63d5445bcb6fa4927124dff2 100644 (file)
@@ -647,7 +647,8 @@ static int merge_3way(struct merge_options *o,
 
        merge_status = ll_merge(result_buf, a->path, &orig, base_name,
                                &src1, name1, &src2, name2,
-                               (!!o->call_depth) | (favor << 1));
+                               ((o->call_depth ? LL_OPT_VIRTUAL_ANCESTOR : 0) |
+                                create_ll_flag(favor)));
 
        free(name1);
        free(name2);