Re: [PATCH v5] Add an explicit GIT_DIR to the list of excludes

2014-06-11 Thread Duy Nguyen
On Tue, Jun 10, 2014 at 10:18 AM, Pasha Bolokhov
 wrote:
>> On Thu, Jun 5, 2014 at 3:15 AM, Pasha Bolokhov  
>> wrote:
>>> +   /* only add it if GIT_DIR does not end with '.git' or '/.git' */
>>> +   if (len < 4 || strcmp(n_git + len - 4, ".git") ||
>>> +   (len > 4 && n_git[len - 5] != '/')) {
>>
>> Hmm.. should we exclude "foobar.git" as well?
>
> Why wouldn't we? Everything that has basename ".git" is hard-wired
> to be excluded, but everything else, including "foobar.git" should be
> added to the excludes manually... How is it better than just "foobar"?

Yes everything except ".git" should be excluded. And you do exactly
that. I misread the code (probably better to write "if (!())", maybe)
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5] Add an explicit GIT_DIR to the list of excludes

2014-06-09 Thread Pasha Bolokhov
> On Thu, Jun 5, 2014 at 3:15 AM, Pasha Bolokhov  
> wrote:
>> +   /* only add it if GIT_DIR does not end with '.git' or '/.git' */
>> +   if (len < 4 || strcmp(n_git + len - 4, ".git") ||
>> +   (len > 4 && n_git[len - 5] != '/')) {
>
> Hmm.. should we exclude "foobar.git" as well?

Why wouldn't we? Everything that has basename ".git" is hard-wired
to be excluded, but everything else, including "foobar.git" should be
added to the excludes manually... How is it better than just "foobar"?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5] Add an explicit GIT_DIR to the list of excludes

2014-06-08 Thread Duy Nguyen
On Thu, Jun 5, 2014 at 3:15 AM, Pasha Bolokhov  wrote:
> +   /* only add it if GIT_DIR does not end with '.git' or '/.git' */
> +   if (len < 4 || strcmp(n_git + len - 4, ".git") ||
> +   (len > 4 && n_git[len - 5] != '/')) {

Hmm.. should we exclude "foobar.git" as well?
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2014-06-04 Thread Pasha Bolokhov
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 a dedicated function
add_git_dir_exclude(), while checking that GIT_DIR is not just '.git'
or its basename is not '.git', in which cases it would be ignored
by default, and that GIT_DIR is inside GIT_WORK_TREE. Function
add_git_dir_exclude() is invoked at the beginning of
dir.c:setup_standard_excludes()

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 to 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 
---
basename() is not needed anymore, as we are excluding a "full" path GIT_DIR
but relative to GIT_WORK_TREE. Now, a full path ensures that nothing
else gets excluded (i.e. files with the same basename), and this behaviour
is checked in tests

Docs (git-grep, git-ls-files, gitignore) will be updated in the
subsequent version, wanted to check right now if you agree with code.
Docs kind of depend on what we decide about the code

 Documentation/technical/api-directory-listing.txt |   4 +-
 dir.c |  33 
 t/t2205-add-gitdir.sh | 187 ++
 3 files changed, 222 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 eb6f581..300ce1c 100644
--- a/dir.c
+++ b/dir.c
@@ -1604,11 +1604,44 @@ int remove_dir_recursively(struct strbuf *path, int 
flag)
return remove_dir_recurse(path, flag, NULL);
 }
 
+static void add_git_dir_exclude(struct dir_struct *dir)
+{
+   const char *r_git, *gitdir = get_git_dir();
+   char *n_git;
+   int len;
+
+   r_git = real_path(absolute_path(gitdir));
+   n_git = xmalloc(strlen(r_git) + 1 + 1);
+   normalize_path_copy(n_git, r_git);
+   len = strlen(n_git);
+
+   /* only add it if GIT_DIR does not end with '.git' or '/.git' */
+   if (len < 4 || strcmp(n_git + len - 4, ".git") ||
+   (len > 4 && n_git[len - 5] != '/')) {
+   const char *worktree = get_git_work_tree();
+
+   if (!worktree ||
+   dir_inside_of(n_git, worktree) >= 0) {
+   struct exclude_list *el = add_exclude_list(dir, 
EXC_CMDL,
+   "GIT_DIR setup");
+   char *reldir = worktree ? n_git + strlen(worktree) : 
n_git;
+
+   /* append a trailing slash to exclude directories only 
*/
+   n_git[len] = '/';
+   n_git[len + 1] = '\0';
+   add_exclude(reldir, "", 0, el, 0);
+   }
+   }
+   free(n_git);
+}
+
 void setup_standard_excludes(struct dir_struct *dir)
 {
const char *path;
char *xdg_path;
 
+   add_git_dir_exclude(dir);
+
dir->exclude_per_dir = ".gitignore";
path = git_path("info/exclude");
if (!excludes_file) {
diff --git a/t/t2205-add-gitdir.sh b/t/t2205-add-gitdir.sh
new file mode 100755
index 000..721970e
--- /dev/null
+++ b/t/t2205-add-gitdir.sh
@@ -0,0 +1,187 @@
+#!/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:
+#
+#  repo-inside/  repo-outside/
+#
+#
+# repo-inside:
+#  a  b  c  d  dir1/ dir2/ [meta/]
+#
+# repo-inside/dir1:
+#  e  f  g  h  meta/  ssubdir/
+#
+# repo-inside/dir1/meta:
+#  aa
+#
+# repo-inside/dir1/ssubdir:
+#  meta/
+#
+# repo-inside/dir1/ssubdir/meta:
+#  aaa
+#
+# repo-inside/di