reset [<commit>] paths...: do not mishandle unmerged paths

Because "diff --cached HEAD" showed an incorrect blob object name on the LHS of the diff, we ended up updating the index entry with bogus value, not what we read from the tree. Noticed by John Nowak. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jul 13, 2011 at 21:36 UTC ff00b682f203eb39876b57404916b4c54b6032c6
3 files changed +18 -2
builtin/reset.c
+1 -1
@@ -162,7 +162,7 @@ static void update_index_from_diff(struct diff_queue_struct *q,
162
163 for (i = 0; i < q->nr; i++) {
164 struct diff_filespec *one = q->queue[i]->one;
165 - if (one->mode) {
165 + if (one->mode && !is_null_sha1(one->sha1)) {
166 struct cache_entry *ce;
167 ce = make_cache_entry(one->mode, one->sha1, one->path,
168 0, 0);
diff-lib.c
+2 -1
@@ -379,7 +379,8 @@ static void do_oneway_diff(struct unpack_trees_options *o,
379 if (cached && idx && ce_stage(idx)) {
380 struct diff_filepair *pair;
381 pair = diff_unmerge(&revs->diffopt, idx->name);
382 - fill_filespec(pair->one, idx->sha1, idx->ce_mode);
382 + if (tree)
383 + fill_filespec(pair->one, tree->sha1, tree->ce_mode);
384 return;
385 }
386
t/t7102-reset.sh
+15
@@ -429,6 +429,21 @@ test_expect_success '--mixed refreshes the index' '
429 test_i18ncmp expect output
430 '
431
432 +test_expect_success 'resetting specific path that is unmerged' '
433 + git rm --cached file2 &&
434 + F1=$(git rev-parse HEAD:file1) &&
435 + F2=$(git rev-parse HEAD:file2) &&
436 + F3=$(git rev-parse HEAD:secondfile) &&
437 + {
438 + echo "100644 $F1 1 file2" &&
439 + echo "100644 $F2 2 file2" &&
440 + echo "100644 $F3 3 file2"
441 + } | git update-index --index-info &&
442 + git ls-files -u &&
443 + test_must_fail git reset HEAD file2 &&
444 + git diff-index --exit-code --cached HEAD
445 +'
446 +
447 test_expect_success 'disambiguation (1)' '
448
449 git reset --hard &&