提交 43f91266 编写于 作者: L Linus Torvalds

Make 'read-tree' do a few more of the trivial merge cases.

This cuts down the work for the "real merge" to stuff where
people might actually disagree on the algorithm. The trivial
cases would seem to be totally independent of any policy.
上级 aee46198
......@@ -73,26 +73,61 @@ static void remove_lock_file(void)
unlink(".git/index.lock");
}
static int same(struct cache_entry *a, struct cache_entry *b)
{
return a->ce_mode == b->ce_mode &&
!memcmp(a->sha1, b->sha1, 20);
}
/*
* This removes all identical entries and collapses them to state 0.
* This removes all trivial merges that don't change the tree
* and collapses them to state 0.
*
* _Any_ other merge (even a trivial one, like both ) is left to user policy.
* That includes "both created the same file", and "both removed the same
* file" - which are trivial, but the user might still want to _note_ it.
* _Any_ other merge is left to user policy. That includes "both
* created the same file", and "both removed the same file" - which are
* trivial, but the user might still want to _note_ it.
*/
static int same_entry(struct cache_entry *a,
struct cache_entry *b,
struct cache_entry *c)
static struct cache_entry *merge_entries(struct cache_entry *a,
struct cache_entry *b,
struct cache_entry *c)
{
int len = ce_namelen(a);
return a->ce_mode == b->ce_mode &&
a->ce_mode == c->ce_mode &&
ce_namelen(b) == len &&
ce_namelen(c) == len &&
!memcmp(a->name, b->name, len) &&
!memcmp(a->name, c->name, len) &&
!memcmp(a->sha1, b->sha1, 20) &&
!memcmp(a->sha1, c->sha1, 20);
/*
* Are they all the same filename? We won't do
* any name merging
*/
if (ce_namelen(b) != len ||
ce_namelen(c) != len ||
memcmp(a->name, b->name, len) ||
memcmp(a->name, c->name, len))
return NULL;
/*
* Ok, all three entries describe the same
* filename, but maybe the contents or file
* mode have changed?
*
* The trivial cases end up being the ones where two
* out of three files are the same:
* - both destinations the same, trivially take either
* - one of the destination versions hasn't changed,
* take the other.
*
* The "all entries exactly the same" case falls out as
* a special case of any of the "two same" cases.
*
* Here "a" is "original", and "b" and "c" are the two
* trees we are merging.
*/
if (same(b,c))
return c;
if (same(a,b))
return c;
if (same(a,c))
return b;
return NULL;
}
static void trivially_merge_cache(struct cache_entry **src, int nr)
......@@ -100,10 +135,11 @@ static void trivially_merge_cache(struct cache_entry **src, int nr)
struct cache_entry **dst = src;
while (nr) {
struct cache_entry *ce;
struct cache_entry *ce, *result;
ce = src[0];
if (nr > 2 && same_entry(ce, src[1], src[2])) {
if (nr > 2 && (result = merge_entries(ce, src[1], src[2])) != NULL) {
ce = result;
ce->ce_flags &= ~htons(CE_STAGEMASK);
src += 2;
nr -= 2;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册