{"thread":{"id":"37448","subject":"Configurable filename for what is now .gitignore","startedAt":"2014-08-30T03:33:01Z","lastAt":"2014-09-04T20:33:27Z","messageCount":6,"participants":["Bostjan Skufca","Jonathan Nieder","Duy Nguyen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"248604","messageId":"CAEp_DRDCQqkwL1N-PemLtOvPEv-xfBW4MatAOomwi+my9QeK8g@mail.gmail.com","threadId":"37448","inReplyTo":null,"subject":"Configurable filename for what is now .gitignore","fromName":"Bostjan Skufca","fromEmail":"bostjan@a2o.si","sentAt":"2014-08-30T03:33:01Z","receivedAt":"2014-08-30T03:33:01Z","isPatch":false,"sender":{"key":"bostjan@a2o.si","avatar":null},"body":"Hi there,\n\nI created a patch which makes \".gitignore\" filename configurabe.\nPreliminary diff is pasted below.\n\nMy question is:\nWould something like this be acceptable for inclusion?\n(providing documentation and test cases will be done too, of course)\n\nSee \"Motivation\" part below for additional explanation.\n\nPossible downsides:\n- default filename .gitignore is kept, so there is no issue here, if\nthis new config option is not changed\n- increased support questions, but I think generally people would not\nchange this setting without having a good reason\n\n\nMotivation:\nGit is great for tracking code development, but when deploying\nmentioned code by using git itself, various configuration files must\nbe created additionally, which are normally .gitignored, for various\nreasons (code portability, sensitive data, etc). There is currently no\nsimple way of tracking changes to those critical configuration files\n(at least none that I am aware of).\n\nOne way to approach this would be tracking those changes in separate\ngit repository. It is possible to create this second repo outside of\ncode repository. But this gets messy very fast (you still need to\ncreate symlinks in code repository, or sth).\n\nIt would be splendid if this configuration tracking repository could\nbe created inside code repository, but in a \"separate namespace\".\n(I've just found out that \"namespaces\" word is already used for\ndifferent concept in git 2.1.x, so let's call it \"dirspace\" in this\ndiscussion).\n\nSeparate dirspace is currently possible for \".git\" directory via\nGIT_DIR environment variable. Adding possibility of using\ndifferently-named .gitignore files is first step for dirspaces,\n.gitmodules and .gitattributes are another two filenames that would\nneed to be made configurable.\n\nI can imagine a tiny tool, let's call it \"gitsth\". When called, sets\nGIT_DIR from .git to .gitsth, and in .gitsth/config configures\nalternate filenames for .gitignore, .gitmodules and .gitattributes to\n.gitignoreSTH, .gitmodulesSTH and .gitattrSTH (for example). This\n.gitignoreSTH could then be used to ignore all files except\nconfiguration files that need to be tracked.\n\nThat is just my imaginative usecase. Think of it as sort of\noverlay-git. Git would only need to provide tools for it, so that on\ntop of those tools new solutions could be created. Other usecases\nwould probably pop up sooner or later.\n\n\nThank you for your opinion,\nb.\n\n\nReadable diff format: http://pastiebin.com/53ff8747b97f1\nActual patch:\n(redacted, as vger swallowed two sending tries with a \"250 2.7.1 Looks\nlike Linux source DIFF email..\" response)\n"},{"id":"248605","messageId":"20140830054312.GA28512@google.com","threadId":"37448","inReplyTo":"CAEp_DRDCQqkwL1N-PemLtOvPEv-xfBW4MatAOomwi+my9QeK8g@mail.gmail.com","subject":"Re: Configurable filename for what is now .gitignore","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2014-08-30T05:43:12Z","receivedAt":"2014-08-30T05:43:12Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nBostjan Skufca wrote:\n\n> Git is great for tracking code development, but when deploying\n> mentioned code by using git itself, various configuration files must\n> be created additionally, which are normally .gitignored, for various\n> reasons (code portability, sensitive data, etc). There is currently no\n> simple way of tracking changes to those critical configuration files\n> (at least none that I am aware of).\n>\n> One way to approach this would be tracking those changes in separate\n> git repository.\n\nHave you seen zit\n<https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Zit>?\n\nCurious,\nJonathan\n"},{"id":"248671","messageId":"CAEp_DRATLprK9LZg45dn5LY=3C8cLM1BNg4rmi0XxJmdPhDGBw@mail.gmail.com","threadId":"37448","inReplyTo":"20140830054312.GA28512@google.com","subject":"Re: Configurable filename for what is now .gitignore","fromName":"Bostjan Skufca","fromEmail":"bostjan@a2o.si","sentAt":"2014-08-31T01:55:48Z","receivedAt":"2014-08-31T01:55:48Z","isPatch":false,"sender":{"key":"bostjan@a2o.si","avatar":null},"body":"Hi Jonathan,\n\nnope, haven't seen zit before, it does partly what I would need, but\njust for one file at a time (a \"bit\" awkward) and not really portable\n(git clone will not clone .FILE.git/exclude, for example).\n\nAnyway, do you think that a patch which makes .gitignore filename\nconfigurable would be appropriate for inclusion in future git\nreleases?\n\nb.\n\n\n\nOn 30 August 2014 07:43, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Hi,\n>\n> Bostjan Skufca wrote:\n>\n>> Git is great for tracking code development, but when deploying\n>> mentioned code by using git itself, various configuration files must\n>> be created additionally, which are normally .gitignored, for various\n>> reasons (code portability, sensitive data, etc). There is currently no\n>> simple way of tracking changes to those critical configuration files\n>> (at least none that I am aware of).\n>>\n>> One way to approach this would be tracking those changes in separate\n>> git repository.\n>\n> Have you seen zit\n> <https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Zit>?\n>\n> Curious,\n> Jonathan\n"},{"id":"248704","messageId":"CAEp_DRBM6cexcoBrYmEktZXh4WMzE-tYwCi80-THCNwJqthQ=g@mail.gmail.com","threadId":"37448","inReplyTo":"CAEp_DRATLprK9LZg45dn5LY=3C8cLM1BNg4rmi0XxJmdPhDGBw@mail.gmail.com","subject":"Re: Configurable filename for what is now .gitignore","fromName":"Bostjan Skufca","fromEmail":"bostjan@a2o.si","sentAt":"2014-09-01T20:30:44Z","receivedAt":"2014-09-01T20:30:44Z","isPatch":false,"sender":{"key":"bostjan@a2o.si","avatar":null},"body":"I see another crux of the problem.\n\nThere is currently no way to transfer/share repository configuration\nbetween clones.\n(Or is there? Could this be done with attributes? Probably not...)\n\nThis is a bit awkward.\nAre there any plans to provide such functionality? Pros/cons?\n\n(It should be limited in scope of course, to provide adequate security\nfor all parties involved.)\n\n\nThanks for sharing your opinion,\nb.\n\n\nPS: For those that did not follow this small thread, here is an\nexample use case to illustrate the problem:\n\n1. I patch git to support custom filename for .gitignore\n2. I reconfigure it in my repository clone (i.e. change it to look for\n.gitexclude files)\n2a. This is configured in .git/config, for example as\ncore.excludesDefaultFilename\n3. I can commit changes to repository code, namely a change which\nrenames .gitignore(s) to .gitexclude(s) (which restores correct\nexclusion pattern parsing)\n4. When I push, only .gitignore rename to .gitexclude goes upstream.\nInfo about required usage of .gitexclude instead of .gitignore stays\nin my repo clone.\n5. When someone pulls, they have messed up \"git status\" output until\nthey manually set the same setting in their repo clone (using\n.gitexclude instead of .gitignore)\n\n\nOn 31 August 2014 03:55, Bostjan Skufca <bostjan@a2o.si> wrote:\n> Hi Jonathan,\n>\n> nope, haven't seen zit before, it does partly what I would need, but\n> just for one file at a time (a \"bit\" awkward) and not really portable\n> (git clone will not clone .FILE.git/exclude, for example).\n>\n> Anyway, do you think that a patch which makes .gitignore filename\n> configurable would be appropriate for inclusion in future git\n> releases?\n>\n> b.\n>\n>\n>\n> On 30 August 2014 07:43, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>> Hi,\n>>\n>> Bostjan Skufca wrote:\n>>\n>>> Git is great for tracking code development, but when deploying\n>>> mentioned code by using git itself, various configuration files must\n>>> be created additionally, which are normally .gitignored, for various\n>>> reasons (code portability, sensitive data, etc). There is currently no\n>>> simple way of tracking changes to those critical configuration files\n>>> (at least none that I am aware of).\n>>>\n>>> One way to approach this would be tracking those changes in separate\n>>> git repository.\n>>\n>> Have you seen zit\n>> <https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Zit>?\n>>\n>> Curious,\n>> Jonathan\n"},{"id":"248707","messageId":"CACsJy8CwSD9Ux+vT9UQUPLFnXoGMn-fvraML+Sj79_et3wJ8WA@mail.gmail.com","threadId":"37448","inReplyTo":"CAEp_DRBM6cexcoBrYmEktZXh4WMzE-tYwCi80-THCNwJqthQ=g@mail.gmail.com","subject":"Re: Configurable filename for what is now .gitignore","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2014-09-01T23:33:02Z","receivedAt":"2014-09-01T23:33:02Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Sep 2, 2014 at 3:30 AM, Bostjan Skufca <bostjan@a2o.si> wrote:\n> There is currently no way to transfer/share repository configuration\n> between clones.\n\nSee http://article.gmane.org/gmane.comp.version-control.git/216624\n-- \nDuy\n"},{"id":"248872","messageId":"CAEp_DRD5u+Vtr8MiFfbLsBtfkuW-EEXRPM9ro1htk7r-8mPYYQ@mail.gmail.com","threadId":"37448","inReplyTo":"CACsJy8CwSD9Ux+vT9UQUPLFnXoGMn-fvraML+Sj79_et3wJ8WA@mail.gmail.com","subject":"Re: Configurable filename for what is now .gitignore","fromName":"Bostjan Skufca","fromEmail":"bostjan@a2o.si","sentAt":"2014-09-04T20:33:27Z","receivedAt":"2014-09-04T20:33:27Z","isPatch":false,"sender":{"key":"bostjan@a2o.si","avatar":null},"body":"I see, tnx for the pointer.\n\nWould inclusion of this patch be viable option then?\n\n\nPatch below, it is possible to look at it here to:\n\nPatch: https://github.com/teonsystems/git/commit/27449825ff4d7bb3eecb5a3e32692aaf1ab1a026\nBranch: https://github.com/teonsystems/git/commits/feature/configurable-gitignore-filename\n\n\n\ncommit 27449825ff4d7bb3eecb5a3e32692aaf1ab1a026\nAuthor: Bostjan Skufca <bostjan@a2o.si>\nDate:   Thu Sep 4 20:20:30 2014 +0000\n\n    .gitignore: make '.gitignore' filename configurable\n\n    When using git with detached work tree and .git directory,\n    it is currently impossible to use multiple git repositories\n    with the same workdir, as .gitignore is always parsed.\n\n    This feature keeps the original '.gitignore' file as default\n    at almost no performance penalty, and enables reconfiguring\n    git to use alternate filename when obtaining per-dir exclusion\n    patterns.\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex c55c22a..1c63b13 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -507,6 +507,17 @@ be delta compressed, but larger binary media\nfiles won't be.\n +\n Common unit suffixes of 'k', 'm', or 'g' are supported.\n\n+core.excludesperdirfilename::\n+ By default, Git checks for presence of .gitignore files to read\n+ exclude patterns from. This option enables the customization of\n+ per-dir exclude patterns filename that is by default called\n+ '.gitignore', to arbitrary filename.\n++\n+This setting is not implicitly distributed when transferring\n+changes between repository clones. In order to achieve identical\n+behaviour in all repository clones, each repository clone must\n+set this option to the same value.\n+\n core.excludesfile::\n  In addition to '.gitignore' (per-directory) and\n  '.git/info/exclude', Git looks into this file for patterns\ndiff --git a/cache.h b/cache.h\nindex 4d5b76c..ff952b4 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -392,6 +392,7 @@ static inline enum object_type\nobject_type(unsigned int mode)\n #define NO_REPLACE_OBJECTS_ENVIRONMENT \"GIT_NO_REPLACE_OBJECTS\"\n #define GITATTRIBUTES_FILE \".gitattributes\"\n #define INFOATTRIBUTES_FILE \"info/attributes\"\n+#define GITIGNORE_FILE \".gitignore\"\n #define ATTRIBUTE_MACRO_PREFIX \"[attr]\"\n #define GIT_NOTES_REF_ENVIRONMENT \"GIT_NOTES_REF\"\n #define GIT_NOTES_DEFAULT_REF \"refs/notes/commits\"\n@@ -1423,6 +1424,7 @@ extern int check_pager_config(const char *cmd);\n\n extern const char *editor_program;\n extern const char *askpass_program;\n+extern const char *excludes_per_dir_filename;\n extern const char *excludes_file;\n\n /* base85 */\ndiff --git a/config.c b/config.c\nindex a191328..da80556 100644\n--- a/config.c\n+++ b/config.c\n@@ -847,6 +847,9 @@ static int git_default_core_config(const char\n*var, const char *value)\n  if (!strcmp(var, \"core.askpass\"))\n  return git_config_string(&askpass_program, var, value);\n\n+ if (!strcmp(var, \"core.excludesperdirfilename\"))\n+ return git_config_string(&excludes_per_dir_filename, var, value);\n+\n  if (!strcmp(var, \"core.excludesfile\"))\n  return git_config_pathname(&excludes_file, var, value);\n\ndiff --git a/dir.c b/dir.c\nindex bd274a7..8b429c3 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1624,7 +1624,12 @@ void setup_standard_excludes(struct dir_struct *dir)\n  const char *path;\n  char *xdg_path;\n\n- dir->exclude_per_dir = \".gitignore\";\n+ if (excludes_per_dir_filename) {\n+ dir->exclude_per_dir = excludes_per_dir_filename;\n+ } else {\n+ dir->exclude_per_dir = GITIGNORE_FILE;\n+ }\n+\n  path = git_path(\"info/exclude\");\n  if (!excludes_file) {\n  home_config_paths(NULL, &xdg_path, \"ignore\");\ndiff --git a/environment.c b/environment.c\nindex 565f652..0d48ef9 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -43,6 +43,7 @@ const char *pager_program;\n int pager_use_color = 1;\n const char *editor_program;\n const char *askpass_program;\n+const char *excludes_per_dir_filename;\n const char *excludes_file;\n enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;\n int check_replace_refs = 1;\ndiff --git a/t/t7515-status-changed-gitignore-filename.sh\nb/t/t7515-status-changed-gitignore-filename.sh\nnew file mode 100755\nindex 0000000..ed7de42\n--- /dev/null\n+++ b/t/t7515-status-changed-gitignore-filename.sh\n@@ -0,0 +1,72 @@\n+#!/bin/sh\n+\n+test_description='status with changed default .gitignore filename'\n+. ./test-lib.sh\n+\n+\n+#\n+# Check if only single file is in 'untracked' state: file2\n+# file1 is excluded by ignore pattern in .gitignore (default)\n+#\n+test_expect_success 'status with default .gitignore filename' '\n+ mkdir repo-default &&\n+ (cd repo-default && git init &&\n+ echo \"/file1\" > .gitignore  &&\n+ git add .gitignore &&\n+ touch file1 &&\n+ touch file2 &&\n+ COUNT_UNTRACKED=`git status | grep -P \"^\\t\" | grep -P -v \"^\\tnew\nfile:\" | grep -c .` &&\n+ if [ \"$COUNT_UNTRACKED\" == \"1\" ]; then\n+  true\n+ else\n+  false\n+ fi\n+ )\n+'\n+\n+\n+#\n+# Check if only single file is in 'untracked' state: file2\n+# file1 is excluded by ignore pattern in .gitexclude (modified\ndefault ignore filename)\n+#\n+test_expect_success 'status with .gitignore filename reconfigured to\n.gitexclude' '\n+ mkdir repo-modified &&\n+ (cd repo-modified && git init &&\n+ git config --add core.excludesperdirfilename .gitexclude &&\n+ echo \"/file1\" > .gitexclude  &&\n+ git add .gitexclude &&\n+ touch file1 &&\n+ touch file2 &&\n+ COUNT_UNTRACKED=`git status | grep -P \"^\\t\" | grep -P -v \"^\\tnew\nfile:\" | grep -c .` &&\n+ if [ \"$COUNT_UNTRACKED\" == \"1\" ]; then\n+  true\n+ else\n+  false\n+ fi\n+ )\n+'\n+\n+\n+#\n+# Check if .gitignore is ignored when default exclude filename is changed\n+# file1 is excluded by ignore pattern in .gitexclude (modified\ndefault ignore filename)\n+#\n+test_expect_success 'ignore .gitignore when reconfigured to use .gitexclude' '\n+ mkdir repo-modified-failure &&\n+ (cd repo-modified-failure && git init &&\n+ git config --add core.excludesperdirfilename .gitexclude &&\n+ echo \"/file1\" > .gitignore  &&\n+ git add .gitignore &&\n+ touch file1 &&\n+ touch file2 &&\n+ COUNT_UNTRACKED=`git status | grep -P \"^\\t\" | grep -P -v \"^\\tnew\nfile:\" | grep -c .` &&\n+ if [ \"$COUNT_UNTRACKED\" == \"2\" ]; then\n+  true\n+ else\n+  false\n+ fi\n+ )\n+'\n+\n+\n+test_done\n\n\nb.\n\n\nOn 2 September 2014 01:33, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Tue, Sep 2, 2014 at 3:30 AM, Bostjan Skufca <bostjan@a2o.si> wrote:\n>> There is currently no way to transfer/share repository configuration\n>> between clones.\n>\n> See http://article.gmane.org/gmane.comp.version-control.git/216624\n> --\n> Duy\n"}]}