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

[PATCH v5 11/28] Add new environment variable $GIT_COMMON_DIR

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Mar 8, 2014, 02:48 UTC
Message-ID
<1394246900-31535-12-git-send-email-pclouds@gmail.com>
In-Reply-To
<1394246900-31535-1-git-send-email-pclouds@gmail.com>

This variable is intended to support multiple working directories attached to a repository. Such a repository may have a main working directory, created by either "git init" or "git clone" and one or more linked working directories. These working directories and the main repository share the same repository directory.

In linked working directories, $GIT_COMMON_DIR must be defined to point to the real repository directory and $GIT_DIR points to an unused subdirectory inside $GIT_COMMON_DIR. File locations inside the repository are reorganized from the linked worktree view point:

 - worktree-specific such as HEAD, logs/HEAD, index, other top-level
   refs and unrecognized files are from $GIT_DIR.
 - the rest like objects, refs, info, hooks, packed-refs, shallow...
   are from $GIT_COMMON_DIR

Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse --git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR" business.

The redirection is done by git_path(), git_pathdup() and strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR, not the other way around in case a developer adds a new worktree-specific file and it's accidentally promoted to be shared across repositories (this includes unknown files added by third party commands)

The list of known files that belong to $GIT_DIR are:

ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/* shallow_*

Path mapping is NOT done for git_path_submodule(). Multi-checkouts are not supported as submodules.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git.txt                  |  8 +++++++
 Documentation/gitrepository-layout.txt | 42 ++++++++++++++++++++++++++--------
 cache.h                                |  4 +++-
 environment.c                          | 19 +++++++++++----
 path.c                                 | 34 +++++++++++++++++++++++++++
 t/t0060-path-utils.sh                  | 15 ++++++++++++
 6 files changed, 108 insertions(+), 14 deletions(-)
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 02bbc08..b094b1f 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -773,6 +773,14 @@ Git so take care if using Cogito etc.
 	an explicit repository directory set via 'GIT_DIR' or on the
 	command line.
 
+'GIT_COMMON_DIR'::
+	If this variable is set to a path, non-worktree files that are
+	normally in $GIT_DIR will be taken from this path
+	instead. Worktree-specific files such as HEAD or index are
+	taken from $GIT_DIR. See linkgit:gitrepository-layout[5] for
+	details. This variable has lower precedence than other path
+	variables such as GIT_INDEX_FILE, GIT_OBJECT_DIRECTORY...
+
 Git Commits
 ~~~~~~~~~~~
 'GIT_AUTHOR_NAME'::
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index aa03882..556da09 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -46,6 +46,9 @@ of incomplete object store is not suitable to be published for
 use with dumb transports but otherwise is OK as long as
 `objects/info/alternates` points at the object stores it
 borrows from.
++
+This directory is ignored if $GIT_COMMON_DIR is set and
+"$GIT_COMMON_DIR/objects" will be used instead.
 
 objects/[0-9a-f][0-9a-f]::
 	A newly created object is stored in its own file.
@@ -92,7 +95,8 @@ refs::
 	References are stored in subdirectories of this
 	directory.  The 'git prune' command knows to preserve
 	objects reachable from refs found in this directory and
-	its subdirectories.
+	its subdirectories. This directory is ignored if $GIT_COMMON_DIR
+	is set and "$GIT_COMMON_DIR/refs" will be used instead.
 
 refs/heads/`name`::
 	records tip-of-the-tree commit objects of branch `name`
@@ -114,7 +118,8 @@ refs/replace/`<obj-sha1>`::
 packed-refs::
 	records the same information as refs/heads/, refs/tags/,
 	and friends record in a more efficient way.  See
-	linkgit:git-pack-refs[1].
+	linkgit:git-pack-refs[1]. This file is ignored if $GIT_COMMON_DIR
+	is set and "$GIT_COMMON_DIR/packed-refs" will be used instead.
 
 HEAD::
 	A symref (see glossary) to the `refs/heads/` namespace
@@ -133,6 +138,11 @@ being a symref to point at the current branch.  Such a state
 is often called 'detached HEAD.'  See linkgit:git-checkout[1]
 for details.
 
+config::
+	Repository specific configuration file. This file is ignored
+	$GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/config" will be
+	used instead.
+
 branches::
 	A slightly deprecated way to store shorthands to be used
 	to specify a URL to 'git fetch', 'git pull' and 'git push'.
@@ -140,7 +150,10 @@ branches::
 	'name' can be given to these commands in place of
 	'repository' argument.  See the REMOTES section in
 	linkgit:git-fetch[1] for details.  This mechanism is legacy
-	and not likely to be found in modern repositories.
+	and not likely to be found in modern repositories. This
+	directory is ignored if $GIT_COMMON_DIR is set and
+	"$GIT_COMMON_DIR/branches" will be used instead.
+
 
 hooks::
 	Hooks are customization scripts used by various Git
@@ -149,7 +162,9 @@ hooks::
 	default.  To enable, the `.sample` suffix has to be
 	removed from the filename by renaming.
 	Read linkgit:githooks[5] for more details about
-	each hook.
+	each hook. This directory is ignored if $GIT_COMMON_DIR is set
+	and "$GIT_COMMON_DIR/hooks" will be used instead.
+
 
 index::
 	The current index file for the repository.  It is
@@ -157,7 +172,8 @@ index::
 
 info::
 	Additional information about the repository is recorded
-	in this directory.
+	in this directory. This directory is ignored if $GIT_COMMON_DIR
+	is set and "$GIT_COMMON_DIR/index" will be used instead.
 
 info/refs::
 	This file helps dumb transports discover what refs are
@@ -193,12 +209,16 @@ remotes::
 	when interacting with remote repositories via 'git fetch',
 	'git pull' and 'git push' commands.  See the REMOTES section
 	in linkgit:git-fetch[1] for details.  This mechanism is legacy
-	and not likely to be found in modern repositories.
+	and not likely to be found in modern repositories. This
+	directory is ignored if $GIT_COMMON_DIR is set and
+	"$GIT_COMMON_DIR/remotes" will be used instead.
 
 logs::
 	Records of changes made to refs are stored in this
 	directory.  See linkgit:git-update-ref[1]
-	for more information.
+	for more information. This directory is ignored
+	$GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/logs" will be used
+	instead.
 
 logs/refs/heads/`name`::
 	Records all changes made to the branch tip named `name`.
@@ -209,10 +229,14 @@ logs/refs/tags/`name`::
 shallow::
 	This is similar to `info/grafts` but is internally used
 	and maintained by shallow clone mechanism.  See `--depth`
-	option to linkgit:git-clone[1] and linkgit:git-fetch[1].
+	option to linkgit:git-clone[1] and linkgit:git-fetch[1]. This
+	file is ignored if $GIT_COMMON_DIR is set and
+	"$GIT_COMMON_DIR/shallow" will be used instead.
 
 modules::
-	Contains the git-repositories of the submodules.
+	Contains the git-repositories of the submodules. This
+	directory is ignored if $GIT_COMMON_DIR is set and
+	"$GIT_COMMON_DIR/modules" will be used instead.
 
 SEE ALSO
 --------
diff --git a/cache.h b/cache.h
index 0f5f44f..9182427 100644
--- a/cache.h
+++ b/cache.h
@@ -347,6 +347,7 @@ static inline enum object_type object_type(unsigned int mode)
 
 /* Double-check local_repo_env below if you add to this list. */
 #define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define GIT_COMMON_DIR_ENVIRONMENT "GIT_COMMON_DIR"
 #define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE"
 #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
 #define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX"
@@ -400,6 +401,7 @@ extern int is_inside_git_dir(void);
 extern char *git_work_tree_cfg;
 extern int is_inside_work_tree(void);
 extern const char *get_git_dir(void);
+extern const char *get_git_common_dir(void);
 extern int is_git_directory(const char *path);
 extern char *get_object_directory(void);
 extern char *get_index_file(void);
@@ -585,7 +587,7 @@ extern int fsync_object_files;
 extern int core_preload_index;
 extern int core_apply_sparse_checkout;
 extern int precomposed_unicode;
-extern int git_db_env, git_index_env, git_graft_env;
+extern int git_db_env, git_index_env, git_graft_env, git_common_dir_env;
 
 /*
  * The character that begins a commented line in user-editable file
diff --git a/environment.c b/environment.c
index f513479..c998120 100644
--- a/environment.c
+++ b/environment.c
@@ -80,9 +80,9 @@ static char *work_tree;
 static const char *namespace;
 static size_t namespace_len;
 
-static const char *git_dir;
+static const char *git_dir, *git_common_dir;
 static char *git_object_dir, *git_index_file, *git_graft_file;
-int git_db_env, git_index_env, git_graft_env;
+int git_db_env, git_index_env, git_graft_env, git_common_dir_env;
 
 /*
  * Repository-local GIT_* environment variables; see cache.h for details.
@@ -134,10 +134,16 @@ static void setup_git_env(void)
 		git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
 	gitfile = read_gitfile(git_dir);
 	git_dir = xstrdup(gitfile ? gitfile : git_dir);
+	git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+	if (git_common_dir) {
+		git_common_dir_env = 1;
+		git_common_dir = xstrdup(git_common_dir);
+	} else
+		git_common_dir = git_dir;
 	git_object_dir = getenv(DB_ENVIRONMENT);
 	if (!git_object_dir) {
-		git_object_dir = xmalloc(strlen(git_dir) + 9);
-		sprintf(git_object_dir, "%s/objects", git_dir);
+		git_object_dir = xmalloc(strlen(git_common_dir) + 9);
+		sprintf(git_object_dir, "%s/objects", git_common_dir);
 	} else
 		git_db_env = 1;
 	git_index_file = getenv(INDEX_ENVIRONMENT);
@@ -173,6 +179,11 @@ const char *get_git_dir(void)
 	return git_dir;
 }
 
+const char *get_git_common_dir(void)
+{
+	return git_common_dir;
+}
+
 const char *get_git_namespace(void)
 {
 	if (!namespace)
diff --git a/path.c b/path.c
index 1069ae0..8453687 100644
--- a/path.c
+++ b/path.c
@@ -90,6 +90,38 @@ static void replace_dir(struct strbuf *buf, int len, const char *newdir)
 		buf->buf[newlen] = '/';
 }
 
+static const char *common_list[] = {
+	"/branches", "/hooks", "/info", "/logs", "/lost-found", "/modules",
+	"/objects", "/refs", "/remotes", "/rr-cache", "/svn",
+	"config", "gc.pid", "packed-refs", "shallow",
+	NULL
+};
+
+static void update_common_dir(struct strbuf *buf, int git_dir_len)
+{
+	char *base = buf->buf + git_dir_len;
+	const char **p;
+
+	if (is_dir_file(base, "logs", "HEAD"))
+		return;	/* keep this in $GIT_DIR */
+	for (p = common_list; *p; p++) {
+		const char *path = *p;
+		int is_dir = 0;
+		if (*path == '/') {
+			path++;
+			is_dir = 1;
+		}
+		if (is_dir && dir_prefix(base, path)) {
+			replace_dir(buf, git_dir_len, get_git_common_dir());
+			return;
+		}
+		if (!is_dir && !strcmp(base, path)) {
+			replace_dir(buf, git_dir_len, get_git_common_dir());
+			return;
+		}
+	}
+}
+
 static void adjust_git_path(struct strbuf *buf, int git_dir_len)
 {
 	const char *base = buf->buf + git_dir_len;
@@ -101,6 +133,8 @@ static void adjust_git_path(struct strbuf *buf, int git_dir_len)
 			      get_index_file(), strlen(get_index_file()));
 	else if (git_db_env && dir_prefix(base, "objects"))
 		replace_dir(buf, git_dir_len + 7, get_object_directory());
+	else if (git_common_dir_env)
+		update_common_dir(buf, git_dir_len);
 }
 
 static void do_git_path(struct strbuf *buf, const char *fmt, va_list args)
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 1d29901..f9a77e4 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -241,5 +241,20 @@ test_expect_success 'setup fake objects directory foo' 'mkdir foo'
 test_git_path GIT_OBJECT_DIRECTORY=foo objects foo
 test_git_path GIT_OBJECT_DIRECTORY=foo objects/foo foo/foo
 test_git_path GIT_OBJECT_DIRECTORY=foo objects2 .git/objects2
+test_expect_success 'setup common repository' 'git --git-dir=bar init'
+test_git_path GIT_COMMON_DIR=bar index                    .git/index
+test_git_path GIT_COMMON_DIR=bar HEAD                     .git/HEAD
+test_git_path GIT_COMMON_DIR=bar logs/HEAD                .git/logs/HEAD
+test_git_path GIT_COMMON_DIR=bar objects                  bar/objects
+test_git_path GIT_COMMON_DIR=bar objects/bar              bar/objects/bar
+test_git_path GIT_COMMON_DIR=bar info/exclude             bar/info/exclude
+test_git_path GIT_COMMON_DIR=bar remotes/bar              bar/remotes/bar
+test_git_path GIT_COMMON_DIR=bar branches/bar             bar/branches/bar
+test_git_path GIT_COMMON_DIR=bar logs/refs/heads/master   bar/logs/refs/heads/master
+test_git_path GIT_COMMON_DIR=bar refs/heads/master        bar/refs/heads/master
+test_git_path GIT_COMMON_DIR=bar hooks/me                 bar/hooks/me
+test_git_path GIT_COMMON_DIR=bar config                   bar/config
+test_git_path GIT_COMMON_DIR=bar packed-refs              bar/packed-refs
+test_git_path GIT_COMMON_DIR=bar shallow                  bar/shallow
 
 test_done
-- 
1.9.0.40.gaa8c3ea
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 144 of 169 in “Support multiple checkouts”
  1. 00/25 Support multiple checkoutsNguyễn Thái Ngọc Duy, Feb 18, 2014
  2. 01/25 path.c: make get_pathname() return strbuf instead of static bufferNguyễn Thái Ngọc Duy, Feb 18, 2014
  3. Junio C HamanoFeb 19, 2014
  4. Junio C HamanoFeb 19, 2014
  5. Duy NguyenMar 1, 2014
  6. Junio C HamanoMar 3, 2014
  7. 02/25 Convert git_snpath() to strbuf_git_path()Nguyễn Thái Ngọc Duy, Feb 18, 2014
  8. Junio C HamanoFeb 19, 2014
  9. Duy NguyenFeb 19, 2014
  10. Junio C HamanoFeb 20, 2014
  11. Duy NguyenFeb 20, 2014
  12. Junio C HamanoFeb 20, 2014
  13. Junio C HamanoFeb 20, 2014
  14. 03/25 path.c: rename vsnpath() to do_git_path()Nguyễn Thái Ngọc Duy, Feb 18, 2014
  15. 04/25 path.c: group git_path(), git_pathdup() and strbuf_git_path() togetherNguyễn Thái Ngọc Duy, Feb 18, 2014
  16. 05/25 Make git_path() aware of file relocation in $GIT_DIRNguyễn Thái Ngọc Duy, Feb 18, 2014
  17. 06/25 *.sh: respect $GIT_INDEX_FILENguyễn Thái Ngọc Duy, Feb 18, 2014
  18. 07/25 reflog: avoid constructing .lock path with git_pathNguyễn Thái Ngọc Duy, Feb 18, 2014
  19. Junio C HamanoFeb 25, 2014
  20. Duy NguyenMar 1, 2014
  21. Junio C HamanoMar 3, 2014
  22. 08/25 fast-import: use git_path() for accessing .git dir instead of get_git_dir()Nguyễn Thái Ngọc Duy, Feb 18, 2014
  23. 09/25 commit: use SEQ_DIR instead of hardcoding "sequencer"Nguyễn Thái Ngọc Duy, Feb 18, 2014
  24. 10/25 Add new environment variable $GIT_COMMON_DIRNguyễn Thái Ngọc Duy, Feb 18, 2014
  25. Eric SunshineFeb 26, 2014
  26. Duy NguyenFeb 26, 2014
  27. Philip OakleyFeb 26, 2014
  28. Eric SunshineFeb 26, 2014
  29. Eric SunshineFeb 26, 2014
  30. Junio C HamanoFeb 26, 2014
  31. Duy NguyenFeb 27, 2014
  32. 11/25 git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objectsNguyễn Thái Ngọc Duy, Feb 18, 2014
  33. Junio C HamanoFeb 27, 2014
  34. 12/25 *.sh: avoid hardcoding $GIT_DIR/hooks/...Nguyễn Thái Ngọc Duy, Feb 18, 2014
  35. 13/25 git-stash: avoid hardcoding $GIT_DIR/logs/....Nguyễn Thái Ngọc Duy, Feb 18, 2014
  36. 14/25 setup.c: convert is_git_directory() to use strbufNguyễn Thái Ngọc Duy, Feb 18, 2014
  37. Junio C HamanoFeb 19, 2014
  38. Duy NguyenFeb 20, 2014
  39. Junio C HamanoFeb 20, 2014
  40. Junio C HamanoFeb 20, 2014
  41. strbuf: style fix -- top opening bracket on a separate lineNguyễn Thái Ngọc Duy, Mar 1, 2014
  42. Eric SunshineFeb 21, 2014
  43. 15/25 setup.c: detect $GIT_COMMON_DIR in is_git_directory()Nguyễn Thái Ngọc Duy, Feb 18, 2014
  44. Junio C HamanoFeb 27, 2014
  45. Duy NguyenMar 1, 2014
  46. 16/25 setup.c: convert check_repository_format_gently to use strbufNguyễn Thái Ngọc Duy, Feb 18, 2014
  47. Junio C HamanoFeb 27, 2014
  48. 17/25 setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()Nguyễn Thái Ngọc Duy, Feb 18, 2014
  49. Junio C HamanoFeb 27, 2014
  50. Duy NguyenFeb 27, 2014
  51. Junio C HamanoFeb 27, 2014
  52. 18/25 setup.c: support multi-checkout repo setupNguyễn Thái Ngọc Duy, Feb 18, 2014
  53. Junio C HamanoFeb 19, 2014
  54. Junio C HamanoFeb 27, 2014
  55. Torsten BögershausenMar 24, 2014
  56. Duy NguyenMar 25, 2014
  57. Duy NguyenMar 25, 2014
  58. Junio C HamanoMar 26, 2014
  59. 19/25 wrapper.c: wrapper to open a file, fprintf then closeNguyễn Thái Ngọc Duy, Feb 18, 2014
  60. 20/25 use new wrapper write_file() for simple file writingNguyễn Thái Ngọc Duy, Feb 18, 2014
  61. 21/25 checkout: support checking out into a new working directoryNguyễn Thái Ngọc Duy, Feb 18, 2014
  62. Eric SunshineFeb 26, 2014
  63. Duy NguyenFeb 26, 2014
  64. Eric SunshineFeb 27, 2014
  65. 22/25 checkout: clean up half-prepared directories in --to modeNguyễn Thái Ngọc Duy, Feb 18, 2014
  66. 23/25 checkout: detach if the branch is already checked out elsewhereNguyễn Thái Ngọc Duy, Feb 18, 2014
  67. Junio C HamanoFeb 19, 2014
  68. Eric SunshineFeb 19, 2014
  69. 24/25 prune: strategies for linked checkoutsNguyễn Thái Ngọc Duy, Feb 18, 2014
  70. Junio C HamanoFeb 19, 2014
  71. Junio C HamanoFeb 19, 2014
  72. Duy NguyenFeb 20, 2014
  73. Junio C HamanoFeb 20, 2014
  74. Eric SunshineFeb 19, 2014
  75. Eric SunshineFeb 19, 2014
  76. Duy NguyenFeb 20, 2014
  77. 25/25 gc: support prune --reposNguyễn Thái Ngọc Duy, Feb 18, 2014
  78. Junio C HamanoFeb 19, 2014
  79. Junio C HamanoFeb 19, 2014
  80. 00/27 Support multiple checkoutsNguyễn Thái Ngọc Duy, Mar 1, 2014
  81. 01/27 path.c: make get_pathname() return strbuf instead of static bufferNguyễn Thái Ngọc Duy, Mar 1, 2014
  82. Eric SunshineMar 2, 2014
  83. Duy NguyenMar 3, 2014
  84. 02/27 Convert git_snpath() to strbuf_git_path()Nguyễn Thái Ngọc Duy, Mar 1, 2014
  85. Eric SunshineMar 3, 2014
  86. Duy NguyenMar 3, 2014
  87. Duy NguyenMar 7, 2014
  88. Eric SunshineMar 7, 2014
  89. 03/27 path.c: rename vsnpath() to do_git_path()Nguyễn Thái Ngọc Duy, Mar 1, 2014
  90. 04/27 path.c: group git_path(), git_pathdup() and strbuf_git_path() togetherNguyễn Thái Ngọc Duy, Mar 1, 2014
  91. 05/27 Make git_path() aware of file relocation in $GIT_DIRNguyễn Thái Ngọc Duy, Mar 1, 2014
  92. Eric SunshineMar 3, 2014
  93. 06/27 *.sh: respect $GIT_INDEX_FILENguyễn Thái Ngọc Duy, Mar 1, 2014
  94. 07/27 reflog: avoid constructing .lock path with git_pathNguyễn Thái Ngọc Duy, Mar 1, 2014
  95. 08/27 fast-import: use git_path() for accessing .git dir instead of get_git_dir()Nguyễn Thái Ngọc Duy, Mar 1, 2014
  96. 09/27 commit: use SEQ_DIR instead of hardcoding "sequencer"Nguyễn Thái Ngọc Duy, Mar 1, 2014
  97. 10/27 Add new environment variable $GIT_COMMON_DIRNguyễn Thái Ngọc Duy, Mar 1, 2014
  98. Eric SunshineMar 3, 2014
  99. 11/27 git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objectsNguyễn Thái Ngọc Duy, Mar 1, 2014
  100. 12/27 *.sh: avoid hardcoding $GIT_DIR/hooks/...Nguyễn Thái Ngọc Duy, Mar 1, 2014
  101. Eric SunshineMar 3, 2014
  102. 13/27 git-stash: avoid hardcoding $GIT_DIR/logs/....Nguyễn Thái Ngọc Duy, Mar 1, 2014
  103. Torsten BögershausenMar 1, 2014
  104. 14/27 setup.c: convert is_git_directory() to use strbufNguyễn Thái Ngọc Duy, Mar 1, 2014
  105. 15/27 setup.c: detect $GIT_COMMON_DIR in is_git_directory()Nguyễn Thái Ngọc Duy, Mar 1, 2014
  106. 16/27 setup.c: convert check_repository_format_gently to use strbufNguyễn Thái Ngọc Duy, Mar 1, 2014
  107. 17/27 setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()Nguyễn Thái Ngọc Duy, Mar 1, 2014
  108. 18/27 setup.c: support multi-checkout repo setupNguyễn Thái Ngọc Duy, Mar 1, 2014
  109. Junio C HamanoMar 5, 2014
  110. Duy NguyenMar 8, 2014
  111. 19/27 wrapper.c: wrapper to open a file, fprintf then closeNguyễn Thái Ngọc Duy, Mar 1, 2014
  112. Torsten BögershausenMar 1, 2014
  113. Eric SunshineMar 4, 2014
  114. 20/27 use new wrapper write_file() for simple file writingNguyễn Thái Ngọc Duy, Mar 1, 2014
  115. 21/27 checkout: support checking out into a new working directoryNguyễn Thái Ngọc Duy, Mar 1, 2014
  116. 22/27 checkout: clean up half-prepared directories in --to modeNguyễn Thái Ngọc Duy, Mar 1, 2014
  117. Eric SunshineMar 6, 2014
  118. 23/27 checkout: detach if the branch is already checked out elsewhereNguyễn Thái Ngọc Duy, Mar 1, 2014
  119. 24/27 prune: strategies for linked checkoutsNguyễn Thái Ngọc Duy, Mar 1, 2014
  120. Torsten BögershausenMar 1, 2014
  121. Duy NguyenMar 2, 2014
  122. Junio C HamanoMar 5, 2014
  123. 25/27 gc: style change -- no SP before closing bracketNguyễn Thái Ngọc Duy, Mar 1, 2014
  124. 26/27 gc: support prune --reposNguyễn Thái Ngọc Duy, Mar 1, 2014
  125. Eric SunshineMar 7, 2014
  126. 27/27 count-objects: report unused files in $GIT_DIR/repos/...Nguyễn Thái Ngọc Duy, Mar 1, 2014
  127. Eric SunshineMar 5, 2014
  128. Duy NguyenMar 5, 2014
  129. 00/28 Support multiple checkoutsNguyễn Thái Ngọc Duy, Mar 8, 2014
  130. 01/28 path.c: make get_pathname() return strbuf instead of static bufferNguyễn Thái Ngọc Duy, Mar 8, 2014
  131. Torsten BögershausenMar 8, 2014
  132. Duy NguyenMar 8, 2014
  133. 02/28 path.c: make get_pathname() call sites return const char *Nguyễn Thái Ngọc Duy, Mar 8, 2014
  134. 03/28 Convert git_snpath() to strbuf_git_path()Nguyễn Thái Ngọc Duy, Mar 8, 2014
  135. Junio C HamanoMar 17, 2014
  136. 04/28 path.c: rename vsnpath() to do_git_path()Nguyễn Thái Ngọc Duy, Mar 8, 2014
  137. 05/28 path.c: group git_path(), git_pathdup() and strbuf_git_path() togetherNguyễn Thái Ngọc Duy, Mar 8, 2014
  138. 06/28 Make git_path() aware of file relocation in $GIT_DIRNguyễn Thái Ngọc Duy, Mar 8, 2014
  139. Eric SunshineMar 9, 2014
  140. 07/28 *.sh: respect $GIT_INDEX_FILENguyễn Thái Ngọc Duy, Mar 8, 2014
  141. 08/28 reflog: avoid constructing .lock path with git_pathNguyễn Thái Ngọc Duy, Mar 8, 2014
  142. 09/28 fast-import: use git_path() for accessing .git dir instead of get_git_dir()Nguyễn Thái Ngọc Duy, Mar 8, 2014
  143. 10/28 commit: use SEQ_DIR instead of hardcoding "sequencer"Nguyễn Thái Ngọc Duy, Mar 8, 2014
  144. 11/28 Add new environment variable $GIT_COMMON_DIRNguyễn Thái Ngọc Duy, Mar 8, 2014
  145. 12/28 git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objectsNguyễn Thái Ngọc Duy, Mar 8, 2014
  146. 13/28 *.sh: avoid hardcoding $GIT_DIR/hooks/...Nguyễn Thái Ngọc Duy, Mar 8, 2014
  147. 14/28 git-stash: avoid hardcoding $GIT_DIR/logs/....Nguyễn Thái Ngọc Duy, Mar 8, 2014
  148. 15/28 setup.c: convert is_git_directory() to use strbufNguyễn Thái Ngọc Duy, Mar 8, 2014
  149. 16/28 setup.c: detect $GIT_COMMON_DIR in is_git_directory()Nguyễn Thái Ngọc Duy, Mar 8, 2014
  150. 17/28 setup.c: convert check_repository_format_gently to use strbufNguyễn Thái Ngọc Duy, Mar 8, 2014
  151. 18/28 setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()Nguyễn Thái Ngọc Duy, Mar 8, 2014
  152. 19/28 setup.c: support multi-checkout repo setupNguyễn Thái Ngọc Duy, Mar 8, 2014
  153. 20/28 wrapper.c: wrapper to open a file, fprintf then closeNguyễn Thái Ngọc Duy, Mar 8, 2014
  154. 21/28 use new wrapper write_file() for simple file writingNguyễn Thái Ngọc Duy, Mar 8, 2014
  155. 22/28 checkout: support checking out into a new working directoryNguyễn Thái Ngọc Duy, Mar 8, 2014
  156. 23/28 checkout: clean up half-prepared directories in --to modeNguyễn Thái Ngọc Duy, Mar 8, 2014
  157. 24/28 checkout: detach if the branch is already checked out elsewhereNguyễn Thái Ngọc Duy, Mar 8, 2014
  158. 25/28 prune: strategies for linked checkoutsNguyễn Thái Ngọc Duy, Mar 8, 2014
  159. Eric SunshineMar 9, 2014
  160. 26/28 gc: style change -- no SP before closing bracketNguyễn Thái Ngọc Duy, Mar 8, 2014
  161. 27/28 gc: support prune --reposNguyễn Thái Ngọc Duy, Mar 8, 2014
  162. 28/28 count-objects: report unused files in $GIT_DIR/repos/...Nguyễn Thái Ngọc Duy, Mar 8, 2014
  163. Eric SunshineMar 9, 2014
  164. Duy NguyenMar 9, 2014
  165. Eric SunshineMar 9, 2014
  166. Max KirillovJul 6, 2014
  167. Duy NguyenJul 7, 2014
  168. Dennis KaarsemakerJul 7, 2014
  169. Max KirillovJul 7, 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.