Sanjoy Mahajan <[EMAIL PROTECTED]> writes:

> I'm having doing a stupidity with git, but here's what is confusing me
> about using bisect:
> If I start with a clean directory except for a 2.6 .git/ (where master =
> d95a1b4818f2fe38a3cfc9a7d5817dc9a1a69329), then do
> $ cd linux-2.6
> $ ls
> $ cat .git/HEAD
> d95a1b4818f2fe38a3cfc9a7d5817dc9a1a69329
> $ git bisect start
> $ git bisect good 17af691cd19765b782d891fc50c1568d0f1276b3
> $ git bisect bad c101f3136cc98a003d0d16be6fab7d0d950581a6  
> Bisecting: 42 revisions left to test after this
> $ ls
> arch   Documentation  include  kernel       Makefile  README    sound
> CREDITS  drivers      init     lib          mm        scripts
> crypto         fs             ipc      MAINTAINERS  net       security
> What happened to, for example, COPYING?  Maybe I am doing something
> silly (which I did before so I didn't get the right kernel trees to
> compile?).  If I do 'git reset' first, then COPYING is there.

Although I think what you saw is pathological, I do not think it
is what you did that is wrong.  The same thing happens if you
have .git/HEAD pointing at some version, you have nothing
checked out, and "git pull" from the upstream which results in a
fast forward merge.  Only the files that have been changed
between ORIG_HEAD and FETCH_HEAD are checked out.

What is happening is that git-checkout-script, which uses
"git-read-tree -m -u", checks out only the files that have
changed between the "current suspect" version and "next suspect"
version, leaving other paths untouched.  This means that if
"other paths" were not in the working tree to begin with, they
are left not-checked-out.

This is because the 'git-read-tree -m A B' is designed to allow
two-tree fast-forward merge work safely in a working tree that
has local modifications.  The local modification in your case is
that "you removed all files".  This is further complicated by
that the low-level git design wants to work in a non-populated
tree and treats not having a file in the working tree a bit
differently from having a file that is modified in the working
tree.  read-tree.c::verify_uptodate() function says when you
removed a file that is recorded in the index, it does not
consider you have a local modification on that path.

The paths that were not checked out fall in the case 14 in the
Documentation/git-read-tree.txt "Two Tree Merge" table, and the
path is not marked for update in "keep index" cases.

Although I think what git-read-tree currently does is
defensible, I do not think what "git checkout" does is.  The
user is asking things to be checked out so it is not a "work
without files in working tree" case anymore.

Maybe we should check if the working tree is clean before using
git-read-tree -m -u and require --force if it is not, perhaps?

The following patch is not tested at all but I am throwing it
out in the open early, in case the approach I am taking is
totally going in the wrong direction.

cd /opt/packrat/playpen/public/in-place/git/git.junio/
# - pu: Debian packaging fixes.
# + (working tree)
diff --git a/git-checkout-script b/git-checkout-script
--- a/git-checkout-script
+++ b/git-checkout-script
@@ -56,7 +56,9 @@ then
     git-read-tree --reset $new &&
        git-checkout-cache -q -f -u -a
-    git-read-tree -m -u $old $new
+    git-update-cache --refresh &&
+    git-read-tree -m -u $old $new ||
+       die "git checkout: your working tree is dirty"
diff --git a/read-tree.c b/read-tree.c
--- a/read-tree.c
+++ b/read-tree.c
@@ -86,7 +86,7 @@ static void verify_uptodate(struct cache
                errno = 0;
-       if (errno == ENOENT)
+       if (errno == ENOENT && !update)
        die("Entry '%s' not uptodate. Cannot merge.", ce->name);

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to