Subject: Re: [PATCH] Add test that checkout does not overwrite entries in .git/info/exclude

From: Nguyen Thai Ngoc Duy <[email-masked]>
Date: Mon, 21 Nov 2011 15:17:01 +0700

On Mon, Nov 21, 2011 at 08:23:45AM +0100, Johannes Sixt wrote:
> From: Johannes Sixt <[email-masked]>
> 
> It is an unintended accident that entries matched by .git/info/exclude are
> considered precious, but entries matched by .gitignore are not. That is,
> 'git checkout' will overwrite untracked files matched by .gitignore, but
> refuses to overwrite files matched by .git/info/exclude.
> 
> It is a lucky accident: it allows the distinction between "untracked but
> precious" and "untracked and garbage". And it is a doubly lucky accident:
> .gitignore entries are meant for files like build products, which usually
> affect all consumers of a repository, whereas .git/info/exclude is
> intended for personal files, which frequently are precious (think of a
> TODO file).
> 
> Add a test that codifies the accident as wanted behavior.

If you want to keep this accident (which is a bug to me), you may want
to add the reason: callers to unpack_trees() are supposed to also
setup exclude rules in .git/info/exclude before calling
unpack_trees(), which they don't.

So .git/info/exclude is entirely dismissed. This patch makes t2023.3
fail. I haven't dug into history to see if this is on purpose though.

-- 8< --
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2a80772..c2fc2ba 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -412,6 +412,8 @@ 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";
+		if (!access(git_path("info/exclude"), R_OK))
+			add_excludes_from_file(topts.dir, git_path("info/exclude"));
 		tree = parse_tree_indirect(old->commit ?
 					   old->commit->object.sha1 :
 					   EMPTY_TREE_SHA1_BIN);
-- 8< --
--
Duy