git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3] Add an explicit GIT_DIR to the list of excludes

From
PBPasha Bolokhov <pasha.bolokhov@gmail.com>
Date
May 23, 2014, 17:33 UTC
Message-ID
<1400866411-14584-1-git-send-email-pasha.bolokhov@gmail.com>

When an explicit '--git-dir' option points to a directory inside the work tree, git treats it as if it were any other directory. In particular, 'git status' lists it as untracked, while 'git add -A' stages the metadata directory entirely

Add GIT_DIR to the list of excludes in setup_standard_excludes(), while checking that GIT_DIR is not just '.git', in which case it would be ignored by default, and that GIT_DIR is inside GIT_WORK_TREE

Although an analogous comparison of any given path against '.git' is done in treat_path(), this does not seem to be the right place to compare against GIT_DIR. Instead, the excludes provide an effective mechanism of ignoring a file/directory, and adding GIT_DIR as an exclude is equivalent of putting it into '.gitignore'. Function setup_standard_excludes() was chosen because that is the place where the excludes are initialized by the commands that are concerned about excludes

Signed-off-by: Pasha Bolokhov <pasha.bolokhov@gmail.com>
---
Slightly brush-up comments, and fix ">file" style in the test, together
with fixing the &&-chain.
One thing is, when you do "git --git-dir meta init", and then explicitly
say "add meta/", the message you get is
"The following paths are ignored by one of your .gitignore files:"
which is not exactly correct.
 Documentation/technical/api-directory-listing.txt |  4 +-
 dir.c                                             | 20 ++++++
 t/t2205-add-gitdir.sh                             | 84 +++++++++++++++++++++++
 3 files changed, 106 insertions(+), 2 deletions(-)
 create mode 100755 t/t2205-add-gitdir.sh
diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt
index 7f8e78d..fd4a178 100644
--- a/Documentation/technical/api-directory-listing.txt
+++ b/Documentation/technical/api-directory-listing.txt
@@ -90,8 +90,8 @@ marked. If you to exclude files, make sure you have loaded index first.
   `add_exclude()`.
 
 * To add patterns from a file (e.g. `.git/info/exclude`), call
-  `add_excludes_from_file()` , and/or set `dir.exclude_per_dir`.  A
-  short-hand function `setup_standard_excludes()` can be used to set
+  `add_excludes_from_file()` , and/or set `dir.exclude_per_dir`.  The
+  short-hand function `setup_standard_excludes()` must be used to set
   up the standard set of exclude settings.
 
 * Set options described in the Data Structure section above.
diff --git a/dir.c b/dir.c
index 98bb50f..76969a7 100644
--- a/dir.c
+++ b/dir.c
@@ -1588,6 +1588,26 @@ void setup_standard_excludes(struct dir_struct *dir)
 {
 	const char *path;
 	char *xdg_path;
+	const char *gitdir = get_git_dir();
+
+	/* Add git directory to the ignores first */
+	if (strcmp(gitdir, ".git") != 0) { /* "--git-dir" has been given */
+		char ngit[PATH_MAX + 1];
+
+		/*
+		 * See if GIT_DIR is inside the work tree; need to normalize
+		 * 'gitdir', whereas 'get_git_work_tree()' always appears
+		 * absolute and normalized
+		 */
+		normalize_path_copy(ngit, real_path(absolute_path(gitdir)));
+
+		if (dir_inside_of(ngit, get_git_work_tree()) >= 0) {
+			struct exclude_list *el = add_exclude_list(dir, EXC_CMDL,
+							"--git-dir option");
+
+			add_exclude(gitdir, "", 0, el, 0);
+		}
+	}
 
 	dir->exclude_per_dir = ".gitignore";
 	path = git_path("info/exclude");
diff --git a/t/t2205-add-gitdir.sh b/t/t2205-add-gitdir.sh
new file mode 100755
index 0000000..0c99508
--- /dev/null
+++ b/t/t2205-add-gitdir.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+#
+# Copyright (c) 2014 Pasha Bolokhov
+#
+
+test_description='alternative repository path specified by --git-dir is ignored by add and status'
+
+. ./test-lib.sh
+
+#
+# Create a tree:
+#
+# 	a  b  c  d  subdir/
+#
+# subdir:
+# 	e  f  g  h  meta/  ssubdir/
+#
+# subdir/meta:
+# 	aa
+#
+# subdir/ssubdir:
+# 	meta/
+#
+# subdir/ssubdir/meta:
+# 	aaa
+#
+# Name the repository "meta" and see whether or not "git status" includes
+# or ignores directories named "meta". The slightly deeper hierarchy is
+# needed in order to be able to put the repository into "../meta", that is,
+# outside the work tree and still have files called "meta" within the tree
+#
+
+test_expect_success "setup" '
+	git --git-dir=meta init &&
+	for f in a b c d
+	do
+		echo "DATA" >"$f" || exit 1
+	done &&
+	mkdir subdir &&
+	for f in e f g h
+	do
+		echo "MORE DATA" >"subdir/$f" || exit 1
+	done &&
+	mkdir subdir/meta &&
+	echo "EVEN more Data" >subdir/meta/aa &&
+	mkdir subdir/ssubdir subdir/ssubdir/meta &&
+	echo "So much more data" >subdir/ssubdir/meta/aaa
+'
+
+test_expect_success "'git status' ignores the repository directory" '
+	git --git-dir=meta --work-tree=. status --porcelain >status.out &&
+	test_might_fail grep meta status.out >out &&
+	! test -s out
+'
+
+test_expect_success "'git add -A' ignores the repository directory" '
+	git --git-dir=meta --work-tree=. add -A &&
+	git --git-dir=meta --work-tree=. status --porcelain >status1.out &&
+	test_might_fail grep meta status1.out >out1 &&
+	! test -s out1
+'
+
+test_expect_success "'git status' acknowledges files 'meta' if repository is not within work tree" '
+	test_might_fail rm -rf meta/ &&
+	(
+		cd subdir &&
+		git --git-dir=../meta init &&
+		git --git-dir=../meta --work-tree=. status --porcelain >status2.out &&
+		test_might_fail grep meta status2.out >out2 &&
+		test -s out2
+	)
+'
+
+test_expect_success "'git add -A' adds 'meta' if the repository is outside the work tree" '
+	(
+		cd subdir &&
+		git --git-dir=../meta --work-tree=. add -A &&
+		git --git-dir=../meta --work-tree=. status --porcelain >status3.out &&
+		test_might_fail grep meta status3.out >out3 &&
+		test -s out3
+	)
+'
+
+test_done
-- 
1.9.1
Next: Junio C Hamano
Message 1 of 10 in “Add an explicit GIT_DIR to the list of excludes”
  1. Add an explicit GIT_DIR to the list of excludesPasha Bolokhov, May 23, 2014
  2. Junio C HamanoMay 23, 2014
  3. Pasha BolokhovMay 23, 2014
  4. Duy NguyenMay 24, 2014
  5. Pasha BolokhovMay 27, 2014
  6. Jakub NarębskiMay 28, 2014
  7. Pasha BolokhovMay 29, 2014
  8. Jakub NarębskiMay 29, 2014
  9. Junio C HamanoMay 27, 2014
  10. Pasha BolokhovMay 27, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.