Merge branch 'en/merge-recursive-fixes'
authorJunio C Hamano <gitster@pobox.com>
Thu, 15 Feb 2018 22:55:40 +0000 (14:55 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 15 Feb 2018 22:55:40 +0000 (14:55 -0800)
* en/merge-recursive-fixes:
  merge-recursive: add explanation for src_entry and dst_entry
  merge-recursive: fix logic ordering issue
  Tighten and correct a few testcases for merging and cherry-picking

1  2 
merge-recursive.c

diff --combined merge-recursive.c
@@@ -513,6 -513,25 +513,25 @@@ static void record_df_conflict_files(st
  
  struct rename {
        struct diff_filepair *pair;
+       /*
+        * Purpose of src_entry and dst_entry:
+        *
+        * If 'before' is renamed to 'after' then src_entry will contain
+        * the versions of 'before' from the merge_base, HEAD, and MERGE in
+        * stages 1, 2, and 3; dst_entry will contain the respective
+        * versions of 'after' in corresponding locations.  Thus, we have a
+        * total of six modes and oids, though some will be null.  (Stage 0
+        * is ignored; we're interested in handling conflicts.)
+        *
+        * Since we don't turn on break-rewrites by default, neither
+        * src_entry nor dst_entry can have all three of their stages have
+        * non-null oids, meaning at most four of the six will be non-null.
+        * Also, since this is a rename, both src_entry and dst_entry will
+        * have at least one non-null oid, meaning at least two will be
+        * non-null.  Of the six oids, a typical rename will have three be
+        * non-null.  Only two implies a rename/delete, and four implies a
+        * rename/add.
+        */
        struct stage_data *src_entry;
        struct stage_data *dst_entry;
        unsigned processed:1;
@@@ -1026,19 -1045,10 +1045,19 @@@ static int merge_file_1(struct merge_op
                                                       &b->oid,
                                                       !o->call_depth);
                } else if (S_ISLNK(a->mode)) {
 -                      oidcpy(&result->oid, &a->oid);
 -
 -                      if (!oid_eq(&a->oid, &b->oid))
 -                              result->clean = 0;
 +                      switch (o->recursive_variant) {
 +                      case MERGE_RECURSIVE_NORMAL:
 +                              oidcpy(&result->oid, &a->oid);
 +                              if (!oid_eq(&a->oid, &b->oid))
 +                                      result->clean = 0;
 +                              break;
 +                      case MERGE_RECURSIVE_OURS:
 +                              oidcpy(&result->oid, &a->oid);
 +                              break;
 +                      case MERGE_RECURSIVE_THEIRS:
 +                              oidcpy(&result->oid, &b->oid);
 +                              break;
 +                      }
                } else
                        die("BUG: unsupported object type in the tree");
        }
@@@ -1998,10 -2008,10 +2017,10 @@@ int merge_trees(struct merge_options *o
                get_files_dirs(o, merge);
  
                entries = get_unmerged();
-               record_df_conflict_files(o, entries);
                re_head  = get_renames(o, head, common, head, merge, entries);
                re_merge = get_renames(o, merge, common, head, merge, entries);
                clean = process_renames(o, re_head, re_merge);
+               record_df_conflict_files(o, entries);
                if (clean < 0)
                        goto cleanup;
                for (i = entries->nr-1; 0 <= i; i--) {