On Mon, Aug 24, 2009 at 04:20:12PM -0700, Junio C Hamano wrote: > I do not think that this is the correct fix, but it should be a good start > for other people to take a look at the issue. With this change, any > leftover work tree files will remain, but it has an interesting effect. > > $ git checkout maint > $ echo 'ref: refs/heads/nosuch' >.git/HEAD > $ git checkout -b foo master > > You will notice that the index matches master (as expected), but the work > tree mostly matches maint. Knowing what these files are (i.e. "these are > git.git source files that match 'maint' branch, and are vastly behind what > are in 'master' branch we are switching to"), this result is utterly > counterintuitive and feels wrong, but if you consider a case like what > Dscho brought up originally in the thread of having a freshly initialized > empty repository with some uncommitted files, totally unrelated to what > you are checking out, I think you could argue that it is the right thing. I don't think this is the right thing to do. We have _no_ current branch, which means that everything in the working tree can be considered untracked (and therefore precious). So I think the right thing to do is barf and say "this untracked file would be overwritten". The user can sort it out as appropriate, either deleting files that are in the way, or using "-f" themselves (after they make the decision that what they have can be overwritten). Something like the patch below seems to work on the test case I posted earlier, and passes the test suite (but other than that, I am very unconfident, never having really looked at the checkout code before). As an aside, if an unborn branch stops implying "-f", should we bother even mentioning it? It seems superfluous now. --- diff --git a/builtin-checkout.c b/builtin-checkout.c index 8a9a474..1f2f84d 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -402,7 +402,9 @@ static int merge_working_tree(struct checkout_opts *opts, topts.dir = xcalloc(1, sizeof(*topts.dir)); topts.dir->flags |= DIR_SHOW_IGNORED; topts.dir->exclude_per_dir = ".gitignore"; - tree = parse_tree_indirect(old->commit->object.sha1); + tree = parse_tree_indirect(old->commit ? + old->commit->object.sha1 : + (unsigned char *)EMPTY_TREE_SHA1_BIN); init_tree_desc(&trees[0], tree->buffer, tree->size); tree = parse_tree_indirect(new->commit->object.sha1); init_tree_desc(&trees[1], tree->buffer, tree->size); @@ -541,13 +543,8 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new) parse_commit(new->commit); } - if (!old.commit && !opts->force) { - if (!opts->quiet) { - warning("You appear to be on a branch yet to be born."); - warning("Forcing checkout of %s.", new->name); - } - opts->force = 1; - } + if (!old.commit && !opts->force && !opts->quiet) + warning("You appear to be on a branch yet to be born."); ret = merge_working_tree(opts, &old, new); if (ret) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html