All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Jonathan Niedier" <jrnieder@gmail.com>,
	"Junio C Hamano" <gitster@pobox.com>,
	"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v2 13/21] setup: support $GIT_SUPER_DIR as well as super .git files
Date: Sat, 14 Dec 2013 17:54:59 +0700	[thread overview]
Message-ID: <1387018507-21999-14-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1387018507-21999-1-git-send-email-pclouds@gmail.com>

The same rules for git repo setup apply except:

- detect super .git files, set $GIT_SUPER_DIR accordingly

- if $GIT_SUPER_DIR is set (or specified by super .git files), look
  for non-worktree stuff in this directory instead of $GIT_DIR. This
  mostly affects is_git_directory() and check_repository_format()

- the worktree setting precedence goes from lower to higher:
  core.worktree, GIT_SUPER_DIR then GIT_WORK_TREE

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/config.txt               |  3 +-
 Documentation/gitrepository-layout.txt | 10 ++++
 builtin/rev-parse.c                    |  6 +++
 cache.h                                |  1 +
 environment.c                          | 11 +++++
 setup.c                                | 89 ++++++++++++++++++++++++----------
 t/t1501-worktree.sh                    | 52 ++++++++++++++++++++
 t/t1510-repo-setup.sh                  |  1 +
 trace.c                                |  1 +
 9 files changed, 147 insertions(+), 27 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index a405806..df19aa8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -381,7 +381,8 @@ false), while all other repositories are assumed to be bare (bare
 
 core.worktree::
 	Set the path to the root of the working tree.
-	This can be overridden by the GIT_WORK_TREE environment
+	This can be overridden by the GIT_WORK_TREE
+	or GIT_SUPER_DIR environment
 	variable and the '--work-tree' command line option.
 	The value can be an absolute path or relative to the path to
 	the .git directory, which is either specified by --git-dir
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index aa03882..7ce31d4 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -29,6 +29,10 @@ containing superproject to `git checkout` a branch that does not
 have the submodule.  The `checkout` has to remove the entire
 submodule working tree, without losing the submodule repository.
 
+If the text file contains `gitsuper: <path>`, this is a "working
+directory only" repository, attached to another repository and share
+everything with the attached repository except HEAD and the index.
+
 These things may exist in a Git repository.
 
 objects::
@@ -214,6 +218,12 @@ shallow::
 modules::
 	Contains the git-repositories of the submodules.
 
+repos/<id>::
+	If a repository's .git is a file contains two lines `gitsuper:
+	<path>` and `repo: <id>`. The directory `<path>/repos/<id>`
+	contains the real non-shared part of .git directory of the
+	repository in question (e.g. HEAD or index).
+
 SEE ALSO
 --------
 linkgit:git-init[1],
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 1d9ecaf..f5f766a 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -725,6 +725,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : "");
 				continue;
 			}
+			if (!strcmp(arg, "--git-super-dir")) {
+				const char *gitdir = getenv(GIT_SUPER_DIR_ENVIRONMENT);
+				if (gitdir)
+					puts(gitdir);
+				continue;
+			}
 			if (!strcmp(arg, "--resolve-git-dir")) {
 				const char *gitdir = resolve_gitdir(argv[i+1]);
 				if (!gitdir)
diff --git a/cache.h b/cache.h
index f85ee70..4c09223 100644
--- a/cache.h
+++ b/cache.h
@@ -406,6 +406,7 @@ extern char *get_object_directory(void);
 extern char *get_index_file(void);
 extern char *get_graft_file(void);
 extern int set_git_dir(const char *path);
+extern int set_git_dir_super(const char *path, const char *super);
 extern const char *get_git_namespace(void);
 extern const char *strip_namespace(const char *namespaced_ref);
 extern const char *get_git_work_tree(void);
diff --git a/environment.c b/environment.c
index cbfa879..5cbbe11 100644
--- a/environment.c
+++ b/environment.c
@@ -284,6 +284,17 @@ int set_git_dir(const char *path)
 	return 0;
 }
 
+int set_git_dir_super(const char *path, const char *super)
+{
+	if (super && super != path &&
+	    setenv(GIT_SUPER_DIR_ENVIRONMENT, super, 1))
+		return error("Could not set GIT_SUPER_DIR to '%s'", super);
+	if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
+		return error("Could not set GIT_DIR to '%s'", path);
+	setup_git_env();
+	return 0;
+}
+
 const char *get_log_output_encoding(void)
 {
 	return git_log_output_encoding ? git_log_output_encoding
diff --git a/setup.c b/setup.c
index 397eecc..7ccb1f8 100644
--- a/setup.c
+++ b/setup.c
@@ -243,7 +243,8 @@ int is_inside_work_tree(void)
 
 void setup_work_tree(void)
 {
-	const char *work_tree, *git_dir;
+	const char *work_tree, *git_dir, *git_super_dir;
+	char *super_new = NULL, *super_relative = NULL;
 	static int initialized = 0;
 
 	if (initialized)
@@ -252,6 +253,9 @@ void setup_work_tree(void)
 	git_dir = get_git_dir();
 	if (!is_absolute_path(git_dir))
 		git_dir = real_path(get_git_dir());
+	git_super_dir = get_git_super_dir();
+	if (git_super_dir && !is_absolute_path(git_super_dir))
+		git_super_dir = super_new = xstrdup(real_path(get_git_super_dir()));
 	if (!work_tree || chdir(work_tree))
 		die("This operation must be run in a work tree");
 
@@ -262,8 +266,16 @@ void setup_work_tree(void)
 	if (getenv(GIT_WORK_TREE_ENVIRONMENT))
 		setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
 
-	set_git_dir(remove_leading_path(git_dir, work_tree));
+	if (git_super_dir) {
+		super_relative = xstrdup(remove_leading_path(git_super_dir, work_tree));
+		git_super_dir = super_relative;
+	}
+
+	set_git_dir_super(remove_leading_path(git_dir, work_tree),
+			  git_super_dir);
 	initialized = 1;
+	free(super_new);
+	free(super_relative);
 }
 
 static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
@@ -386,24 +398,30 @@ const char *read_gitfile(const char *path)
 
 
 static const char *setup_explicit_git_dir(const char *gitdirenv,
+					  const char *super,
 					  char *cwd, int len,
 					  int *nongit_ok)
 {
 	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
 	const char *worktree;
-	char *gitfile;
+	char *gitfile, *super_new = NULL;
 	int offset;
 
 	if (PATH_MAX - 40 < strlen(gitdirenv))
 		die("'$%s' too big", GIT_DIR_ENVIRONMENT);
 
-	gitfile = (char*)read_gitfile(gitdirenv);
+	if (super)
+		gitfile = (char*)read_gitfile(gitdirenv);
+	else {
+		gitfile = (char*)read_gitfile_super(gitdirenv, &super_new);
+		super = super_new;
+	}
 	if (gitfile) {
 		gitfile = xstrdup(gitfile);
 		gitdirenv = gitfile;
 	}
 
-	if (!is_git_directory(gitdirenv)) {
+	if (!is_git_directory_super(gitdirenv, super)) {
 		if (nongit_ok) {
 			*nongit_ok = 1;
 			goto done_null;
@@ -411,7 +429,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 		die("Not a git repository: '%s'", gitdirenv);
 	}
 
-	if (check_repository_format_gently(gitdirenv, nongit_ok))
+	if (check_repository_format_gently(super ? super : gitdirenv, nongit_ok))
 		goto done_null;
 
 	/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */
@@ -422,10 +440,10 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 			die("core.bare and core.worktree do not make sense");
 
 		/* #18, #26 */
-		set_git_dir(gitdirenv);
+		set_git_dir_super(gitdirenv, super);
 		goto done_null;
 	}
-	else if (git_work_tree_cfg) { /* #6, #14 */
+	else if (git_work_tree_cfg && !super) { /* #6, #14 */
 		if (is_absolute_path(git_work_tree_cfg))
 			set_git_work_tree(git_work_tree_cfg);
 		else {
@@ -443,7 +461,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	}
 	else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
 		/* #16d */
-		set_git_dir(gitdirenv);
+		set_git_dir_super(gitdirenv, super);
 		goto done_null;
 	}
 	else /* #2, #10 */
@@ -454,43 +472,47 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 
 	/* both get_git_work_tree() and cwd are already normalized */
 	if (!strcmp(cwd, worktree)) { /* cwd == worktree */
-		set_git_dir(gitdirenv);
+		set_git_dir_super(gitdirenv, super);
 		goto done_null;
 	}
 
 	offset = dir_inside_of(cwd, worktree);
 	if (offset >= 0) {	/* cwd inside worktree? */
-		set_git_dir(real_path(gitdirenv));
+		set_git_dir_super(real_path(gitdirenv), super);
 		if (chdir(worktree))
 			die_errno("Could not chdir to '%s'", worktree);
 		cwd[len++] = '/';
 		cwd[len] = '\0';
 		free(gitfile);
+		free(super_new);
 		return cwd + offset;
 	}
 
 	/* cwd outside worktree */
-	set_git_dir(gitdirenv);
+	set_git_dir_super(gitdirenv, super);
 
 done_null:
 	free(gitfile);
+	free(super_new);
 	return NULL;
 }
 
 static const char *setup_discovered_git_dir(const char *gitdir,
+					    const char *super,
 					    char *cwd, int offset, int len,
 					    int *nongit_ok)
 {
-	if (check_repository_format_gently(gitdir, nongit_ok))
+	if (check_repository_format_gently(super ? super : gitdir, nongit_ok))
 		return NULL;
 
 	/* --work-tree is set without --git-dir; use discovered one */
-	if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
+	if (getenv(GIT_WORK_TREE_ENVIRONMENT) ||
+	    (git_work_tree_cfg && !super)) {
 		if (offset != len && !is_absolute_path(gitdir))
 			gitdir = xstrdup(real_path(gitdir));
 		if (chdir(cwd))
 			die_errno("Could not come back to cwd");
-		return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
+		return setup_explicit_git_dir(gitdir, super, cwd, len, nongit_ok);
 	}
 
 	/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
@@ -503,8 +525,8 @@ static const char *setup_discovered_git_dir(const char *gitdir,
 
 	/* #0, #1, #5, #8, #9, #12, #13 */
 	set_git_work_tree(".");
-	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
-		set_git_dir(gitdir);
+	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT) || super)
+		set_git_dir_super(gitdir, super);
 	inside_git_dir = 0;
 	inside_work_tree = 1;
 	if (offset == len)
@@ -534,7 +556,7 @@ static const char *setup_bare_git_dir(char *cwd, int offset, int len, int *nongi
 		gitdir = offset == len ? "." : xmemdupz(cwd, offset);
 		if (chdir(cwd))
 			die_errno("Could not come back to cwd");
-		return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
+		return setup_explicit_git_dir(gitdir, NULL, cwd, len, nongit_ok);
 	}
 
 	inside_git_dir = 1;
@@ -613,8 +635,8 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
 	struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
 	static char cwd[PATH_MAX + 1];
-	const char *gitdirenv, *ret;
-	char *gitfile;
+	const char *gitdirenv, *ret, *super;
+	char *gitfile, *super_new = NULL;
 	int len, offset, offset_parent, ceil_offset = -1;
 	dev_t current_device = 0;
 	int one_filesystem = 1;
@@ -637,8 +659,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	 * validation.
 	 */
 	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
+	super = getenv(GIT_SUPER_DIR_ENVIRONMENT);
 	if (gitdirenv)
-		return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
+		return setup_explicit_git_dir(gitdirenv, super,
+					      cwd, len, nongit_ok);
 
 	if (env_ceiling_dirs) {
 		int empty_entry_found = 0;
@@ -668,25 +692,38 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	if (one_filesystem)
 		current_device = get_device_or_die(".", NULL, 0);
 	for (;;) {
-		gitfile = (char*)read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT);
+		if (super)
+			gitfile = (char*)read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT);
+		else {
+			gitfile = (char*)read_gitfile_super(DEFAULT_GIT_DIR_ENVIRONMENT,
+							    &super_new);
+			super = super_new;
+		}
 		if (gitfile)
 			gitdirenv = gitfile = xstrdup(gitfile);
 		else {
-			if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))
+			if (is_git_directory_super(DEFAULT_GIT_DIR_ENVIRONMENT, super))
 				gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT;
 		}
 
 		if (gitdirenv) {
-			ret = setup_discovered_git_dir(gitdirenv,
+			ret = setup_discovered_git_dir(gitdirenv, super,
 						       cwd, offset, len,
 						       nongit_ok);
 			free(gitfile);
+			free(super_new);
 			return ret;
 		}
 		free(gitfile);
 
-		if (is_git_directory("."))
-			return setup_bare_git_dir(cwd, offset, len, nongit_ok);
+		if (is_git_directory(".")) {
+			ret = setup_bare_git_dir(cwd, offset, len, nongit_ok);
+			free(super_new);
+			return ret;
+		}
+
+		free(super_new);
+		super_new = NULL;
 
 		offset_parent = offset;
 		while (--offset_parent > ceil_offset && cwd[offset_parent] != '/');
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index 8f36aa9..dcd8d16 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -346,4 +346,56 @@ test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
 	test_cmp expected actual
 '
 
+test_expect_success 'Split repo setup' '
+	mkdir work &&
+	mkdir -p repo.git/repos/foo &&
+	cp repo.git/HEAD repo.git/index repo.git/repos/foo
+'
+
+test_expect_success 'GIT_SUPER_DIR set' '
+	unset GIT_WORK_TREE GIT_DIR GIT_CONFIG &&
+	GIT_SUPER_DIR=repo.git GIT_DIR=repo.git/repos/foo git rev-parse --git-super-dir >actual &&
+	echo repo.git >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'GIT_DIR set (1)' '
+	(
+		cat <<EOF >gitfile &&
+gitsuper: repo.git
+gitdir: foo
+EOF
+		cd work &&
+		GIT_DIR=../gitfile git rev-parse --git-super-dir >actual &&
+		echo ../repo.git >expect &&
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'GIT_DIR set (2)' '
+	(
+		cat <<EOF >gitfile &&
+gitsuper: $TRASH_DIRECTORY/repo.git
+gitdir: foo
+EOF
+		cd work &&
+		GIT_DIR=../gitfile git rev-parse --git-super-dir >actual &&
+		echo "$TRASH_DIRECTORY"/repo.git >expect &&
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'Auto discovery' '
+	(
+		cat <<EOF >.git &&
+gitsuper: repo.git
+gitdir: foo
+EOF
+		cd work &&
+		git rev-parse --git-super-dir >actual &&
+		echo repo.git >expect &&
+		test_cmp expect actual
+	)
+'
+
 test_done
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index cf2ee78..713f4d7 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -106,6 +106,7 @@ setup_env () {
 expect () {
 	cat >"$1/expected" <<-EOF
 	setup: git_dir: $2
+	setup: git_super_dir: (null)
 	setup: worktree: $3
 	setup: cwd: $4
 	setup: prefix: $5
diff --git a/trace.c b/trace.c
index 3d744d1..53d800b 100644
--- a/trace.c
+++ b/trace.c
@@ -173,6 +173,7 @@ void trace_repo_setup(const char *prefix)
 		prefix = "(null)";
 
 	trace_printf_key(key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
+	trace_printf_key(key, "setup: git_super_dir: %s\n", quote_crnl(get_git_super_dir()));
 	trace_printf_key(key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
 	trace_printf_key(key, "setup: cwd: %s\n", quote_crnl(cwd));
 	trace_printf_key(key, "setup: prefix: %s\n", quote_crnl(prefix));
-- 
1.8.5.1.77.g42c48fa

  parent reply	other threads:[~2013-12-14 10:52 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-11 14:15 [PATCH/POC 0/7] Support multiple worktrees Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` [PATCH/POC 1/7] Make git_path() beware of file relocation in $GIT_DIR Nguyễn Thái Ngọc Duy
2013-12-13 16:30   ` Junio C Hamano
2013-12-11 14:15 ` [PATCH/POC 2/7] Add new environment variable $GIT_SUPER_DIR Nguyễn Thái Ngọc Duy
2013-12-13 18:12   ` Junio C Hamano
2013-12-14  1:11     ` Duy Nguyen
2013-12-14 19:43       ` Junio C Hamano
2013-12-11 14:15 ` [PATCH/POC 3/7] setup.c: add split-repo support to .git files Nguyễn Thái Ngọc Duy
2013-12-13 18:30   ` Junio C Hamano
2013-12-13 20:43     ` Jonathan Nieder
2013-12-14  1:28       ` Duy Nguyen
2013-12-23  3:38       ` Duy Nguyen
2013-12-11 14:15 ` [PATCH/POC 4/7] setup.c: add split-repo support to is_git_directory() Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` [PATCH/POC 5/7] setup.c: reduce cleanup sites in setup_explicit_git_dir() Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` [PATCH/POC 6/7] setup.c: add split-repo support to setup_git_directory* Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` [PATCH/POC 7/7] init: add --split-repo with the same functionality as git-new-workdir Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 00/21] Support multiple worktrees Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 01/21] path.c: avoid PATH_MAX as buffer size from get_pathname() Nguyễn Thái Ngọc Duy
2013-12-15  8:35     ` Torsten Bögershausen
2013-12-15  9:02       ` Duy Nguyen
2013-12-15  9:33         ` Antoine Pelisse
2013-12-14 10:54   ` [PATCH v2 02/21] path.c: rename vsnpath() to git_vsnpath() Nguyễn Thái Ngọc Duy
2013-12-14 20:23     ` Ramsay Jones
2013-12-15  2:25       ` Duy Nguyen
2013-12-15 21:13         ` Ramsay Jones
2013-12-16  7:21           ` Duy Nguyen
2013-12-16 17:11             ` Jonathan Nieder
2013-12-16 20:16               ` Junio C Hamano
2013-12-16 22:59               ` Ramsay Jones
2013-12-14 10:54   ` [PATCH v2 03/21] path.c: move git_path() closer to similar functions git_pathdup() Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 04/21] Make git_path() aware of file relocation in $GIT_DIR Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 05/21] reflog: use avoid constructing .lock path with git_path Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 06/21] fast-import: use git_path() for accessing .git dir instead of get_git_dir() Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 07/21] Add new environment variable $GIT_SUPER_DIR Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 08/21] setup.c: refactor path manipulation out of read_gitfile() Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 09/21] setup.c: add split-repo support to .git files Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 10/21] setup.c: add split-repo support to is_git_directory() Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 11/21] setup.c: reduce cleanup sites in setup_explicit_git_dir() Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` [PATCH v2 12/21] environment.c: support super .git file specified by $GIT_DIR Nguyễn Thái Ngọc Duy
2013-12-14 10:54   ` Nguyễn Thái Ngọc Duy [this message]
2013-12-14 10:55   ` [PATCH v2 14/21] checkout: support checking out into a new working directory Nguyễn Thái Ngọc Duy
2013-12-14 10:55   ` [PATCH v2 15/21] checkout: clean up half-prepared directories in --to mode Nguyễn Thái Ngọc Duy
2013-12-14 10:55   ` [PATCH v2 16/21] setup.c: keep track of the .git file location if read Nguyễn Thái Ngọc Duy
2013-12-14 10:55   ` [PATCH v2 17/21] prune: strategies for split repositories Nguyễn Thái Ngọc Duy
2013-12-14 10:55   ` [PATCH v2 18/21] refs: adjust reflog path for repos/<id>/HEAD Nguyễn Thái Ngọc Duy
2013-12-14 10:55   ` [PATCH v2 19/21] refs: detach split repos' HEAD when the linked ref is updated/deleted Nguyễn Thái Ngọc Duy
2013-12-14 10:55   ` [PATCH v2 20/21] refs.c: refactor do_head_ref(... to do_one_head_ref("HEAD", Nguyễn Thái Ngọc Duy
2013-12-14 10:55   ` [PATCH v2 21/21] revision: include repos/../HEAD in --all Nguyễn Thái Ngọc Duy
2013-12-15  2:29   ` [PATCH v2 00/21] Support multiple worktrees Duy Nguyen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1387018507-21999-14-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jrnieder@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.