From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: [PATCH] Move worktree setup out of setup_git_directory*
Date: Sun, 24 Feb 2008 11:46:51 +0700 [thread overview]
Message-ID: <20080224044650.GA25343@laptop> (raw)
setup_git_directory* now work as if there is no worktree. It may set
some worktree-related variables but its prefix (and current directory)
should not be affected by worktree settings.
Previously only setup_git_directory() takes worktree into account when
calculating prefix (with an exception). This behaviour possibly gives
commands that do only call setup_git_directory_gently() wrong prefix.
The behavior does not expose often as setup_git_directory_gently()
tries to make correct prefix if both GIT_DIR and GIT_WORK_TREE are set
(the mentioned exception). Only if core.worktree is used, the defect
is summoned.
setup_work_tree() will now take the role of recalculating prefix when
worktree is required.
This also effectively reverts dd5c8af (Fix
setup_git_directory_gently() with relative GIT_DIR & GIT_WORK_TREE).
The problem is IMHO that git-diff does not setup worktree when it
needs it, so setting up worktree from setup_git_directory_gently() is
a fix in a wrong place.
While at it, fix builtin-diff-files.c as well with the same problem.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
setup_git_directory() is now just a thin wrapper around _gently(). Sweet.
builtin-blame.c | 4 +-
builtin-diff-files.c | 4 ++-
builtin-diff.c | 5 ++-
builtin-ls-files.c | 10 +++---
builtin-rev-parse.c | 2 +
builtin-rm.c | 2 +-
cache.h | 2 +-
git.c | 2 +-
setup.c | 80 ++++++++++++++++---------------------------------
t/t1501-worktree.sh | 30 ++++++++++++++++++-
10 files changed, 74 insertions(+), 67 deletions(-)
diff --git a/builtin-blame.c b/builtin-blame.c
index bfd562d..f5a878b 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2291,6 +2291,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
/* (3) */
if (argc <= i)
usage(blame_usage);
+ prefix = setup_work_tree(prefix);
path = add_prefix(prefix, argv[i]);
if (i + 1 == argc - 1) {
final_commit_name = argv[i + 1];
@@ -2306,7 +2307,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
else if (i != argc - 1)
usage(blame_usage); /* garbage at end */
- setup_work_tree();
if (!has_path_in_work_tree(path))
die("cannot stat path %s: %s",
path, strerror(errno));
@@ -2354,7 +2354,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
* do not default to HEAD, but use the working tree
* or "--contents".
*/
- setup_work_tree();
+ setup_work_tree(prefix);
sb.final = fake_working_tree_commit(path, contents_from);
add_pending_object(&revs, &(sb.final->object), ":");
}
diff --git a/builtin-diff-files.c b/builtin-diff-files.c
index 4abe3c2..e3cc5cc 100644
--- a/builtin-diff-files.c
+++ b/builtin-diff-files.c
@@ -26,8 +26,10 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
if (!setup_diff_no_index(&rev, argc, argv, nongit, prefix))
argc = 0;
- else
+ else {
+ rev.prefix = prefix = setup_work_tree(prefix);
argc = setup_revisions(argc, argv, &rev, NULL);
+ }
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_RAW;
result = run_diff_files_cmd(&rev, argc, argv);
diff --git a/builtin-diff.c b/builtin-diff.c
index 444ff2f..93221a0 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -244,8 +244,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
if (!setup_diff_no_index(&rev, argc, argv, nongit, prefix))
argc = 0;
- else
+ else {
+ rev.prefix = prefix = setup_work_tree(prefix);
+ rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;
argc = setup_revisions(argc, argv, &rev, NULL);
+ }
if (!rev.diffopt.output_format) {
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
if (diff_setup_done(&rev.diffopt) < 0)
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 25dbfb4..4d833e1 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -23,7 +23,7 @@ static int show_valid_bit;
static int line_terminator = '\n';
static int prefix_len;
-static int prefix_offset;
+static int prefix_offset = -1;
static const char **pathspec;
static int error_unmatch;
static char *ps_matched;
@@ -435,8 +435,6 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
struct dir_struct dir;
memset(&dir, 0, sizeof(dir));
- if (prefix)
- prefix_offset = strlen(prefix);
git_config(git_default_config);
for (i = 1; i < argc; i++) {
@@ -568,8 +566,10 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
break;
}
- if (require_work_tree && !is_inside_work_tree())
- setup_work_tree();
+ if (require_work_tree)
+ prefix = setup_work_tree(prefix);
+ if (prefix_offset == -1)
+ prefix_offset = prefix ? strlen(prefix) : 0;
pathspec = get_pathspec(prefix, argv + i);
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index b9af1a5..9f05cb3 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -472,6 +472,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
continue;
}
if (!strcmp(arg, "--show-prefix")) {
+ if (is_inside_work_tree())
+ prefix = setup_work_tree(prefix);
if (prefix)
puts(prefix);
continue;
diff --git a/builtin-rm.c b/builtin-rm.c
index c0a8bb6..2c15d66 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -156,7 +156,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
usage_with_options(builtin_rm_usage, builtin_rm_options);
if (!index_only)
- setup_work_tree();
+ prefix = setup_work_tree(prefix);
pathspec = get_pathspec(prefix, argv);
seen = NULL;
diff --git a/cache.h b/cache.h
index a5b9ffd..dc768db 100644
--- a/cache.h
+++ b/cache.h
@@ -282,7 +282,7 @@ extern const char *get_git_work_tree(void);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
extern const char **get_pathspec(const char *prefix, const char **pathspec);
-extern void setup_work_tree(void);
+extern const char *setup_work_tree(const char *prefix);
extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
extern const char *prefix_path(const char *prefix, int len, const char *path);
diff --git a/git.c b/git.c
index 4f804a2..90451ee 100644
--- a/git.c
+++ b/git.c
@@ -252,7 +252,7 @@ static int run_command(struct cmd_struct *p, int argc, const char **argv)
if (p->option & USE_PAGER)
setup_pager();
if (p->option & NEED_WORK_TREE)
- setup_work_tree();
+ prefix = setup_work_tree(prefix);
trace_argv_printf(argv, "trace: built-in: git");
diff --git a/setup.c b/setup.c
index 89c81e5..b181b24 100644
--- a/setup.c
+++ b/setup.c
@@ -262,38 +262,25 @@ int is_inside_work_tree(void)
return inside_work_tree;
}
-/*
- * set_work_tree() is only ever called if you set GIT_DIR explicitely.
- * The old behaviour (which we retain here) is to set the work tree root
- * to the cwd, unless overridden by the config, the command line, or
- * GIT_WORK_TREE.
- */
-static const char *set_work_tree(const char *dir)
-{
- char buffer[PATH_MAX + 1];
-
- if (!getcwd(buffer, sizeof(buffer)))
- die ("Could not get the current working directory");
- git_work_tree_cfg = xstrdup(buffer);
- inside_work_tree = 1;
-
- return NULL;
-}
-
-void setup_work_tree(void)
+const char *setup_work_tree(const char *prefix)
{
const char *work_tree, *git_dir;
- static int initialized = 0;
+ static char buffer[PATH_MAX + 1];
+ char *rel;
- if (initialized)
- return;
- work_tree = get_git_work_tree();
git_dir = get_git_dir();
if (!is_absolute_path(git_dir))
set_git_dir(make_absolute_path(git_dir));
- if (!work_tree || chdir(work_tree))
+ work_tree = get_git_work_tree();
+ if (!work_tree)
+ die("This operation must be run in a work tree");
+ if (prefix && chdir(prefix))
+ die ("Could not jump back into original cwd");
+ rel = get_relative_cwd(buffer, PATH_MAX, work_tree);
+ trace_printf("test: worktree = %s\n", rel ? rel : "NULL");
+ if (chdir(work_tree))
die("This operation must be run in a work tree");
- initialized = 1;
+ return rel && *rel ? strcat(rel, "/") : NULL;
}
static int check_repository_format_gently(int *nongit_ok)
@@ -336,24 +323,21 @@ const char *setup_git_directory_gently(int *nongit_ok)
static char buffer[1024 + 1];
const char *retval;
+ /*
+ * The old behaviour (which we retain here) is to set
+ * the work tree root to the cwd, unless overridden by
+ * the config, the command line, or GIT_WORK_TREE.
+ */
if (!work_tree_env) {
- retval = set_work_tree(gitdirenv);
- /* config may override worktree */
- if (check_repository_format_gently(nongit_ok))
- return NULL;
- return retval;
+ char buffer[PATH_MAX + 1];
+
+ if (!getcwd(buffer, sizeof(buffer)))
+ die ("Could not get the current working directory");
+ git_work_tree_cfg = xstrdup(buffer);
+ inside_work_tree = 1;
}
- if (check_repository_format_gently(nongit_ok))
- return NULL;
- retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
- get_git_work_tree());
- if (!retval || !*retval)
- return NULL;
- set_git_dir(make_absolute_path(gitdirenv));
- if (chdir(work_tree_env) < 0)
- die ("Could not chdir to %s", work_tree_env);
- strcat(buffer, "/");
- return retval;
+ check_repository_format_gently(nongit_ok);
+ return NULL;
}
if (nongit_ok) {
*nongit_ok = 1;
@@ -462,17 +446,5 @@ int check_repository_format(void)
const char *setup_git_directory(void)
{
- const char *retval = setup_git_directory_gently(NULL);
-
- /* If the work tree is not the default one, recompute prefix */
- if (inside_work_tree < 0) {
- static char buffer[PATH_MAX + 1];
- char *rel;
- if (retval && chdir(retval))
- die ("Could not jump back into original cwd");
- rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
- return rel && *rel ? strcat(rel, "/") : NULL;
- }
-
- return retval;
+ return setup_git_directory_gently(NULL);
}
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index 7ee3820..2b1629b 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -58,6 +58,34 @@ cd sub/dir || exit 1
test_rev_parse 'subdirectory' false false true sub/dir/
cd ../../.. || exit 1
+test_expect_success 'git ls-files -o gets correct prefix' '
+ (cd work/sub && touch untracked &&
+ test "$(git ls-files -o)" = untracked)'
+
+rm work/sub/untracked || exit 1
+
+cat <<EOF >expected
+:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 M sub/tracked
+EOF
+
+test_expect_success 'git diff-files gets correct prefix' '
+ (cd work/sub && touch tracked &&
+ git add tracked && echo modified > tracked &&
+ git diff-files > ../../result &&
+ git rm -f tracked) &&
+ cmp result expected'
+
+cat <<EOF >expected
+:100644 100644 e69de29... 0000000... M sub/tracked
+EOF
+
+test_expect_success 'git diff gets correct prefix' '
+ (cd work/sub && touch tracked &&
+ git add tracked && echo modified > tracked &&
+ git diff --raw > ../../result &&
+ git rm -f tracked) &&
+ cmp result expected'
+
say "GIT_WORK_TREE=relative path (override core.worktree)"
export GIT_DIR=$(pwd)/repo.git
export GIT_CONFIG=$GIT_DIR/config
@@ -103,7 +131,7 @@ test_expect_success 'repo finds its work tree from work tree, too' '
test sub/dir/tracked = "$(git ls-files)")
'
-test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
+test_expect_success '"git diff" setup worktree properly' '
cd repo.git/work/sub/dir &&
GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \
git diff --exit-code tracked &&
--
1.5.4.2.281.g28d0e
next reply other threads:[~2008-02-24 4:47 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-24 4:46 Nguyễn Thái Ngọc Duy [this message]
2008-02-25 1:13 ` [PATCH] Move worktree setup out of setup_git_directory* Junio C Hamano
2008-02-25 13:17 ` Nguyen Thai Ngoc Duy
2008-02-25 19:01 ` Junio C Hamano
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=20080224044650.GA25343@laptop \
--to=pclouds@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
/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.