Merge branch 'js/git-path-in-subdir'
authorJunio C Hamano <gitster@pobox.com>
Mon, 27 Feb 2017 21:57:17 +0000 (13:57 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 27 Feb 2017 21:57:17 +0000 (13:57 -0800)
The "--git-path", "--git-common-dir", and "--shared-index-path"
options of "git rev-parse" did not produce usable output. They are
now updated to show the path to the correct file, relative to where
the caller is.

* js/git-path-in-subdir:
rev-parse: fix several options when running in a subdirectory
rev-parse tests: add tests executed from a subdirectory

1  2 
builtin/rev-parse.c
t/t1500-rev-parse.sh
diff --combined builtin/rev-parse.c
index 1967bafba40e62b3f2db52ccd3c9630314672ca2,2cfd8d2aae455b96781fd81e509746776200a294..e08677e559f443f8a290f200f691ef770ecde3ef
@@@ -545,6 -545,7 +545,7 @@@ int cmd_rev_parse(int argc, const char 
        unsigned int flags = 0;
        const char *name = NULL;
        struct object_context unused;
+       struct strbuf buf = STRBUF_INIT;
  
        if (argc > 1 && !strcmp("--parseopt", argv[1]))
                return cmd_parseopt(argc - 1, argv + 1, prefix);
                if (!strcmp(arg, "--git-path")) {
                        if (!argv[i + 1])
                                die("--git-path requires an argument");
-                       puts(git_path("%s", argv[i + 1]));
+                       strbuf_reset(&buf);
+                       puts(relative_path(git_path("%s", argv[i + 1]),
+                                          prefix, &buf));
                        i++;
                        continue;
                }
                                putchar('\n');
                                continue;
                        }
 -                      if (!strcmp(arg, "--git-dir")) {
 +                      if (!strcmp(arg, "--git-dir") ||
 +                          !strcmp(arg, "--absolute-git-dir")) {
                                const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
                                char *cwd;
                                int len;
 -                              if (gitdir) {
 -                                      puts(gitdir);
 -                                      continue;
 -                              }
 -                              if (!prefix) {
 -                                      puts(".git");
 -                                      continue;
 +                              if (arg[2] == 'g') {    /* --git-dir */
 +                                      if (gitdir) {
 +                                              puts(gitdir);
 +                                              continue;
 +                                      }
 +                                      if (!prefix) {
 +                                              puts(".git");
 +                                              continue;
 +                                      }
 +                              } else {                /* --absolute-git-dir */
 +                                      if (!gitdir && !prefix)
 +                                              gitdir = ".git";
 +                                      if (gitdir) {
 +                                              puts(real_path(gitdir));
 +                                              continue;
 +                                      }
                                }
                                cwd = xgetcwd();
                                len = strlen(cwd);
                                continue;
                        }
                        if (!strcmp(arg, "--git-common-dir")) {
-                               const char *pfx = prefix ? prefix : "";
-                               puts(prefix_filename(pfx, strlen(pfx), get_git_common_dir()));
+                               strbuf_reset(&buf);
+                               puts(relative_path(get_git_common_dir(),
+                                                  prefix, &buf));
                                continue;
                        }
                        if (!strcmp(arg, "--is-inside-git-dir")) {
                                        die(_("Could not read the index"));
                                if (the_index.split_index) {
                                        const unsigned char *sha1 = the_index.split_index->base_sha1;
-                                       puts(git_path("sharedindex.%s", sha1_to_hex(sha1)));
+                                       const char *path = git_path("sharedindex.%s", sha1_to_hex(sha1));
+                                       strbuf_reset(&buf);
+                                       puts(relative_path(path, prefix, &buf));
                                }
                                continue;
                        }
                        continue;
                verify_filename(prefix, arg, 1);
        }
+       strbuf_release(&buf);
        if (verify) {
                if (revs_count == 1) {
                        show_rev(type, sha1, name);
diff --combined t/t1500-rev-parse.sh
index 8b62ed85b3e74916aaa75962c7a44dcc306eb166,d74f09ad93eca1b68f23829f072becf096d282fe..9ed8b8ccba5db702eaf7b872bd4a1e1af1fd2192
@@@ -3,7 -3,7 +3,7 @@@
  test_description='test git rev-parse'
  . ./test-lib.sh
  
 -# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir
 +# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir absolute-git-dir
  test_rev_parse () {
        d=
        bare=
@@@ -29,8 -29,7 +29,8 @@@
                 --is-inside-git-dir \
                 --is-inside-work-tree \
                 --show-prefix \
 -               --git-dir
 +               --git-dir \
 +               --absolute-git-dir
        do
                test $# -eq 0 && break
                expect="$1"
@@@ -63,29 -62,57 +63,57 @@@ test_expect_success 'setup' 
        cp -R .git repo.git
  '
  
 -test_rev_parse toplevel false false true '' .git
 +test_rev_parse toplevel false false true '' .git "$ROOT/.git"
  
 -test_rev_parse -C .git .git/ false true false '' .
 -test_rev_parse -C .git/objects .git/objects/ false true false '' "$ROOT/.git"
 +test_rev_parse -C .git .git/ false true false '' . "$ROOT/.git"
 +test_rev_parse -C .git/objects .git/objects/ false true false '' "$ROOT/.git" "$ROOT/.git"
  
 -test_rev_parse -C sub/dir subdirectory false false true sub/dir/ "$ROOT/.git"
 +test_rev_parse -C sub/dir subdirectory false false true sub/dir/ "$ROOT/.git" "$ROOT/.git"
  
  test_rev_parse -b t 'core.bare = true' true false false
  
  test_rev_parse -b u 'core.bare undefined' false false true
  
  
 -test_rev_parse -C work -g ../.git -b f 'GIT_DIR=../.git, core.bare = false' false false true ''
 +test_rev_parse -C work -g ../.git -b f 'GIT_DIR=../.git, core.bare = false' false false true '' "../.git" "$ROOT/.git"
  
  test_rev_parse -C work -g ../.git -b t 'GIT_DIR=../.git, core.bare = true' true false false ''
  
  test_rev_parse -C work -g ../.git -b u 'GIT_DIR=../.git, core.bare undefined' false false true ''
  
  
 -test_rev_parse -C work -g ../repo.git -b f 'GIT_DIR=../repo.git, core.bare = false' false false true ''
 +test_rev_parse -C work -g ../repo.git -b f 'GIT_DIR=../repo.git, core.bare = false' false false true '' "../repo.git" "$ROOT/repo.git"
  
  test_rev_parse -C work -g ../repo.git -b t 'GIT_DIR=../repo.git, core.bare = true' true false false ''
  
  test_rev_parse -C work -g ../repo.git -b u 'GIT_DIR=../repo.git, core.bare undefined' false false true ''
  
+ test_expect_success 'git-common-dir from worktree root' '
+       echo .git >expect &&
+       git rev-parse --git-common-dir >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'git-common-dir inside sub-dir' '
+       mkdir -p path/to/child &&
+       test_when_finished "rm -rf path" &&
+       echo "$(git -C path/to/child rev-parse --show-cdup).git" >expect &&
+       git -C path/to/child rev-parse --git-common-dir >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'git-path from worktree root' '
+       echo .git/objects >expect &&
+       git rev-parse --git-path objects >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'git-path inside sub-dir' '
+       mkdir -p path/to/child &&
+       test_when_finished "rm -rf path" &&
+       echo "$(git -C path/to/child rev-parse --show-cdup).git/objects" >expect &&
+       git -C path/to/child rev-parse --git-path objects >actual &&
+       test_cmp expect actual
+ '
  test_done