Re: [PATCH v4 18/27] setup.c: support multi-checkout repo setup

2014-03-07 Thread Duy Nguyen
On Thu, Mar 6, 2014 at 2:42 AM, Junio C Hamano gits...@pobox.com wrote:
 Nguyễn Thái Ngọc Duy  pclo...@gmail.com writes:

  core.worktree::
   Set the path to the root of the working tree.
 + If GIT_COMMON_DIR environment variable is set, core.worktree
 + is ignored and not used for determining the root of working tree.

 Just thinking aloud to see if I got the full implication of the
 above right...

 If we find ourselves in the multi-checkout mode because we saw
 .git/commondir on the filesystem, it is clear that the root of the
 working tree is the parent directory of that .git directory.

 If the reason we think we are in the multi-checkout mode is not
 because of .git/commondir but because $GIT_COMMON_DIR is set,

I tend to think so, .git/commondir is just a convenient way to set
$GIT_COMMON_DIR. $GIT_COMMON_DIR is the key. config.txt correctly
states so, but the commit message is misleading.

  should we assume the same relationship between the root of the working tree
 and the GIT_DIR (however we find it) when the environment variable
 $GIT_WORK_TREE is not set?  Or should that configuration be an error?
 With $GIT_DIR set without $GIT_WORK_TREE set, the user is telling us
 that the $cwd is the root of the working tree, so perhaps we should
 do the same?

It should work exactly like how normal worktree does, so if $GIT_DIR
is set and $GIT_WORK_TREE is not, $PWD is the worktree root.
-- 
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 v4 18/27] setup.c: support multi-checkout repo setup

2014-03-05 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy  pclo...@gmail.com writes:

  core.worktree::
   Set the path to the root of the working tree.
 + If GIT_COMMON_DIR environment variable is set, core.worktree
 + is ignored and not used for determining the root of working tree.

Just thinking aloud to see if I got the full implication of the
above right...

If we find ourselves in the multi-checkout mode because we saw
.git/commondir on the filesystem, it is clear that the root of the
working tree is the parent directory of that .git directory.

If the reason we think we are in the multi-checkout mode is not
because of .git/commondir but because $GIT_COMMON_DIR is set, should
we assume the same relationship between the root of the working tree
and the GIT_DIR (however we find it) when the environment variable
$GIT_WORK_TREE is not set?  Or should that configuration be an error?
With $GIT_DIR set without $GIT_WORK_TREE set, the user is telling us
that the $cwd is the root of the working tree, so perhaps we should
do the same?

--
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 v4 18/27] setup.c: support multi-checkout repo setup

2014-03-01 Thread Nguyễn Thái Ngọc Duy
The repo setup procedure is updated to detect $GIT_DIR/commondir and
set $GIT_COMMON_DIR properly.

The core.worktree is ignored when $GIT_DIR/commondir presents. This is
because commondir repos are intended for separate/linked checkouts
and pointing them back to a fixed core.worktree just does not make
sense.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/config.txt|  2 ++
 Documentation/git-rev-parse.txt |  3 ++
 builtin/rev-parse.c |  4 +++
 cache.h |  1 +
 environment.c   |  8 ++---
 setup.c | 33 +-
 t/t1501-worktree.sh | 76 +
 t/t1510-repo-setup.sh   |  1 +
 trace.c |  1 +
 9 files changed, 115 insertions(+), 14 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5f4d793..313d4b3 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -381,6 +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.
+   If GIT_COMMON_DIR environment variable is set, core.worktree
+   is ignored and not used for determining the root of working tree.
This can be overridden by the GIT_WORK_TREE environment
variable and the '--work-tree' command line option.
The value can be an absolute path or relative to the path to
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 33e4e90..8e6ad32 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -215,6 +215,9 @@ If `$GIT_DIR` is not defined and the current directory
 is not detected to lie in a Git repository or work tree
 print a message to stderr and exit with nonzero status.
 
+--git-common-dir::
+   Show `$GIT_COMMON_DIR` if defined, else `$GIT_DIR`.
+
 --is-inside-git-dir::
When the current working directory is below the repository
directory print true, otherwise false.
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index e50bc65..c7057ce 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -744,6 +744,10 @@ 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-common-dir)) {
+   puts(get_git_common_dir());
+   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 51ade32..98b5dd3 100644
--- a/cache.h
+++ b/cache.h
@@ -407,6 +407,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 get_common_dir(struct strbuf *sb, const char *gitdir);
 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 c998120..0999fc1 100644
--- a/environment.c
+++ b/environment.c
@@ -126,6 +126,7 @@ static char *expand_namespace(const char *raw_namespace)
 
 static void setup_git_env(void)
 {
+   struct strbuf sb = STRBUF_INIT;
const char *gitfile;
const char *shallow_file;
 
@@ -134,12 +135,9 @@ 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) {
+   if (get_common_dir(sb, git_dir))
git_common_dir_env = 1;
-   git_common_dir = xstrdup(git_common_dir);
-   } else
-   git_common_dir = git_dir;
+   git_common_dir = strbuf_detach(sb, NULL);
git_object_dir = getenv(DB_ENVIRONMENT);
if (!git_object_dir) {
git_object_dir = xmalloc(strlen(git_common_dir) + 9);
diff --git a/setup.c b/setup.c
index 42849f3..40ce191 100644
--- a/setup.c
+++ b/setup.c
@@ -170,14 +170,15 @@ void verify_non_filename(const char *prefix, const char 
*arg)
'git command [revision...] -- [file...]', arg);
 }
 
-static void get_common_dir(struct strbuf *sb, const char *gitdir)
+int get_common_dir(struct strbuf *sb, const char *gitdir)
 {
struct strbuf data = STRBUF_INIT;
struct strbuf path = STRBUF_INIT;
const char *git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+   int ret = 0;
if (git_common_dir) {
strbuf_addstr(sb, git_common_dir);