diff options
author | Junio C Hamano <junkio@cox.net> | 2005-06-07 11:36:30 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-07 11:41:51 -0700 |
commit | c859600954df4c292ec7c81d7f2f9d0a62b5975b (patch) | |
tree | 4c2f1d9fae4deff6e82d0f32f11cc14cd67093c3 /read-tree.c | |
parent | 63aff4fed94355889be98ad44371e29942ff70e4 (diff) | |
download | git-c859600954df4c292ec7c81d7f2f9d0a62b5975b.tar.gz git-c859600954df4c292ec7c81d7f2f9d0a62b5975b.tar.xz |
[PATCH] read-tree: save more user hassles during fast-forward.
This implements the "never lose the current cache information or
the work tree state, but favor a successful merge over merge
failure" principle in the fast-forward two-tree merge operation.
It comes with a set of tests to cover all the cases described in
the case matrix found in the new documentation.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'read-tree.c')
-rw-r--r-- | read-tree.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/read-tree.c b/read-tree.c index 2fb27e974..8eb243212 100644 --- a/read-tree.c +++ b/read-tree.c @@ -155,28 +155,51 @@ static int threeway_merge(struct cache_entry *stages[4], struct cache_entry **ds /* * Two-way merge. * - * The rule is: - * - every current entry has to match the old tree - * - if the current entry matches the new tree, we leave it - * as-is. Otherwise we require that it be up-to-date. + * The rule is to "carry forward" what is in the index without losing + * information across a "fast forward", favoring a successful merge + * over a merge failure when it makes sense. For details of the + * "carry forward" rule, please see <Documentation/git-read-tree.txt>. + * */ static int twoway_merge(struct cache_entry **src, struct cache_entry **dst) { - struct cache_entry *old = src[0]; - struct cache_entry *a = src[1], *b = src[2]; + struct cache_entry *current = src[0]; + struct cache_entry *oldtree = src[1], *newtree = src[2]; if (src[3]) return -1; - if (old) { - if (!a || !same(old, a)) + if (current) { + if ((!oldtree && !newtree) || /* 4 and 5 */ + (!oldtree && newtree && + same(current, newtree)) || /* 6 and 7 */ + (oldtree && newtree && + same(oldtree, newtree)) || /* 14 and 15 */ + (oldtree && newtree && + !same(oldtree, newtree) && /* 18 and 19*/ + same(current, newtree))) { + *dst++ = current; + return 1; + } + else if (oldtree && !newtree && same(current, oldtree)) { + /* 10 or 11 */ + verify_uptodate(current); + return 0; + } + else if (oldtree && newtree && + same(current, oldtree) && !same(current, newtree)) { + /* 20 or 21 */ + verify_uptodate(current); + return merged_entry(newtree, NULL, dst); + } + else + /* all other failures */ return -1; } - if (b) - return merged_entry(b, old, dst); - if (old) - verify_uptodate(old); - return 0; + else if (newtree) + return merged_entry(newtree, NULL, dst); + else + return 0; } /* |