Code

setup_work_tree: adjust relative $GIT_WORK_TREE after moving cwd
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Mon, 27 Dec 2010 01:26:04 +0000 (08:26 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 27 Dec 2010 16:34:19 +0000 (08:34 -0800)
When setup_work_tree() is called, it moves cwd to $GIT_WORK_TREE and
makes internal copy of $GIT_WORK_TREE absolute. The environt variable,
if set by user, remains unchanged. If the variable is relative, it is
no longer correct because its base dir has changed.

Instead of making $GIT_WORK_TREE absolute too, we just say "." and let
subsequent git processes handle it.

Reported-by: Michel Briand <michelbriand@free.fr>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
.gitignore
Makefile
setup.c
t/t1501-worktree.sh
test-subprocess.c [new file with mode: 0644]

index 20560b810b0471c3b7d012bf0f14d7885e2b83ec..1dcc082a881e6a33e5208d15aa65ef08867caf81 100644 (file)
 /test-sha1
 /test-sigchain
 /test-string-pool
+/test-subprocess
 /test-svn-fe
 /test-treap
 /common-cmds.h
index 1f1ce04edf0b87f6fdbd579052d5ccaa538e6b93..f96d990d5ac4556a1b5c0fc839931b078e98340f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -425,6 +425,7 @@ TEST_PROGRAMS_NEED_X += test-run-command
 TEST_PROGRAMS_NEED_X += test-sha1
 TEST_PROGRAMS_NEED_X += test-sigchain
 TEST_PROGRAMS_NEED_X += test-string-pool
+TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
 TEST_PROGRAMS_NEED_X += test-treap
 TEST_PROGRAMS_NEED_X += test-index-version
diff --git a/setup.c b/setup.c
index 2e2865cc41628b7c39b35e01ffcee1cb46167c78..be550af42a12a29d3e10a2d6cbfcc3287d46cbbc 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -221,6 +221,14 @@ void setup_work_tree(void)
                git_dir = make_absolute_path(git_dir);
        if (!work_tree || chdir(work_tree))
                die("This operation must be run in a work tree");
+
+       /*
+        * Make sure subsequent git processes find correct worktree
+        * if $GIT_WORK_TREE is set relative
+        */
+       if (getenv(GIT_WORK_TREE_ENVIRONMENT))
+               setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
+
        set_git_dir(make_relative_path(git_dir, work_tree));
        initialized = 1;
 }
index 2c8f01f6684cbe492132575209f79371ad761d87..f072a8ed48ce87267c72635f417bc0b3ebe03f19 100755 (executable)
@@ -340,4 +340,11 @@ test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
        git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file
 '
 
+test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
+       GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
+       test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
+       echo "$TRASH_DIRECTORY/repo.git/work" >expected &&
+       test_cmp expected actual
+'
+
 test_done
diff --git a/test-subprocess.c b/test-subprocess.c
new file mode 100644 (file)
index 0000000..667d3e5
--- /dev/null
@@ -0,0 +1,21 @@
+#include "cache.h"
+#include "run-command.h"
+
+int main(int argc, char **argv)
+{
+       const char *prefix;
+       struct child_process cp;
+       int nogit = 0;
+
+       prefix = setup_git_directory_gently(&nogit);
+       if (nogit)
+               die("No git repo found");
+       if (!strcmp(argv[1], "--setup-work-tree")) {
+               setup_work_tree();
+               argv++;
+       }
+       memset(&cp, 0, sizeof(cp));
+       cp.git_cmd = 1;
+       cp.argv = (const char **)argv+1;
+       return run_command(&cp);
+}