From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: [PATCH WIP] Move worktree setup out of setup_git_directory*
Date: Sun, 9 Dec 2007 17:24:32 +0700 [thread overview]
Message-ID: <20071209102432.GA18362@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.
While at it, put set_work_tree() code into
setup_git_directory_gently() for cleaner code.
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. Additional test is added
to catch this.
setup_work_tree() will now take the role of recalculating
prefix when worktree is required.
This also effectively reverts
dd5c8af176bb935a0b01a7dc2d5e022565c3aac3. 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.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Now I'm pretty sure I made it wrong in builtin-diff.c. But I
found no better solution as diff territory is too far from my home.
One more thing, with this change, "git ls-files -c" would show
full path as it does not require a worktree, hence no worktree setup,
NULL prefix or so. Is it bad?
builtin-blame.c | 4 +-
builtin-diff.c | 7 ++++-
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 | 8 ++++-
9 files changed, 51 insertions(+), 66 deletions(-)
diff --git a/builtin-blame.c b/builtin-blame.c
index c158d31..160a1cd 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2280,6 +2280,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];
@@ -2295,7 +2296,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));
@@ -2343,7 +2343,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();
+ prefix = 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.c b/builtin-diff.c
index 1b61599..24c3080 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -246,8 +246,13 @@ 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 {
+ prefix = setup_work_tree(prefix);
+ /* reinitialize rev as prefix can change */
+ init_revisions(&rev, 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 0f0ab2d..3da6d0c 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;
@@ -433,8 +433,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++) {
@@ -566,8 +564,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 20d1789..e48c7ea 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -441,6 +441,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 a3d25e6..920a18f 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 b5811ec..08d7bf6 100644
--- a/cache.h
+++ b/cache.h
@@ -229,7 +229,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 c8b7e74..4b3b6b9 100644
--- a/git.c
+++ b/git.c
@@ -259,7 +259,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 b59dbe7..e23ee8d 100644
--- a/setup.c
+++ b/setup.c
@@ -188,38 +188,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)
@@ -262,24 +249,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;
@@ -387,17 +371,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..3b610ac 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -58,6 +58,12 @@ cd sub/dir || exit 1
test_rev_parse 'subdirectory' false false true sub/dir/
cd ../../.. || exit 1
+test_expect_success 'setup_work_tree() gives correct prefix' '
+ (cd work/sub && touch untracked &&
+ test "$(git ls-files -o)" = untracked)'
+
+rm work/sub/untracked || exit 1
+
say "GIT_WORK_TREE=relative path (override core.worktree)"
export GIT_DIR=$(pwd)/repo.git
export GIT_CONFIG=$GIT_DIR/config
@@ -103,7 +109,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.3.7.2155.g4c25
reply other threads:[~2007-12-09 10:25 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20071209102432.GA18362@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.