aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--read-tree.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/read-tree.c b/read-tree.c
index abb522550..46747b5e9 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -169,9 +169,36 @@ static void trivially_merge_cache(struct cache_entry **src, int nr)
nr -= 2;
active_nr -= 2;
}
- *dst = ce;
+ *dst++ = ce;
+ src++;
+ nr--;
+ }
+}
+
+static void merge_stat_info(struct cache_entry **src, int nr)
+{
+ static struct cache_entry null_entry;
+ struct cache_entry **dst = src;
+ struct cache_entry *old = &null_entry;
+
+ while (nr) {
+ struct cache_entry *ce;
+
+ ce = src[0];
+
+ /* We throw away original cache entries except for the stat information */
+ if (!ce_stage(ce)) {
+ old = ce;
+ src++;
+ nr--;
+ active_nr--;
+ continue;
+ }
+ if (path_matches(ce, old) && same(ce, old))
+ *ce = *old;
+ ce->ce_flags &= ~htons(CE_STAGEMASK);
+ *dst++ = ce;
src++;
- dst++;
nr--;
}
}
@@ -214,9 +241,16 @@ int main(int argc, char **argv)
stage++;
}
if (merge) {
- if (stage != 4)
- usage("I need three trees to merge: original, branch1 and branch2");
- trivially_merge_cache(active_cache, active_nr);
+ switch (stage) {
+ case 4: /* Three-way merge */
+ trivially_merge_cache(active_cache, active_nr);
+ break;
+ case 2: /* Just read a tree, merge with old cache contents */
+ merge_stat_info(active_cache, active_nr);
+ break;
+ default:
+ die("just how do you expect me to merge %d trees?", stage-1);
+ }
}
if (write_cache(newfd, active_cache, active_nr) ||
rename(".git/index.lock", ".git/index"))