Browse Source

Make "read-tree" take the 'stat' information for a merge result from the

old index state if the result matches.

This leaves the stat information in the result tree for any trivial
merges, which is just the way we like it.
maint
Linus Torvalds 20 years ago
parent
commit
ca016f0e4e
  1. 41
      read-tree.c

41
read-tree.c

@ -73,6 +73,13 @@ static void remove_lock_file(void) @@ -73,6 +73,13 @@ static void remove_lock_file(void)
unlink(".git/index.lock");
}

static int path_matches(struct cache_entry *a, struct cache_entry *b)
{
int len = ce_namelen(a);
return ce_namelen(b) == len &&
!memcmp(a->name, b->name, len);
}

static int same(struct cache_entry *a, struct cache_entry *b)
{
return a->ce_mode == b->ce_mode &&
@ -132,13 +139,30 @@ static struct cache_entry *merge_entries(struct cache_entry *a, @@ -132,13 +139,30 @@ static struct cache_entry *merge_entries(struct cache_entry *a,

static void trivially_merge_cache(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, *result;

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 (nr > 2 && (result = merge_entries(ce, src[1], src[2])) != NULL) {
/*
* See if we can re-use the old CE directly?
* That way we get the uptodate stat info.
*/
if (path_matches(result, old) && same(result, old))
*result = *old;
ce = result;
ce->ce_flags &= ~htons(CE_STAGEMASK);
src += 2;
@ -154,7 +178,7 @@ static void trivially_merge_cache(struct cache_entry **src, int nr) @@ -154,7 +178,7 @@ static void trivially_merge_cache(struct cache_entry **src, int nr)

int main(int argc, char **argv)
{
int i, newfd;
int i, newfd, merge;
unsigned char sha1[20];

newfd = open(".git/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
@ -163,12 +187,22 @@ int main(int argc, char **argv) @@ -163,12 +187,22 @@ int main(int argc, char **argv)
atexit(remove_lock_file);
remove_lock = 1;

merge = 0;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];

/* "-m" stands for "merge", meaning we start in stage 1 */
if (!strcmp(arg, "-m")) {
int i;
if (stage)
usage("-m needs to come first");
read_cache();
for (i = 0; i < active_nr; i++) {
if (ce_stage(active_cache[i]))
usage("you need to resolve your current index first");
}
stage = 1;
merge = 1;
continue;
}
if (get_sha1_hex(arg, sha1) < 0)
@ -179,8 +213,11 @@ int main(int argc, char **argv) @@ -179,8 +213,11 @@ int main(int argc, char **argv)
die("failed to unpack tree object %s", arg);
stage++;
}
if (stage == 4)
if (merge) {
if (stage != 4)
usage("I need three trees to merge: original, branch1 and branch2");
trivially_merge_cache(active_cache, active_nr);
}
if (write_cache(newfd, active_cache, active_nr) ||
rename(".git/index.lock", ".git/index"))
die("unable to write new index file");

Loading…
Cancel
Save