Skip to content

Commit 7551391

Browse files
committed
Merge branch 'jc/unpack-trees'
* jc/unpack-trees: unpack_trees(): skip trees that are the same in all input unpack-trees.c: cosmetic fix Conflicts: unpack-trees.c
2 parents 7fb9ec2 + 83c9031 commit 7551391

File tree

1 file changed

+62
-2
lines changed

1 file changed

+62
-2
lines changed

unpack-trees.c

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ static void add_same_unmerged(struct cache_entry *ce,
381381
static int unpack_index_entry(struct cache_entry *ce,
382382
struct unpack_trees_options *o)
383383
{
384-
struct cache_entry *src[5] = { NULL };
384+
struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
385385
int ret;
386386

387387
src[0] = ce;
@@ -427,14 +427,26 @@ static int switch_cache_bottom(struct traverse_info *info)
427427
return ret;
428428
}
429429

430-
static int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info)
430+
static int fast_forward_merge(int n, unsigned long dirmask,
431+
struct name_entry *names,
432+
struct traverse_info *info);
433+
434+
static int traverse_trees_recursive(int n, unsigned long dirmask,
435+
unsigned long df_conflicts,
436+
struct name_entry *names,
437+
struct traverse_info *info)
431438
{
432439
int i, ret, bottom;
433440
struct tree_desc t[MAX_UNPACK_TREES];
434441
void *buf[MAX_UNPACK_TREES];
435442
struct traverse_info newinfo;
436443
struct name_entry *p;
437444

445+
if (!df_conflicts) {
446+
int status = fast_forward_merge(n, dirmask, names, info);
447+
if (status)
448+
return status;
449+
}
438450
p = names;
439451
while (!p->mode)
440452
p++;
@@ -682,6 +694,53 @@ static struct cache_entry *find_cache_entry(struct traverse_info *info,
682694
return NULL;
683695
}
684696

697+
static int fast_forward_merge(int n, unsigned long dirmask,
698+
struct name_entry *names,
699+
struct traverse_info *info)
700+
{
701+
int i;
702+
struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
703+
struct unpack_trees_options *o = info->data;
704+
705+
/* merging two or more trees with an identical subdirectory? */
706+
if ((n < 2) || ((1UL << n) - 1) != dirmask ||
707+
!o->merge || o->reset || o->initial_checkout)
708+
return 0;
709+
for (i = 1; i < n; i++)
710+
if (hashcmp(names[i-1].sha1, names[i].sha1))
711+
return 0;
712+
713+
/*
714+
* Instead of descending into the directory, keep the contents
715+
* of the current index.
716+
*/
717+
while (1) {
718+
struct cache_entry *ce;
719+
ce = next_cache_entry(o);
720+
if (!ce)
721+
break;
722+
/* Is the entry still in that directory? */
723+
if (do_compare_entry(ce, info, names))
724+
break;
725+
/*
726+
* Note: we do not just run unpack_index_entry() here,
727+
* as the callback may want to compare what is in the
728+
* index with what are from the HEAD and the other tree
729+
* and reject the merge. We pretend that ancestors, the
730+
* HEAD and the other tree all have the same contents as
731+
* the current index, which is a lie, but it works.
732+
*/
733+
for (i = 0; i < n + 1; i++)
734+
src[i] = ce;
735+
mark_ce_used(ce, o);
736+
if (call_unpack_fn(src, o) < 0)
737+
return unpack_failed(o, NULL);
738+
if (ce_stage(ce))
739+
mark_ce_used_same_name(ce, o);
740+
}
741+
return dirmask;
742+
}
743+
685744
static void debug_path(struct traverse_info *info)
686745
{
687746
if (info->prev) {
@@ -1105,6 +1164,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
11051164

11061165
}
11071166
if (o->result.cache_nr && empty_worktree) {
1167+
/* dubious---why should this fail??? */
11081168
ret = unpack_failed(o, "Sparse checkout leaves no entry on working directory");
11091169
goto done;
11101170
}

0 commit comments

Comments
 (0)