Skip to content

Commit 34110cd

Browse files
torvaldsgitster
authored andcommitted
Make 'unpack_trees()' have a separate source and destination index
We will always unpack into our own internal index, but we will take the source from wherever specified, and we will optionally write the result to a specified index (optionally, because not everybody even _wants_ any result: the index diffing really wants to just walk the tree and index in parallel). This ends up removing a fair number more lines than it adds, for the simple reason that we can now skip all the crud that tried to be oh-so-careful about maintaining our position in the index as we were traversing and modifying it. Since we don't actually modify the source index any more, we can just update the 'o->pos' pointer without worrying about whether an index entry got removed or replaced or added to. Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bc052d7 commit 34110cd

File tree

8 files changed

+102
-153
lines changed

8 files changed

+102
-153
lines changed

builtin-checkout.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ static int reset_to_new(struct tree *tree, int quiet)
160160
opts.merge = 1;
161161
opts.fn = oneway_merge;
162162
opts.verbose_update = !quiet;
163-
opts.index = &the_index;
163+
opts.src_index = &the_index;
164+
opts.dst_index = &the_index;
164165
parse_tree(tree);
165166
init_tree_desc(&tree_desc, tree->buffer, tree->size);
166167
if (unpack_trees(1, &tree_desc, &opts))
@@ -180,7 +181,8 @@ static void reset_clean_to_new(struct tree *tree, int quiet)
180181
opts.merge = 1;
181182
opts.fn = oneway_merge;
182183
opts.verbose_update = !quiet;
183-
opts.index = &the_index;
184+
opts.src_index = &the_index;
185+
opts.dst_index = &the_index;
184186
parse_tree(tree);
185187
init_tree_desc(&tree_desc, tree->buffer, tree->size);
186188
if (unpack_trees(1, &tree_desc, &opts))
@@ -231,7 +233,8 @@ static int merge_working_tree(struct checkout_opts *opts,
231233

232234
memset(&topts, 0, sizeof(topts));
233235
topts.head_idx = -1;
234-
topts.index = &the_index;
236+
topts.src_index = &the_index;
237+
topts.dst_index = &the_index;
235238

236239
refresh_cache(REFRESH_QUIET);
237240

builtin-commit.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ static void create_base_index(void)
198198
opts.head_idx = 1;
199199
opts.index_only = 1;
200200
opts.merge = 1;
201-
opts.index = &the_index;
201+
opts.src_index = &the_index;
202+
opts.dst_index = &the_index;
202203

203204
opts.fn = oneway_merge;
204205
tree = parse_tree_indirect(head_sha1);

builtin-merge-recursive.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ static int git_merge_trees(int index_only,
213213
opts.merge = 1;
214214
opts.head_idx = 2;
215215
opts.fn = threeway_merge;
216-
opts.index = &the_index;
216+
opts.src_index = &the_index;
217+
opts.dst_index = &the_index;
217218

218219
init_tree_desc_from_tree(t+0, common);
219220
init_tree_desc_from_tree(t+1, head);

builtin-read-tree.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
102102

103103
memset(&opts, 0, sizeof(opts));
104104
opts.head_idx = -1;
105-
opts.index = &the_index;
105+
opts.src_index = &the_index;
106+
opts.dst_index = &the_index;
106107

107108
git_config(git_default_config);
108109

@@ -221,27 +222,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
221222
if ((opts.dir && !opts.update))
222223
die("--exclude-per-directory is meaningless unless -u");
223224

224-
if (opts.prefix) {
225-
int pfxlen = strlen(opts.prefix);
226-
int pos;
227-
if (opts.prefix[pfxlen-1] != '/')
228-
die("prefix must end with /");
229-
if (stage != 2)
230-
die("binding merge takes only one tree");
231-
pos = cache_name_pos(opts.prefix, pfxlen);
232-
if (0 <= pos)
233-
die("corrupt index file");
234-
pos = -pos-1;
235-
if (pos < active_nr &&
236-
!strncmp(active_cache[pos]->name, opts.prefix, pfxlen))
237-
die("subdirectory '%s' already exists.", opts.prefix);
238-
pos = cache_name_pos(opts.prefix, pfxlen-1);
239-
if (0 <= pos)
240-
die("file '%.*s' already exists.",
241-
pfxlen-1, opts.prefix);
242-
opts.pos = -1 - pos;
243-
}
244-
245225
if (opts.merge) {
246226
if (stage < 2)
247227
die("just how do you expect me to merge %d trees?", stage-1);

diff-lib.c

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,7 @@ static void mark_merge_entries(void)
600600
*/
601601
static void do_oneway_diff(struct unpack_trees_options *o,
602602
struct cache_entry *idx,
603-
struct cache_entry *tree,
604-
int idx_pos, int idx_nr)
603+
struct cache_entry *tree)
605604
{
606605
struct rev_info *revs = o->unpack_data;
607606
int match_missing, cached;
@@ -642,34 +641,6 @@ static void do_oneway_diff(struct unpack_trees_options *o,
642641
show_modified(revs, tree, idx, 1, cached, match_missing);
643642
}
644643

645-
/*
646-
* Count how many index entries go with the first one
647-
*/
648-
static inline int count_skip(const struct cache_entry *src, int pos)
649-
{
650-
int skip = 1;
651-
652-
/* We can only have multiple entries if the first one is not stage-0 */
653-
if (ce_stage(src)) {
654-
struct cache_entry **p = active_cache + pos;
655-
int namelen = ce_namelen(src);
656-
657-
for (;;) {
658-
const struct cache_entry *ce;
659-
pos++;
660-
if (pos >= active_nr)
661-
break;
662-
ce = *++p;
663-
if (ce_namelen(ce) != namelen)
664-
break;
665-
if (memcmp(ce->name, src->name, namelen))
666-
break;
667-
skip++;
668-
}
669-
}
670-
return skip;
671-
}
672-
673644
/*
674645
* The unpack_trees() interface is designed for merging, so
675646
* the different source entries are designed primarily for
@@ -685,18 +656,12 @@ static inline int count_skip(const struct cache_entry *src, int pos)
685656
* the fairly complex unpack_trees() semantic requirements, including
686657
* the skipping, the path matching, the type conflict cases etc.
687658
*/
688-
static int oneway_diff(struct cache_entry **src,
689-
struct unpack_trees_options *o,
690-
int index_pos)
659+
static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
691660
{
692-
int skip = 0;
693661
struct cache_entry *idx = src[0];
694662
struct cache_entry *tree = src[1];
695663
struct rev_info *revs = o->unpack_data;
696664

697-
if (index_pos >= 0)
698-
skip = count_skip(idx, index_pos);
699-
700665
/*
701666
* Unpack-trees generates a DF/conflict entry if
702667
* there was a directory in the index and a tree
@@ -707,9 +672,9 @@ static int oneway_diff(struct cache_entry **src,
707672
tree = NULL;
708673

709674
if (ce_path_match(idx ? idx : tree, revs->prune_data))
710-
do_oneway_diff(o, idx, tree, index_pos, skip);
675+
do_oneway_diff(o, idx, tree);
711676

712-
return skip;
677+
return 0;
713678
}
714679

715680
int run_diff_index(struct rev_info *revs, int cached)
@@ -734,7 +699,8 @@ int run_diff_index(struct rev_info *revs, int cached)
734699
opts.merge = 1;
735700
opts.fn = oneway_diff;
736701
opts.unpack_data = revs;
737-
opts.index = &the_index;
702+
opts.src_index = &the_index;
703+
opts.dst_index = NULL;
738704

739705
init_tree_desc(&t, tree->buffer, tree->size);
740706
if (unpack_trees(1, &t, &opts))
@@ -788,7 +754,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
788754
opts.merge = 1;
789755
opts.fn = oneway_diff;
790756
opts.unpack_data = &revs;
791-
opts.index = &the_index;
757+
opts.src_index = &the_index;
758+
opts.dst_index = &the_index;
792759

793760
init_tree_desc(&t, tree->buffer, tree->size);
794761
if (unpack_trees(1, &t, &opts))

t/t1005-read-tree-reset.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ test_expect_success 'setup' '
2121
git commit -m two
2222
'
2323

24-
test_expect_failure 'reset should work' '
24+
test_expect_success 'reset should work' '
2525
git read-tree -u --reset HEAD^ &&
2626
git ls-files >actual &&
2727
diff -u expect actual

0 commit comments

Comments
 (0)