Revision b018ff60857ee7d79e3c4a8772bac08656a2a3c6 authored by Jeff King on 29 December 2012, 20:51:54 UTC, committed by Junio C Hamano on 04 November 2013, 18:13:27 UTC
When we call "read-tree --reset -u HEAD ORIG_HEAD", the first thing we
do with the index is to call read_cache_unmerged.  Originally that
would read the index, leaving aside any unmerged entries.  However, as
of d1a43f2 (reset --hard/read-tree --reset -u: remove unmerged new
paths, 2008-10-15), it actually creates a new cache entry to serve as
a placeholder, so that we later know to update the working tree.

However, we later noticed that the sha1 of that unmerged entry was
just copied from some higher stage, leaving you with random content in
the index.  That was fixed by e11d7b5 ("reset --merge": fix unmerged
case, 2009-12-31), which instead puts the null sha1 into the newly
created entry, and sets a CE_CONFLICTED flag. At the same time, it
teaches the unpack-trees machinery to pay attention to this flag, so
that oneway_merge throws away the current value.

However, it did not update the code paths for twoway_merge, which is
where we end up in the two-way read-tree with --reset. We notice that
the HEAD and ORIG_HEAD versions are the same, and say "oh, we can just
reuse the current version". But that's not true. The current version
is bogus.

Notice this case and make sure we do not keep the bogus entry; either
we do not have that path in the tree we are moving to (i.e. remove
it), or we want to have the cache entry we created for the tree we are
moving to (i.e. resolve by explicitly saying the "newtree" version is
what we want).

[jc: this is from the almost year-old $gmane/212316]

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent c479d14
Raw File
t5306-pack-nobase.sh
#!/bin/sh
#
# Copyright (c) 2008 Google Inc.
#

test_description='git-pack-object with missing base

'
. ./test-lib.sh

# Create A-B chain
#
test_expect_success \
    'setup base' \
    'for a in a b c d e f g h i; do echo $a >>text; done &&
     echo side >side &&
     git update-index --add text side &&
     A=$(echo A | git commit-tree $(git write-tree)) &&

     echo m >>text &&
     git update-index text &&
     B=$(echo B | git commit-tree $(git write-tree) -p $A) &&
     git update-ref HEAD $B
    '

# Create repository with C whose parent is B.
# Repository contains C, C^{tree}, C:text, B, B^{tree}.
# Repository is missing B:text (best delta base for C:text).
# Repository is missing A (parent of B).
# Repository is missing A:side.
#
test_expect_success \
    'setup patch_clone' \
    'base_objects=$(pwd)/.git/objects &&
     (mkdir patch_clone &&
      cd patch_clone &&
      git init &&
      echo "$base_objects" >.git/objects/info/alternates &&
      echo q >>text &&
      git read-tree $B &&
      git update-index text &&
      git update-ref HEAD $(echo C | git commit-tree $(git write-tree) -p $B) &&
      rm .git/objects/info/alternates &&

      git --git-dir=../.git cat-file commit $B |
      git hash-object -t commit -w --stdin &&

      git --git-dir=../.git cat-file tree "$B^{tree}" |
      git hash-object -t tree -w --stdin
     ) &&
     C=$(git --git-dir=patch_clone/.git rev-parse HEAD)
    '

# Clone patch_clone indirectly by cloning base and fetching.
#
test_expect_success \
    'indirectly clone patch_clone' \
    '(mkdir user_clone &&
      cd user_clone &&
      git init &&
      git pull ../.git &&
      test $(git rev-parse HEAD) = $B &&

      git pull ../patch_clone/.git &&
      test $(git rev-parse HEAD) = $C
     )
    '

# Cloning the patch_clone directly should fail.
#
test_expect_success \
    'clone of patch_clone is incomplete' \
    '(mkdir user_direct &&
      cd user_direct &&
      git init &&
      test_must_fail git fetch ../patch_clone/.git
     )
    '

test_done
back to top