* Fwd: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) [not found] <CA+dzEB=2LJXiLSTqyLw8AeHNwdQicwvEiMg=hVEX0-_s1bySpA@mail.gmail.com> @ 2015-11-24 2:22 ` Anthony Sottile 2015-11-24 17:57 ` Stefan Beller 0 siblings, 1 reply; 39+ messages in thread From: Anthony Sottile @ 2015-11-24 2:22 UTC (permalink / raw) To: git * Short description of the problem * It seems GIT_WORK_DIR is now exported invariantly when calling git hooks such as pre-commit. If these hooks involve cloning repositories they will not fail due to this exported environment variable. This was not the case in prior versions (such as v2.5.0). * Simple reproduction * ``` $ cat test.sh #!/usr/bin/env bash set -ex rm -rf test # Exit non {0, 1} to abort git bisect make -j 8 > /dev/null || exit 2 # Put our new git on the path PATH="$(pwd):$PATH" git init test pushd test mkdir -p .git/hooks echo 'git clone git://github.com/asottile/css-explore css-explore' > .git/hooks/pre-commit chmod 755 .git/hooks/pre-commit git commit -m foo --allow-empty || exit 1 ``` * Under 2.6.3 * ``` $ ./test.sh ... + git init test warning: templates not found /home/anthony/share/git-core/templates Initialized empty Git repository in /home/anthony/workspace/git/test/.git/ + pushd test ~/workspace/git/test ~/workspace/git + mkdir -p .git/hooks + echo 'git clone git://github.com/asottile/css-explore css-explore' + chmod 755 .git/hooks/pre-commit + git commit -m foo --allow-empty fatal: working tree '.' already exists. + exit 1 ``` * Under 2.5 * ``` $ ./test.sh ... + git init test warning: templates not found /home/anthony/share/git-core/templates Initialized empty Git repository in /home/anthony/workspace/git/test/.git/ + pushd test ~/workspace/git/test ~/workspace/git + mkdir -p .git/hooks + echo 'git clone git://github.com/asottile/css-explore css-explore' + chmod 755 .git/hooks/pre-commit + git commit -m foo --allow-empty Cloning into 'css-explore'... warning: templates not found /home/anthony/share/git-core/templates remote: Counting objects: 214, done. remote: Total 214 (delta 0), reused 0 (delta 0), pack-reused 214 Receiving objects: 100% (214/214), 25.89 KiB | 0 bytes/s, done. Resolving deltas: 100% (129/129), done. Checking connectivity... done. [master (root-commit) 5eb999d] foo ``` * Bisect * ``` $ git bisect good v2.5.0 $ git bisect bad origin/master $ git bisect run ./test.sh ... d95138e695d99d32dcad528a2a7974f434c51e79 is the first bad commit commit d95138e695d99d32dcad528a2a7974f434c51e79 Author: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Date: Fri Jun 26 17:37:35 2015 +0700 setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR In the test case, we run setup_git_dir_gently() the first time to read $GIT_DIR/config so that we can resolve aliases. We'll enter setup_discovered_git_dir() and may or may not call set_git_dir() near the end of the function, depending on whether the detected git dir is ".git" or not. This set_git_dir() will set env var $GIT_DIR. For normal repo, git dir detected via setup_discovered_git_dir() will be ".git", and set_git_dir() is not called. If .git file is used however, the git dir can't be ".git" and set_git_dir() is called and $GIT_DIR set. This is the key of this problem. If we expand an alias (or autocorrect command names), then setup_git_dir_gently() is run the second time. If $GIT_DIR is not set in the first run, we run the same setup_discovered_git_dir() as before. Nothing to see. If it is, however, we'll enter setup_explicit_git_dir() this time. This is where the "fun" is. If $GIT_WORK_TREE is not set but $GIT_DIR is, you are supposed to be at the root level of the worktree. But if you are in a subdir "foo/bar" (real worktree's top is "foo"), this rule bites you: your detected worktree is now "foo/bar", even though the first run correctly detected worktree as "foo". You get "internal error: work tree has already been set" as a result. Bottom line is, when $GIT_DIR is set, $GIT_WORK_TREE should be set too unless there's no work tree. But setting $GIT_WORK_TREE inside set_git_dir() may backfire. We don't know at that point if work tree is already configured by the caller. So set it when work tree is detected. It does not harm if $GIT_WORK_TREE is set while $GIT_DIR is not. Reported-by: Bjørnar Snoksrud <snoksrud@gmail.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> :100644 100644 9daa0ba4a36ced9f63541203e7bcc2ab9e1eae56 36fbba57fc83afd36d99bf5d4f3a1fc3feefba09 M environment.c :040000 040000 1d7c4bf77e0fd49ca315271993cb69a8b055c3aa 145d85895cb6cb0810597e1854a7721ccfc8f457 M t bisect run success ``` Causing me a few headaches in https://github.com/pre-commit/pre-commit/issues/300 I'm working around it in https://github.com/pre-commit/pre-commit/pull/301 Thanks, Anthony ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) 2015-11-24 2:22 ` Fwd: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) Anthony Sottile @ 2015-11-24 17:57 ` Stefan Beller 2015-11-25 20:13 ` Duy Nguyen 0 siblings, 1 reply; 39+ messages in thread From: Stefan Beller @ 2015-11-24 17:57 UTC (permalink / raw) To: Anthony Sottile, Duy Nguyen; +Cc: git@vger.kernel.org +to Nguyễn Thái Ngọc Duy <pclouds@gmail.com> On Mon, Nov 23, 2015 at 6:22 PM, Anthony Sottile <asottile@umich.edu> wrote: > * Short description of the problem * > > It seems GIT_WORK_DIR is now exported invariantly when calling git > hooks such as pre-commit. If these hooks involve cloning repositories > they will not fail due to this exported environment variable. This > was not the case in prior versions (such as v2.5.0). > > * Simple reproduction * > > ``` > $ cat test.sh > #!/usr/bin/env bash > set -ex > > rm -rf test > > # Exit non {0, 1} to abort git bisect > make -j 8 > /dev/null || exit 2 > > # Put our new git on the path > PATH="$(pwd):$PATH" > > git init test > > pushd test > mkdir -p .git/hooks > echo 'git clone git://github.com/asottile/css-explore css-explore' > > .git/hooks/pre-commit > chmod 755 .git/hooks/pre-commit > > git commit -m foo --allow-empty || exit 1 > ``` > > * Under 2.6.3 * > > ``` > $ ./test.sh > > ... > > + git init test > warning: templates not found /home/anthony/share/git-core/templates > Initialized empty Git repository in /home/anthony/workspace/git/test/.git/ > + pushd test > ~/workspace/git/test ~/workspace/git > + mkdir -p .git/hooks > + echo 'git clone git://github.com/asottile/css-explore css-explore' > + chmod 755 .git/hooks/pre-commit > + git commit -m foo --allow-empty > fatal: working tree '.' already exists. > + exit 1 > ``` > > * Under 2.5 * > > ``` > $ ./test.sh > > ... > > + git init test > warning: templates not found /home/anthony/share/git-core/templates > Initialized empty Git repository in /home/anthony/workspace/git/test/.git/ > + pushd test > ~/workspace/git/test ~/workspace/git > + mkdir -p .git/hooks > + echo 'git clone git://github.com/asottile/css-explore css-explore' > + chmod 755 .git/hooks/pre-commit > + git commit -m foo --allow-empty > Cloning into 'css-explore'... > warning: templates not found /home/anthony/share/git-core/templates > remote: Counting objects: 214, done. > remote: Total 214 (delta 0), reused 0 (delta 0), pack-reused 214 > Receiving objects: 100% (214/214), 25.89 KiB | 0 bytes/s, done. > Resolving deltas: 100% (129/129), done. > Checking connectivity... done. > [master (root-commit) 5eb999d] foo > ``` > > > * Bisect * > > ``` > $ git bisect good v2.5.0 > $ git bisect bad origin/master > $ git bisect run ./test.sh > > ... > > d95138e695d99d32dcad528a2a7974f434c51e79 is the first bad commit > commit d95138e695d99d32dcad528a2a7974f434c51e79 > Author: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> > Date: Fri Jun 26 17:37:35 2015 +0700 > > setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR > > In the test case, we run setup_git_dir_gently() the first time to read > $GIT_DIR/config so that we can resolve aliases. We'll enter > setup_discovered_git_dir() and may or may not call set_git_dir() near > the end of the function, depending on whether the detected git dir is > ".git" or not. This set_git_dir() will set env var $GIT_DIR. > > For normal repo, git dir detected via setup_discovered_git_dir() will be > ".git", and set_git_dir() is not called. If .git file is used however, > the git dir can't be ".git" and set_git_dir() is called and $GIT_DIR > set. This is the key of this problem. > > If we expand an alias (or autocorrect command names), then > setup_git_dir_gently() is run the second time. If $GIT_DIR is not set in > the first run, we run the same setup_discovered_git_dir() as before. > Nothing to see. If it is, however, we'll enter setup_explicit_git_dir() > this time. > > This is where the "fun" is. If $GIT_WORK_TREE is not set but > $GIT_DIR is, you are supposed to be at the root level of the > worktree. But if you are in a subdir "foo/bar" (real worktree's top > is "foo"), this rule bites you: your detected worktree is now > "foo/bar", even though the first run correctly detected worktree as > "foo". You get "internal error: work tree has already been set" as a > result. > > Bottom line is, when $GIT_DIR is set, $GIT_WORK_TREE should be set too > unless there's no work tree. But setting $GIT_WORK_TREE inside > set_git_dir() may backfire. We don't know at that point if work tree is > already configured by the caller. So set it when work tree is > detected. It does not harm if $GIT_WORK_TREE is set while $GIT_DIR is > not. > > Reported-by: Bjørnar Snoksrud <snoksrud@gmail.com> > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> > Signed-off-by: Junio C Hamano <gitster@pobox.com> > > :100644 100644 9daa0ba4a36ced9f63541203e7bcc2ab9e1eae56 > 36fbba57fc83afd36d99bf5d4f3a1fc3feefba09 M environment.c > :040000 040000 1d7c4bf77e0fd49ca315271993cb69a8b055c3aa > 145d85895cb6cb0810597e1854a7721ccfc8f457 M t > bisect run success > ``` > > Causing me a few headaches in > https://github.com/pre-commit/pre-commit/issues/300 > I'm working around it in https://github.com/pre-commit/pre-commit/pull/301 > > Thanks, > > Anthony > -- > To unsubscribe from this list: send the line "unsubscribe git" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) 2015-11-24 17:57 ` Stefan Beller @ 2015-11-25 20:13 ` Duy Nguyen 2015-11-30 19:01 ` Duy Nguyen 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-11-25 20:13 UTC (permalink / raw) To: Anthony Sottile; +Cc: git@vger.kernel.org, Stefan Beller On Tue, Nov 24, 2015 at 6:57 PM, Stefan Beller <sbeller@google.com> wrote: > +to Nguyễn Thái Ngọc Duy <pclouds@gmail.com> > > On Mon, Nov 23, 2015 at 6:22 PM, Anthony Sottile <asottile@umich.edu> wrote: >> * Short description of the problem * >> >> It seems GIT_WORK_DIR is now exported invariantly when calling git >> hooks such as pre-commit. If these hooks involve cloning repositories >> they will not fail due to this exported environment variable. This >> was not the case in prior versions (such as v2.5.0). I'm getting good at fixing one bug and adding ten more. I don't think the cited commit is the problem. It just exposes another bug. I did > ~/w/git $ GIT_WORK_TREE=abc ./git clone .git /tmp/def and what I got was really surprising, /tmp/def contains the git repository while the true worktree is in "abc". It does not make sense, at least from the first sight, unless it inherits this from git-init, where we do(?) want GIT_WORK_TREE to specify a separate worktree. No time to dig to the bottom yet.. -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) 2015-11-25 20:13 ` Duy Nguyen @ 2015-11-30 19:01 ` Duy Nguyen 2015-11-30 20:16 ` Junio C Hamano 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-11-30 19:01 UTC (permalink / raw) To: Anthony Sottile; +Cc: git@vger.kernel.org, Stefan Beller On Wed, Nov 25, 2015 at 9:13 PM, Duy Nguyen <pclouds@gmail.com> wrote: > On Tue, Nov 24, 2015 at 6:57 PM, Stefan Beller <sbeller@google.com> wrote: >> +to Nguyễn Thái Ngọc Duy <pclouds@gmail.com> >> >> On Mon, Nov 23, 2015 at 6:22 PM, Anthony Sottile <asottile@umich.edu> wrote: >>> * Short description of the problem * >>> >>> It seems GIT_WORK_DIR is now exported invariantly when calling git >>> hooks such as pre-commit. If these hooks involve cloning repositories >>> they will not fail due to this exported environment variable. This >>> was not the case in prior versions (such as v2.5.0). > > I'm getting good at fixing one bug and adding ten more. I don't think > the cited commit is the problem. It just exposes another bug. I did > >> ~/w/git $ GIT_WORK_TREE=abc ./git clone .git /tmp/def > > and what I got was really surprising, /tmp/def contains the git > repository while the true worktree is in "abc". It does not make > sense, at least from the first sight, unless it inherits this from > git-init, where we do(?) want GIT_WORK_TREE to specify a separate > worktree. No time to dig to the bottom yet.. I was wrong, GIT_WORK_TREE support was added in git-clone many years ago in 20ccef4 (make git-clone GIT_WORK_TREE aware - 2007-07-06). So my change accidentally triggers an (undocumented) feature. We could add a hack to ignore GIT_WORK_TREE if GIT_DIR is set too, but I don't think people will like it. I don't really like reverting d95138e (setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - 2015-06-26) because another bug reappears. So I'm out of options.. -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) 2015-11-30 19:01 ` Duy Nguyen @ 2015-11-30 20:16 ` Junio C Hamano 2015-12-01 17:59 ` Duy Nguyen 0 siblings, 1 reply; 39+ messages in thread From: Junio C Hamano @ 2015-11-30 20:16 UTC (permalink / raw) To: Duy Nguyen; +Cc: Anthony Sottile, git@vger.kernel.org, Stefan Beller Duy Nguyen <pclouds@gmail.com> writes: > I was wrong, GIT_WORK_TREE support was added in git-clone many years > ago in 20ccef4 (make git-clone GIT_WORK_TREE aware - 2007-07-06). So > my change accidentally triggers an (undocumented) feature. We could > add a hack to ignore GIT_WORK_TREE if GIT_DIR is set too, but I don't > think people will like it. I don't really like reverting d95138e > (setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - > 2015-06-26) because another bug reappears. > So I'm out of options.. Perhaps d95138e can be reverted and then the bug it tried to fix can be fixed in a different way somehow? (I am not quite up to speed yet, so the above may turn out to be infeasible--take it with a large grain of salt please). ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) 2015-11-30 20:16 ` Junio C Hamano @ 2015-12-01 17:59 ` Duy Nguyen 2015-12-02 17:09 ` Junio C Hamano 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-12-01 17:59 UTC (permalink / raw) To: Junio C Hamano, Jeff King Cc: Anthony Sottile, git@vger.kernel.org, Stefan Beller On Mon, Nov 30, 2015 at 9:16 PM, Junio C Hamano <gitster@pobox.com> wrote: > Duy Nguyen <pclouds@gmail.com> writes: > >> I was wrong, GIT_WORK_TREE support was added in git-clone many years >> ago in 20ccef4 (make git-clone GIT_WORK_TREE aware - 2007-07-06). So >> my change accidentally triggers an (undocumented) feature. We could >> add a hack to ignore GIT_WORK_TREE if GIT_DIR is set too, but I don't >> think people will like it. I don't really like reverting d95138e >> (setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - >> 2015-06-26) because another bug reappears. > >> So I'm out of options.. > > Perhaps d95138e can be reverted and then the bug it tried to fix can > be fixed in a different way somehow? > > (I am not quite up to speed yet, so the above may turn out to be > infeasible--take it with a large grain of salt please). That would mean we do not set $GIT_DIR too early. While it sounds good, it could be just another trap, and could be a lot of reorganizing setup code. I'm more tempted to revert 20ccef4, with deprecation warning for some releases, and a new git-clone option for the same functionality. But let me sleep on it (and everybody please give ideas if you have any). Meanwhile, maybe reverting d95138e should be done any way for now. Broken aliases are not as bad as broken hooks. -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) 2015-12-01 17:59 ` Duy Nguyen @ 2015-12-02 17:09 ` Junio C Hamano 2015-12-03 18:17 ` [PATCH 1/2] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy 2015-12-21 10:22 ` [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" Nguyễn Thái Ngọc Duy 0 siblings, 2 replies; 39+ messages in thread From: Junio C Hamano @ 2015-12-02 17:09 UTC (permalink / raw) To: Duy Nguyen; +Cc: Jeff King, Anthony Sottile, git@vger.kernel.org, Stefan Beller Duy Nguyen <pclouds@gmail.com> writes: > ... But let me sleep on it (and everybody please > give ideas if you have any). Meanwhile, maybe reverting d95138e should > be done any way for now. Broken aliases are not as bad as broken > hooks. OK, when/if you decide that our first step should be a revert of d95138e please send in a patch to do so with a brief write-up of a follow-up plan. Thanks. ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH 1/2] git.c: make it clear save_env() is for alias handling only 2015-12-02 17:09 ` Junio C Hamano @ 2015-12-03 18:17 ` Nguyễn Thái Ngọc Duy 2015-12-03 18:17 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Nguyễn Thái Ngọc Duy 2015-12-21 10:22 ` [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" Nguyễn Thái Ngọc Duy 1 sibling, 2 replies; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-03 18:17 UTC (permalink / raw) To: git Cc: Junio C Hamano, sbeller, asottile, Nguyễn Thái Ngọc Duy Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> --- git.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/git.c b/git.c index 6ed824c..6ce7043 100644 --- a/git.c +++ b/git.c @@ -25,14 +25,14 @@ static const char *env_names[] = { GIT_PREFIX_ENVIRONMENT }; static char *orig_env[4]; -static int saved_environment; +static int saved_env_before_alias; -static void save_env(void) +static void save_env_before_alias(void) { int i; - if (saved_environment) + if (saved_env_before_alias) return; - saved_environment = 1; + saved_env_before_alias = 1; orig_cwd = xgetcwd(); for (i = 0; i < ARRAY_SIZE(env_names); i++) { orig_env[i] = getenv(env_names[i]); @@ -233,6 +233,7 @@ static int handle_alias(int *argcp, const char ***argv) char *alias_string; int unused_nongit; + save_env_before_alias(); subdir = setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; @@ -530,7 +531,7 @@ static void handle_builtin(int argc, const char **argv) builtin = get_builtin(cmd); if (builtin) { - if (saved_environment && (builtin->option & NO_SETUP)) + if (saved_env_before_alias && (builtin->option & NO_SETUP)) restore_env(); else exit(run_builtin(builtin, argc, argv)); @@ -590,7 +591,6 @@ static int run_argv(int *argcp, const char ***argv) */ if (done_alias) break; - save_env(); if (!handle_alias(argcp, argv)) break; done_alias = 1; -- 2.2.0.513.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when .. 2015-12-03 18:17 ` [PATCH 1/2] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy @ 2015-12-03 18:17 ` Nguyễn Thái Ngọc Duy 2015-12-04 20:35 ` Junio C Hamano ` (2 more replies) 2015-12-20 7:50 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Nguyễn Thái Ngọc Duy 1 sibling, 3 replies; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-03 18:17 UTC (permalink / raw) To: git Cc: Junio C Hamano, sbeller, asottile, Nguyễn Thái Ngọc Duy Commit d95138e [1] fixes a .git file problem by setting GIT_WORK_TREE whenever GIT_DIR is set. It sounded harmless because we handle GIT_DIR and GIT_WORK_TREE side by side for most commands, with two exceptions: git-init and git-clone. "git clone" is not happy with d95138e. This command ignores GIT_DIR but respects GIT_WORK_TREE [2] [3] which means it used to run fine from a hook, where GIT_DIR was set but GIT_WORK_TREE was not (*). With d95138e, GIT_WORK_TREE is set all the time and git-clone interprets that as "I give you order to put the worktree here", usually against the user's intention. The solution in d95138e is reverted in this commit. Instead we reuse the solution from c056261 [4]. c056261 fixes another setup-messed-up-by-alias by saving and restoring env for git-clone and git-init. Now I conclude that setup-messed-by-alias is always evil. So the env restoration is done for _all_ commands whenever aliases are involved. It fixes what d95138e tries to fix. And it does not upset git-clone-inside-hooks. The test from d95138e remains to verify it's not broken by this. A new test is added to make sure git-clone-inside-hooks remains happy. In future, perhaps we should look up aliases in a separate process (provided that Windows folks are happy with one extra process). It'll be cleanest. (*) GIT_WORK_TREE was not set _most of the time_. In some cases GIT_WORK_TREE is set and git-clone will behave differently. The use of GIT_WORK_TREE to direct git-clone to put work tree elsewhere looks like a mistake because it causes surprises this way. But that's a separate story. [1] d95138e (setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - 2015-06-26) [2] 2beebd2 (clone: create intermediate directories of destination repo - 2008-06-25) [3] 20ccef4 (make git-clone GIT_WORK_TREE aware - 2007-07-06) [4] c056261 (git potty: restore environments after alias expansion - 2014-06-08) Reported-by: Anthony Sottile <asottile@umich.edu> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> --- This may be a brilliant fix, or another invitation for regressions. environment.c | 2 -- git.c | 9 ++++----- t/t5601-clone.sh | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/environment.c b/environment.c index 2da7fe2..1cc4aab 100644 --- a/environment.c +++ b/environment.c @@ -235,8 +235,6 @@ void set_git_work_tree(const char *new_work_tree) } git_work_tree_initialized = 1; work_tree = xstrdup(real_path(new_work_tree)); - if (setenv(GIT_WORK_TREE_ENVIRONMENT, work_tree, 1)) - die("could not set GIT_WORK_TREE to '%s'", work_tree); } const char *get_git_work_tree(void) diff --git a/git.c b/git.c index 6ce7043..e2f187d 100644 --- a/git.c +++ b/git.c @@ -308,7 +308,6 @@ static int handle_alias(int *argcp, const char ***argv) * RUN_SETUP for reading from the configuration file. */ #define NEED_WORK_TREE (1<<3) -#define NO_SETUP (1<<4) struct cmd_struct { const char *cmd; @@ -390,7 +389,7 @@ static struct cmd_struct commands[] = { { "cherry", cmd_cherry, RUN_SETUP }, { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE }, { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, - { "clone", cmd_clone, NO_SETUP }, + { "clone", cmd_clone }, { "column", cmd_column, RUN_SETUP_GENTLY }, { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, { "commit-tree", cmd_commit_tree, RUN_SETUP }, @@ -416,8 +415,8 @@ static struct cmd_struct commands[] = { { "hash-object", cmd_hash_object }, { "help", cmd_help }, { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, - { "init", cmd_init_db, NO_SETUP }, - { "init-db", cmd_init_db, NO_SETUP }, + { "init", cmd_init_db }, + { "init-db", cmd_init_db }, { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY }, { "log", cmd_log, RUN_SETUP }, { "ls-files", cmd_ls_files, RUN_SETUP }, @@ -531,7 +530,7 @@ static void handle_builtin(int argc, const char **argv) builtin = get_builtin(cmd); if (builtin) { - if (saved_env_before_alias && (builtin->option & NO_SETUP)) + if (saved_env_before_alias) restore_env(); else exit(run_builtin(builtin, argc, argv)); diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 9b34f3c..31b4658 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -65,6 +65,29 @@ test_expect_success 'clone respects GIT_WORK_TREE' ' ' +test_expect_success 'clone from hooks' ' + + test_create_repo r0 && + cd r0 && + test_commit initial && + cd .. && + git init r1 && + cd r1 && + cat >.git/hooks/pre-commit <<-\EOF && + #!/bin/sh + git clone ../r0 ../r2 + exit 1 + EOF + chmod u+x .git/hooks/pre-commit && + : >file && + git add file && + test_must_fail git commit -m invoke-hook && + cd .. && + test_cmp r0/.git/HEAD r2/.git/HEAD && + test_cmp r0/initial.t r2/initial.t + +' + test_expect_success 'clone creates intermediate directories' ' git clone src long/path/to/dst && -- 2.2.0.513.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when .. 2015-12-03 18:17 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy @ 2015-12-04 20:35 ` Junio C Hamano 2015-12-05 5:48 ` Duy Nguyen 2015-12-05 15:32 ` [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts Nguyễn Thái Ngọc Duy 2015-12-05 19:12 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Duy Nguyen 2 siblings, 1 reply; 39+ messages in thread From: Junio C Hamano @ 2015-12-04 20:35 UTC (permalink / raw) To: Nguyễn Thái Ngọc Duy; +Cc: git, sbeller, asottile Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: > ... Now I conclude > that setup-messed-by-alias is always evil. So the env restoration is > done for _all_ commands whenever aliases are involved. So a side effect of this is whenever an alias is involved, all commands are re-spawned, not just the external ones but builtins as well. > This may be a brilliant fix, or another invitation for regressions. ;-) ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when .. 2015-12-04 20:35 ` Junio C Hamano @ 2015-12-05 5:48 ` Duy Nguyen 0 siblings, 0 replies; 39+ messages in thread From: Duy Nguyen @ 2015-12-05 5:48 UTC (permalink / raw) To: Junio C Hamano; +Cc: Git Mailing List, Stefan Beller, Anthony Sottile On Fri, Dec 4, 2015 at 9:35 PM, Junio C Hamano <gitster@pobox.com> wrote: > Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: > >> ... Now I conclude >> that setup-messed-by-alias is always evil. So the env restoration is >> done for _all_ commands whenever aliases are involved. > > So a side effect of this is whenever an alias is involved, all > commands are re-spawned, not just the external ones but builtins as > well. I missed that while re-reading c056261, but yes that's true. So Windows folks will be grumpy anyway. Maybe we can avoid that in certain (safe) cases, when we know the second setup_git_... will be executed by the builtin command and won't have any side effects, which is probably the common case. But let's see how it goes. -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts 2015-12-03 18:17 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy 2015-12-04 20:35 ` Junio C Hamano @ 2015-12-05 15:32 ` Nguyễn Thái Ngọc Duy 2015-12-07 18:54 ` Junio C Hamano 2015-12-05 19:12 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Duy Nguyen 2 siblings, 1 reply; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-05 15:32 UTC (permalink / raw) To: git Cc: Junio C Hamano, sbeller, asottile, Nguyễn Thái Ngọc Duy The unfortunate commit d95138e (setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - 2015-06-26) exposes another problem, besides git-clone that's described in the previous commit. If GIT_WORK_TREE (or even GIT_DIR) is exported to an alias script, it may mislead git commands in the script where the repo is. Granted, most scripts work on the repo where the alias is summoned from. But nowhere do we forbid the script to visit another repository. The revert of d95138e in the previous commit is sufficient as a fix. However, to protect us from accidentally leaking GIT_* environment variables again, we restore certain sensitive env before calling the external script. GIT_PREFIX is let through because there's another setup side effect that we simply accepted so far: current working directory is moved. Maybe in future we can introduce a new alias format that guarantees no cwd move, then we can unexport GIT_PREFIX. Reported-by: Gabriel Ganne <gabriel.ganne@gmail.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> --- Let's hope there will be no third report about this commit.. git.c | 10 +++++++--- t/t0001-init.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/git.c b/git.c index e2f187d..83b6c56 100644 --- a/git.c +++ b/git.c @@ -41,13 +41,16 @@ static void save_env_before_alias(void) } } -static void restore_env(void) +static void restore_env(int external_alias) { int i; - if (orig_cwd && chdir(orig_cwd)) + if (!external_alias && orig_cwd && chdir(orig_cwd)) die_errno("could not move to %s", orig_cwd); free(orig_cwd); for (i = 0; i < ARRAY_SIZE(env_names); i++) { + if (external_alias && + !strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT)) + continue; if (orig_env[i]) setenv(env_names[i], orig_env[i], 1); else @@ -244,6 +247,7 @@ static int handle_alias(int *argcp, const char ***argv) int argc = *argcp, i; commit_pager_choice(); + restore_env(1); /* build alias_argv */ alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1)); @@ -531,7 +535,7 @@ static void handle_builtin(int argc, const char **argv) builtin = get_builtin(cmd); if (builtin) { if (saved_env_before_alias) - restore_env(); + restore_env(0); else exit(run_builtin(builtin, argc, argv)); } diff --git a/t/t0001-init.sh b/t/t0001-init.sh index f91bbcf..19539fc 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -87,6 +87,33 @@ test_expect_success 'plain nested in bare through aliased command' ' check_config bare-ancestor-aliased.git/plain-nested/.git false unset ' +test_expect_success 'No extra GIT_* on alias scripts' ' + cat <<-\EOF >expected && + GIT_ATTR_NOSYSTEM + GIT_AUTHOR_EMAIL + GIT_AUTHOR_NAME + GIT_COMMITTER_EMAIL + GIT_COMMITTER_NAME + GIT_CONFIG_NOSYSTEM + GIT_EXEC_PATH + GIT_MERGE_AUTOEDIT + GIT_MERGE_VERBOSITY + GIT_PREFIX + GIT_TEMPLATE_DIR + GIT_TEXTDOMAINDIR + GIT_TRACE_BARE + EOF + cat <<-\EOF >script && + #!/bin/sh + env | grep GIT_ | sed "s/=.*//" | sort >actual + exit 0 + EOF + chmod 755 script && + git config alias.script \!./script && + ( mkdir sub && cd sub && git script ) && + test_cmp expected actual +' + test_expect_success 'plain with GIT_WORK_TREE' ' mkdir plain-wt && test_must_fail env GIT_WORK_TREE="$(pwd)/plain-wt" git init plain-wt -- 2.2.0.513.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts 2015-12-05 15:32 ` [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts Nguyễn Thái Ngọc Duy @ 2015-12-07 18:54 ` Junio C Hamano 2015-12-08 16:55 ` Duy Nguyen 0 siblings, 1 reply; 39+ messages in thread From: Junio C Hamano @ 2015-12-07 18:54 UTC (permalink / raw) To: Nguyễn Thái Ngọc Duy; +Cc: git, sbeller, asottile Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: > Let's hope there will be no third report about this commit.. Hmm, why does this additional test fail only under prove but pass without it? > diff --git a/t/t0001-init.sh b/t/t0001-init.sh > index f91bbcf..19539fc 100755 > --- a/t/t0001-init.sh > +++ b/t/t0001-init.sh > @@ -87,6 +87,33 @@ test_expect_success 'plain nested in bare through aliased command' ' > check_config bare-ancestor-aliased.git/plain-nested/.git false unset > ' > > +test_expect_success 'No extra GIT_* on alias scripts' ' > + cat <<-\EOF >expected && > + GIT_ATTR_NOSYSTEM > + GIT_AUTHOR_EMAIL > + GIT_AUTHOR_NAME > + GIT_COMMITTER_EMAIL > + GIT_COMMITTER_NAME > + GIT_CONFIG_NOSYSTEM > + GIT_EXEC_PATH > + GIT_MERGE_AUTOEDIT > + GIT_MERGE_VERBOSITY > + GIT_PREFIX > + GIT_TEMPLATE_DIR > + GIT_TEXTDOMAINDIR > + GIT_TRACE_BARE > + EOF > + cat <<-\EOF >script && > + #!/bin/sh > + env | grep GIT_ | sed "s/=.*//" | sort >actual This is more about coding discipline than style, but piping grep output to sed is wasteful. "sed -ne '/^GIT_/s/=.*//p'" or something like that, perhaps? I wondered what happens if the user has an unrelated stray variable whose name happens to begin with GIT_ in her environment, but it turns out that we cleanse them in test-lib.sh fairly early, so that would be fine. You need to tighten your "grep" pattern, though. > + exit 0 > + EOF > + chmod 755 script && > + git config alias.script \!./script && > + ( mkdir sub && cd sub && git script ) && > + test_cmp expected actual > +' > + > test_expect_success 'plain with GIT_WORK_TREE' ' > mkdir plain-wt && > test_must_fail env GIT_WORK_TREE="$(pwd)/plain-wt" git init plain-wt ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts 2015-12-07 18:54 ` Junio C Hamano @ 2015-12-08 16:55 ` Duy Nguyen 2015-12-08 17:20 ` Jeff King 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-12-08 16:55 UTC (permalink / raw) To: Junio C Hamano; +Cc: Git Mailing List, Stefan Beller, Anthony Sottile On Mon, Dec 7, 2015 at 7:54 PM, Junio C Hamano <gitster@pobox.com> wrote: > Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: > >> Let's hope there will be no third report about this commit.. > > Hmm, why does this additional test fail only under prove but pass > without it? It passes with prove for me. Some mysterious variable leaks through somehow? >> + env | grep GIT_ | sed "s/=.*//" | sort >actual > > This is more about coding discipline than style, but piping grep > output to sed is wasteful. "sed -ne '/^GIT_/s/=.*//p'" or something > like that, perhaps? OK will fix. > I wondered what happens if the user has an unrelated stray variable > whose name happens to begin with GIT_ in her environment, but it > turns out that we cleanse them in test-lib.sh fairly early, so that > would be fine. You need to tighten your "grep" pattern, though. OK -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts 2015-12-08 16:55 ` Duy Nguyen @ 2015-12-08 17:20 ` Jeff King 2015-12-08 23:55 ` Junio C Hamano 0 siblings, 1 reply; 39+ messages in thread From: Jeff King @ 2015-12-08 17:20 UTC (permalink / raw) To: Duy Nguyen Cc: Junio C Hamano, Git Mailing List, Stefan Beller, Anthony Sottile On Tue, Dec 08, 2015 at 05:55:20PM +0100, Duy Nguyen wrote: > On Mon, Dec 7, 2015 at 7:54 PM, Junio C Hamano <gitster@pobox.com> wrote: > > Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: > > > >> Let's hope there will be no third report about this commit.. > > > > Hmm, why does this additional test fail only under prove but pass > > without it? > > It passes with prove for me. Some mysterious variable leaks through somehow? It fails for me when run via "make" (with prove or without) but not as "./t0001-init.sh". Looks like extra variables from my config.mak leak through: $ make t0001-init.sh GIT_TEST_OPTS="-v -i" [...] --- expected 2015-12-08 17:18:06.304699181 +0000 +++ actual 2015-12-08 17:18:06.312699180 +0000 @@ -9,5 +9,9 @@ GIT_MERGE_VERBOSITY GIT_PREFIX GIT_TEMPLATE_DIR +GIT_TEST_GIT_DAEMON +GIT_TEST_HTTPD +GIT_TEST_OPTS GIT_TEXTDOMAINDIR GIT_TRACE_BARE +MAKEFLAGS not ok 6 - No extra GIT_* on alias scripts Any GIT_TEST_* is allowed through by test-lib.sh. For the MAKEFLAGS one, I suspect it's hitting MAKEFLAGS=GIT_TEST_OPTS=... You should probably anchor your regex. :) -Peff ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts 2015-12-08 17:20 ` Jeff King @ 2015-12-08 23:55 ` Junio C Hamano 0 siblings, 0 replies; 39+ messages in thread From: Junio C Hamano @ 2015-12-08 23:55 UTC (permalink / raw) To: Jeff King; +Cc: Duy Nguyen, Git Mailing List, Stefan Beller, Anthony Sottile Jeff King <peff@peff.net> writes: > It fails for me when run via "make" (with prove or without) but not as > "./t0001-init.sh". Looks like extra variables from my config.mak leak > through: > > $ make t0001-init.sh GIT_TEST_OPTS="-v -i" > [...] > --- expected 2015-12-08 17:18:06.304699181 +0000 > +++ actual 2015-12-08 17:18:06.312699180 +0000 > @@ -9,5 +9,9 @@ > GIT_MERGE_VERBOSITY > GIT_PREFIX > GIT_TEMPLATE_DIR > +GIT_TEST_GIT_DAEMON > +GIT_TEST_HTTPD > +GIT_TEST_OPTS > GIT_TEXTDOMAINDIR > GIT_TRACE_BARE > +MAKEFLAGS > not ok 6 - No extra GIT_* on alias scripts > > Any GIT_TEST_* is allowed through by test-lib.sh. Also GIT_PROVE_OPTS (which caused false positive for me). Perhaps grab "env" output outside the alias to create the expected (instead of a random handcrafted list that you have to maintain as the test suite evolves), and compare it from within the alias, or something? ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when .. 2015-12-03 18:17 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy 2015-12-04 20:35 ` Junio C Hamano 2015-12-05 15:32 ` [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts Nguyễn Thái Ngọc Duy @ 2015-12-05 19:12 ` Duy Nguyen 2015-12-07 18:33 ` Junio C Hamano 2 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-12-05 19:12 UTC (permalink / raw) To: Git Mailing List Cc: Junio C Hamano, Stefan Beller, Anthony Sottile, Nguyễn Thái Ngọc Duy On Thu, Dec 3, 2015 at 7:17 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote: > The solution in d95138e is reverted in this commit. Instead we reuse the > solution from c056261 [4]. c056261 fixes another setup-messed-up-by-alias > by saving and restoring env for git-clone and git-init. Now I conclude > that setup-messed-by-alias is always evil. So the env restoration is > done for _all_ commands whenever aliases are involved. It fixes what > d95138e tries to fix. And it does not upset git-clone-inside-hooks. (Reviewer hat on) I wrote env restoration is done for all commands, but the patch is actually about all _builtin_ commands. External ones do not receive this treatment. FIx is in the next reroll. -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when .. 2015-12-05 19:12 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Duy Nguyen @ 2015-12-07 18:33 ` Junio C Hamano 0 siblings, 0 replies; 39+ messages in thread From: Junio C Hamano @ 2015-12-07 18:33 UTC (permalink / raw) To: Duy Nguyen; +Cc: Git Mailing List, Stefan Beller, Anthony Sottile Duy Nguyen <pclouds@gmail.com> writes: > On Thu, Dec 3, 2015 at 7:17 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote: >> The solution in d95138e is reverted in this commit. Instead we reuse the >> solution from c056261 [4]. c056261 fixes another setup-messed-up-by-alias >> by saving and restoring env for git-clone and git-init. Now I conclude >> that setup-messed-by-alias is always evil. So the env restoration is >> done for _all_ commands whenever aliases are involved. It fixes what >> d95138e tries to fix. And it does not upset git-clone-inside-hooks. > > (Reviewer hat on) I wrote env restoration is done for all commands, > but the patch is actually about all _builtin_ commands. External ones > do not receive this treatment. FIx is in the next reroll. Thanks for being careful. ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-03 18:17 ` [PATCH 1/2] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy 2015-12-03 18:17 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 ` Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 1/3] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy ` (3 more replies) 1 sibling, 4 replies; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 UTC (permalink / raw) To: git Cc: Junio C Hamano, sbeller, asottile, Nguyễn Thái Ngọc Duy Changes since v1: - make sure we save/restore env for external commands in 2/3 - fix t0001 test in 3/3 Interdiff: diff --git b/git.c a/git.c index 83b6c56..da278c3 100644 --- b/git.c +++ a/git.c @@ -229,7 +229,6 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) static int handle_alias(int *argcp, const char ***argv) { int envchanged = 0, ret = 0, saved_errno = errno; - const char *subdir; int count, option_count; const char **new_argv; const char *alias_command; @@ -237,7 +236,7 @@ static int handle_alias(int *argcp, const char ***argv) int unused_nongit; save_env_before_alias(); - subdir = setup_git_directory_gently(&unused_nongit); + setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; alias_string = alias_lookup(alias_command); @@ -296,8 +295,7 @@ static int handle_alias(int *argcp, const char ***argv) ret = 1; } - if (subdir && chdir(subdir)) - die_errno("Cannot change to '%s'", subdir); + restore_env(0); errno = saved_errno; @@ -534,9 +532,13 @@ static void handle_builtin(int argc, const char **argv) builtin = get_builtin(cmd); if (builtin) { - if (saved_env_before_alias) - restore_env(0); - else + /* + * XXX: if we can figure out cases where it is _safe_ + * to do, we can avoid spawning a new process when + * saved_env_before_alias is true + * (i.e. setup_git_dir* has been run once) + */ + if (!saved_env_before_alias) exit(run_builtin(builtin, argc, argv)); } } diff --git b/t/t0001-init.sh a/t/t0001-init.sh index 19539fc..295aa59 100755 --- b/t/t0001-init.sh +++ a/t/t0001-init.sh @@ -88,24 +88,14 @@ test_expect_success 'plain nested in bare through aliased command' ' ' test_expect_success 'No extra GIT_* on alias scripts' ' - cat <<-\EOF >expected && - GIT_ATTR_NOSYSTEM - GIT_AUTHOR_EMAIL - GIT_AUTHOR_NAME - GIT_COMMITTER_EMAIL - GIT_COMMITTER_NAME - GIT_CONFIG_NOSYSTEM - GIT_EXEC_PATH - GIT_MERGE_AUTOEDIT - GIT_MERGE_VERBOSITY - GIT_PREFIX - GIT_TEMPLATE_DIR - GIT_TEXTDOMAINDIR - GIT_TRACE_BARE - EOF + ( + env | sed -ne "/^GIT_/s/=.*//p" && + echo GIT_PREFIX && # setup.c + echo GIT_TEXTDOMAINDIR # wrapper-for-bin.sh + ) | sort | uniq >expected && cat <<-\EOF >script && #!/bin/sh - env | grep GIT_ | sed "s/=.*//" | sort >actual + env | sed -ne "/^GIT_/s/=.*//p" | sort >actual exit 0 EOF chmod 755 script && Nguyễn Thái Ngọc Duy (3): git.c: make it clear save_env() is for alias handling only setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when .. git.c: make sure we do not leak GIT_* to alias scripts environment.c | 2 -- git.c | 41 +++++++++++++++++++++++------------------ t/t0001-init.sh | 17 +++++++++++++++++ t/t5601-clone.sh | 23 +++++++++++++++++++++++ 4 files changed, 63 insertions(+), 20 deletions(-) -- 2.3.0.rc1.137.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v2 1/3] git.c: make it clear save_env() is for alias handling only 2015-12-20 7:50 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 ` Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 2/3] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy ` (2 subsequent siblings) 3 siblings, 0 replies; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 UTC (permalink / raw) To: git Cc: Junio C Hamano, sbeller, asottile, Nguyễn Thái Ngọc Duy Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> --- git.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/git.c b/git.c index 6ed824c..6ce7043 100644 --- a/git.c +++ b/git.c @@ -25,14 +25,14 @@ static const char *env_names[] = { GIT_PREFIX_ENVIRONMENT }; static char *orig_env[4]; -static int saved_environment; +static int saved_env_before_alias; -static void save_env(void) +static void save_env_before_alias(void) { int i; - if (saved_environment) + if (saved_env_before_alias) return; - saved_environment = 1; + saved_env_before_alias = 1; orig_cwd = xgetcwd(); for (i = 0; i < ARRAY_SIZE(env_names); i++) { orig_env[i] = getenv(env_names[i]); @@ -233,6 +233,7 @@ static int handle_alias(int *argcp, const char ***argv) char *alias_string; int unused_nongit; + save_env_before_alias(); subdir = setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; @@ -530,7 +531,7 @@ static void handle_builtin(int argc, const char **argv) builtin = get_builtin(cmd); if (builtin) { - if (saved_environment && (builtin->option & NO_SETUP)) + if (saved_env_before_alias && (builtin->option & NO_SETUP)) restore_env(); else exit(run_builtin(builtin, argc, argv)); @@ -590,7 +591,6 @@ static int run_argv(int *argcp, const char ***argv) */ if (done_alias) break; - save_env(); if (!handle_alias(argcp, argv)) break; done_alias = 1; -- 2.3.0.rc1.137.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v2 2/3] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when .. 2015-12-20 7:50 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 1/3] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 ` Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 3/3] git.c: make sure we do not leak GIT_* to alias scripts Nguyễn Thái Ngọc Duy 2015-12-21 21:18 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Junio C Hamano 3 siblings, 0 replies; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 UTC (permalink / raw) To: git Cc: Junio C Hamano, sbeller, asottile, Nguyễn Thái Ngọc Duy Commit d95138e [1] fixes a .git file problem by setting GIT_WORK_TREE whenever GIT_DIR is set. It sounded harmless because we handle GIT_DIR and GIT_WORK_TREE side by side for most commands, with two exceptions: git-init and git-clone. "git clone" is not happy with d95138e. This command ignores GIT_DIR but respects GIT_WORK_TREE [2] [3] which means it used to run fine from a hook, where GIT_DIR was set but GIT_WORK_TREE was not (*). With d95138e, GIT_WORK_TREE is set all the time and git-clone interprets that as "I give you order to put the worktree here", usually against the user's intention. The solution in d95138e is reverted in this commit. Instead we reuse the solution from c056261 [4]. c056261 fixes another setup-messed- up-by-alias by saving and restoring env and spawning a new process, but for git-clone and git-init only. Now I conclude that setup-messed- up-by-alias is always evil. So the env restoration is done for _all_ commands, including external ones, whenever aliases are involved. It fixes what d95138e tries to fix. And it does not upset git-clone- inside-hooks. The test from d95138e remains to verify it's not broken by this. A new test is added to make sure git-clone-inside-hooks remains happy. (*) GIT_WORK_TREE was not set _most of the time_. In some cases GIT_WORK_TREE is set and git-clone will behave differently. The use of GIT_WORK_TREE to direct git-clone to put work tree elsewhere looks like a mistake because it causes surprises this way. But that's a separate story. [1] d95138e (setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - 2015-06-26) [2] 2beebd2 (clone: create intermediate directories of destination repo - 2008-06-25) [3] 20ccef4 (make git-clone GIT_WORK_TREE aware - 2007-07-06) [4] c056261 (git potty: restore environments after alias expansion - 2014-06-08) Reported-by: Anthony Sottile <asottile@umich.edu> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> --- environment.c | 2 -- git.c | 23 ++++++++++++----------- t/t5601-clone.sh | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/environment.c b/environment.c index 2da7fe2..1cc4aab 100644 --- a/environment.c +++ b/environment.c @@ -235,8 +235,6 @@ void set_git_work_tree(const char *new_work_tree) } git_work_tree_initialized = 1; work_tree = xstrdup(real_path(new_work_tree)); - if (setenv(GIT_WORK_TREE_ENVIRONMENT, work_tree, 1)) - die("could not set GIT_WORK_TREE to '%s'", work_tree); } const char *get_git_work_tree(void) diff --git a/git.c b/git.c index 6ce7043..1a7d399 100644 --- a/git.c +++ b/git.c @@ -226,7 +226,6 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) static int handle_alias(int *argcp, const char ***argv) { int envchanged = 0, ret = 0, saved_errno = errno; - const char *subdir; int count, option_count; const char **new_argv; const char *alias_command; @@ -234,7 +233,7 @@ static int handle_alias(int *argcp, const char ***argv) int unused_nongit; save_env_before_alias(); - subdir = setup_git_directory_gently(&unused_nongit); + setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; alias_string = alias_lookup(alias_command); @@ -292,8 +291,7 @@ static int handle_alias(int *argcp, const char ***argv) ret = 1; } - if (subdir && chdir(subdir)) - die_errno("Cannot change to '%s'", subdir); + restore_env(); errno = saved_errno; @@ -308,7 +306,6 @@ static int handle_alias(int *argcp, const char ***argv) * RUN_SETUP for reading from the configuration file. */ #define NEED_WORK_TREE (1<<3) -#define NO_SETUP (1<<4) struct cmd_struct { const char *cmd; @@ -390,7 +387,7 @@ static struct cmd_struct commands[] = { { "cherry", cmd_cherry, RUN_SETUP }, { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE }, { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, - { "clone", cmd_clone, NO_SETUP }, + { "clone", cmd_clone }, { "column", cmd_column, RUN_SETUP_GENTLY }, { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, { "commit-tree", cmd_commit_tree, RUN_SETUP }, @@ -416,8 +413,8 @@ static struct cmd_struct commands[] = { { "hash-object", cmd_hash_object }, { "help", cmd_help }, { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, - { "init", cmd_init_db, NO_SETUP }, - { "init-db", cmd_init_db, NO_SETUP }, + { "init", cmd_init_db }, + { "init-db", cmd_init_db }, { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY }, { "log", cmd_log, RUN_SETUP }, { "ls-files", cmd_ls_files, RUN_SETUP }, @@ -531,9 +528,13 @@ static void handle_builtin(int argc, const char **argv) builtin = get_builtin(cmd); if (builtin) { - if (saved_env_before_alias && (builtin->option & NO_SETUP)) - restore_env(); - else + /* + * XXX: if we can figure out cases where it is _safe_ + * to do, we can avoid spawning a new process when + * saved_env_before_alias is true + * (i.e. setup_git_dir* has been run once) + */ + if (!saved_env_before_alias) exit(run_builtin(builtin, argc, argv)); } } diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 9b34f3c..31b4658 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -65,6 +65,29 @@ test_expect_success 'clone respects GIT_WORK_TREE' ' ' +test_expect_success 'clone from hooks' ' + + test_create_repo r0 && + cd r0 && + test_commit initial && + cd .. && + git init r1 && + cd r1 && + cat >.git/hooks/pre-commit <<-\EOF && + #!/bin/sh + git clone ../r0 ../r2 + exit 1 + EOF + chmod u+x .git/hooks/pre-commit && + : >file && + git add file && + test_must_fail git commit -m invoke-hook && + cd .. && + test_cmp r0/.git/HEAD r2/.git/HEAD && + test_cmp r0/initial.t r2/initial.t + +' + test_expect_success 'clone creates intermediate directories' ' git clone src long/path/to/dst && -- 2.3.0.rc1.137.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* [PATCH v2 3/3] git.c: make sure we do not leak GIT_* to alias scripts 2015-12-20 7:50 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 1/3] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 2/3] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 ` Nguyễn Thái Ngọc Duy 2015-12-21 21:18 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Junio C Hamano 3 siblings, 0 replies; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-20 7:50 UTC (permalink / raw) To: git Cc: Junio C Hamano, sbeller, asottile, Nguyễn Thái Ngọc Duy The unfortunate commit d95138e (setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR - 2015-06-26) exposes another problem, besides git-clone that's described in the previous commit. If GIT_WORK_TREE (or even GIT_DIR) is exported to an alias script, it may mislead git commands in the script where the repo is. Granted, most scripts work on the repo where the alias is summoned from. But nowhere do we forbid the script to visit another repository. The revert of d95138e in the previous commit is sufficient as a fix. However, to protect us from accidentally leaking GIT_* environment variables again, we restore certain sensitive env before calling the external script. GIT_PREFIX is let through because there's another setup side effect that we simply accepted so far: current working directory is moved. Maybe in future we can introduce a new alias format that guarantees no cwd move, then we can unexport GIT_PREFIX. Reported-by: Gabriel Ganne <gabriel.ganne@gmail.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> --- git.c | 10 +++++++--- t/t0001-init.sh | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/git.c b/git.c index 1a7d399..da278c3 100644 --- a/git.c +++ b/git.c @@ -41,13 +41,16 @@ static void save_env_before_alias(void) } } -static void restore_env(void) +static void restore_env(int external_alias) { int i; - if (orig_cwd && chdir(orig_cwd)) + if (!external_alias && orig_cwd && chdir(orig_cwd)) die_errno("could not move to %s", orig_cwd); free(orig_cwd); for (i = 0; i < ARRAY_SIZE(env_names); i++) { + if (external_alias && + !strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT)) + continue; if (orig_env[i]) setenv(env_names[i], orig_env[i], 1); else @@ -243,6 +246,7 @@ static int handle_alias(int *argcp, const char ***argv) int argc = *argcp, i; commit_pager_choice(); + restore_env(1); /* build alias_argv */ alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1)); @@ -291,7 +295,7 @@ static int handle_alias(int *argcp, const char ***argv) ret = 1; } - restore_env(); + restore_env(0); errno = saved_errno; diff --git a/t/t0001-init.sh b/t/t0001-init.sh index f91bbcf..295aa59 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -87,6 +87,23 @@ test_expect_success 'plain nested in bare through aliased command' ' check_config bare-ancestor-aliased.git/plain-nested/.git false unset ' +test_expect_success 'No extra GIT_* on alias scripts' ' + ( + env | sed -ne "/^GIT_/s/=.*//p" && + echo GIT_PREFIX && # setup.c + echo GIT_TEXTDOMAINDIR # wrapper-for-bin.sh + ) | sort | uniq >expected && + cat <<-\EOF >script && + #!/bin/sh + env | sed -ne "/^GIT_/s/=.*//p" | sort >actual + exit 0 + EOF + chmod 755 script && + git config alias.script \!./script && + ( mkdir sub && cd sub && git script ) && + test_cmp expected actual +' + test_expect_success 'plain with GIT_WORK_TREE' ' mkdir plain-wt && test_must_fail env GIT_WORK_TREE="$(pwd)/plain-wt" git init plain-wt -- 2.3.0.rc1.137.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-20 7:50 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Nguyễn Thái Ngọc Duy ` (2 preceding siblings ...) 2015-12-20 7:50 ` [PATCH v2 3/3] git.c: make sure we do not leak GIT_* to alias scripts Nguyễn Thái Ngọc Duy @ 2015-12-21 21:18 ` Junio C Hamano 2015-12-22 10:57 ` Duy Nguyen 3 siblings, 1 reply; 39+ messages in thread From: Junio C Hamano @ 2015-12-21 21:18 UTC (permalink / raw) To: Nguyễn Thái Ngọc Duy; +Cc: git, sbeller, asottile Thanks. I wiggled these three on top of the "Revert the earlier one"; while I think the result is correct, I'd appreciate if you can double check the result when I push the topic out later today. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-21 21:18 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Junio C Hamano @ 2015-12-22 10:57 ` Duy Nguyen 2015-12-22 11:53 ` Duy Nguyen 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-12-22 10:57 UTC (permalink / raw) To: Junio C Hamano; +Cc: Git Mailing List, Stefan Beller, Anthony Sottile On Tue, Dec 22, 2015 at 4:18 AM, Junio C Hamano <gitster@pobox.com> wrote: > Thanks. I wiggled these three on top of the "Revert the earlier > one"; while I think the result is correct, I'd appreciate if you can > double check the result when I push the topic out later today. Looks good. "prove" passed too by the way. -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-22 10:57 ` Duy Nguyen @ 2015-12-22 11:53 ` Duy Nguyen 2015-12-22 18:13 ` Junio C Hamano 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-12-22 11:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: Git Mailing List, Stefan Beller, Anthony Sottile On Tue, Dec 22, 2015 at 5:57 PM, Duy Nguyen <pclouds@gmail.com> wrote: > On Tue, Dec 22, 2015 at 4:18 AM, Junio C Hamano <gitster@pobox.com> wrote: >> Thanks. I wiggled these three on top of the "Revert the earlier >> one"; while I think the result is correct, I'd appreciate if you can >> double check the result when I push the topic out later today. > > Looks good. "prove" passed too by the way. Another by the way, this "forcing aliases as external commands" now shows something like "error: git-log died of signal 13" when the pager exits early, for an alias like "l1 = log --oneline". It's probably not a regression because other external git commands with pager should show the same message. But I haven't checked thoroughly yet. -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-22 11:53 ` Duy Nguyen @ 2015-12-22 18:13 ` Junio C Hamano 2015-12-23 9:37 ` Jeff King 0 siblings, 1 reply; 39+ messages in thread From: Junio C Hamano @ 2015-12-22 18:13 UTC (permalink / raw) To: Duy Nguyen; +Cc: Git Mailing List, Stefan Beller, Anthony Sottile Duy Nguyen <pclouds@gmail.com> writes: > On Tue, Dec 22, 2015 at 5:57 PM, Duy Nguyen <pclouds@gmail.com> wrote: >> On Tue, Dec 22, 2015 at 4:18 AM, Junio C Hamano <gitster@pobox.com> wrote: >>> Thanks. I wiggled these three on top of the "Revert the earlier >>> one"; while I think the result is correct, I'd appreciate if you can >>> double check the result when I push the topic out later today. >> >> Looks good. "prove" passed too by the way. > > Another by the way, this "forcing aliases as external commands" now > shows something like "error: git-log died of signal 13" when the pager > exits early, for an alias like "l1 = log --oneline". ... and we do not show that when we directly call "git log" is...? We do signal this with non-zero exit status like so: $ GIT_PAGER=true git log --oneline ; echo $? 141 and it is not surprising that the one that is catching the exit status of what was spawned and reporting "signal 13". ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-22 18:13 ` Junio C Hamano @ 2015-12-23 9:37 ` Jeff King 2015-12-23 10:20 ` Duy Nguyen ` (2 more replies) 0 siblings, 3 replies; 39+ messages in thread From: Jeff King @ 2015-12-23 9:37 UTC (permalink / raw) To: Junio C Hamano Cc: Duy Nguyen, Git Mailing List, Stefan Beller, Anthony Sottile On Tue, Dec 22, 2015 at 10:13:03AM -0800, Junio C Hamano wrote: > > Another by the way, this "forcing aliases as external commands" now > > shows something like "error: git-log died of signal 13" when the pager > > exits early, for an alias like "l1 = log --oneline". > > ... and we do not show that when we directly call "git log" is...? > > We do signal this with non-zero exit status like so: > > $ GIT_PAGER=true git log --oneline ; echo $? > 141 > > and it is not surprising that the one that is catching the exit > status of what was spawned and reporting "signal 13". This sounded very familiar. Apparently I've been running with the patch below for almost 3 years and never got around to re-examining it. The original discussion is in: http://thread.gmane.org/gmane.comp.version-control.git/212630 Having skimmed through the arguments there, and given that we applied the patch from the middle of the thread, I think this is a good change. -- >8 -- Date: Fri, 4 Jan 2013 07:19:35 -0500 Subject: [PATCH] avoid SIGPIPE warnings for aliases When git executes an alias that specifies an external command, it will complain if the alias dies due to a signal. This is usually a good thing, as signal deaths are unexpected. However, SIGPIPE is not unexpected for many commands which produce a lot of output; it is intended that the user closing the pager would kill them them via SIGPIPE. As a result, the user might see annoying messages in a scenario like this: $ cat ~/.gitconfig [alias] lgbase = log --some-options lg = !git lgbase --more-options lg2 = !git lgbase --other-options $ git lg -p [user hits 'q' to exit pager] error: git lgbase --more-options died of signal 13 fatal: While expanding alias 'lg': 'git lgbase --more-options': Success Many users won't see this, because we execute the external command with the shell, and a POSIX shell will silently rewrite the signal-death exit code into 128+signal, and we will treat it like a normal exit code. However, this does not always happen: 1. If the sub-command does not have shell metacharacters, we will skip the shell and exec it directly, getting the signal code. 2. Some shells do not do this rewriting; for example, setting SHELL_PATH set to zsh will reveal this problem. This patch squelches the message, and lets git exit silently (with the same exit code that a shell would use in case of a signal). The first line of the message comes from run-command's wait_or_whine. To silence that message, we remain quiet anytime we see SIGPIPE. The second line comes from handle_alias itself. It calls die_errno whenever run_command returns a negative value. However, only -1 indicates a syscall error where errno has something useful (note that it says the useless "success" above). Instead, we treat negative returns from run_command (except for -1) as a normal code to be passed to exit. Signed-off-by: Jeff King <peff@peff.net> --- git.c | 2 +- run-command.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/git.c b/git.c index 6ed824c..34a18a3 100644 --- a/git.c +++ b/git.c @@ -252,7 +252,7 @@ static int handle_alias(int *argcp, const char ***argv) alias_argv[argc] = NULL; ret = run_command_v_opt(alias_argv, RUN_USING_SHELL); - if (ret >= 0) /* normal exit */ + if (ret != -1) /* normal exit */ exit(ret); die_errno("While expanding alias '%s': '%s'", diff --git a/run-command.c b/run-command.c index 13fa452..694a6ff 100644 --- a/run-command.c +++ b/run-command.c @@ -245,7 +245,7 @@ static int wait_or_whine(pid_t pid, const char *argv0, int in_signal) error("waitpid is confused (%s)", argv0); } else if (WIFSIGNALED(status)) { code = WTERMSIG(status); - if (code != SIGINT && code != SIGQUIT) + if (code != SIGINT && code != SIGQUIT && code != SIGPIPE) error("%s died of signal %d", argv0, code); /* * This return value is chosen so that code & 0xff -- 2.7.0.rc2.368.g1cbb535 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-23 9:37 ` Jeff King @ 2015-12-23 10:20 ` Duy Nguyen 2015-12-23 16:17 ` Eric Sunshine 2015-12-23 20:37 ` Johannes Sixt 2 siblings, 0 replies; 39+ messages in thread From: Duy Nguyen @ 2015-12-23 10:20 UTC (permalink / raw) To: Jeff King Cc: Junio C Hamano, Git Mailing List, Stefan Beller, Anthony Sottile On Wed, Dec 23, 2015 at 4:37 PM, Jeff King <peff@peff.net> wrote: > On Tue, Dec 22, 2015 at 10:13:03AM -0800, Junio C Hamano wrote: > >> > Another by the way, this "forcing aliases as external commands" now >> > shows something like "error: git-log died of signal 13" when the pager >> > exits early, for an alias like "l1 = log --oneline". >> >> ... and we do not show that when we directly call "git log" is...? >> >> We do signal this with non-zero exit status like so: >> >> $ GIT_PAGER=true git log --oneline ; echo $? >> 141 >> >> and it is not surprising that the one that is catching the exit >> status of what was spawned and reporting "signal 13". > > This sounded very familiar. Apparently I've been running with the patch > below for almost 3 years and never got around to re-examining it. > > The original discussion is in: > > http://thread.gmane.org/gmane.comp.version-control.git/212630 > > Having skimmed through the arguments there, and given that we applied > the patch from the middle of the thread, I think this is a good change. Yep. The new thing here is the "died of" message now also comes from execv_dashed_external() for non-external aliases, so it can show up a lot more often. I wasn't sure if excluding SIGPIPE in wait_and_whine was safe. But I _guess_ it is, based on your having no problem with the patch for a long time and the past discussion. > > -- >8 -- > Date: Fri, 4 Jan 2013 07:19:35 -0500 > Subject: [PATCH] avoid SIGPIPE warnings for aliases > > When git executes an alias that specifies an external > command, it will complain if the alias dies due to a signal. > This is usually a good thing, as signal deaths are > unexpected. However, SIGPIPE is not unexpected for many > commands which produce a lot of output; it is intended that > the user closing the pager would kill them them via SIGPIPE. > > As a result, the user might see annoying messages in a > scenario like this: > > $ cat ~/.gitconfig > [alias] > lgbase = log --some-options > lg = !git lgbase --more-options > lg2 = !git lgbase --other-options > > $ git lg -p > [user hits 'q' to exit pager] > error: git lgbase --more-options died of signal 13 > fatal: While expanding alias 'lg': 'git lgbase --more-options': Success > > Many users won't see this, because we execute the external > command with the shell, and a POSIX shell will silently > rewrite the signal-death exit code into 128+signal, and we > will treat it like a normal exit code. However, this does > not always happen: > > 1. If the sub-command does not have shell metacharacters, > we will skip the shell and exec it directly, getting > the signal code. > > 2. Some shells do not do this rewriting; for example, > setting SHELL_PATH set to zsh will reveal this problem. > > This patch squelches the message, and lets git exit silently > (with the same exit code that a shell would use in case of a > signal). > > The first line of the message comes from run-command's > wait_or_whine. To silence that message, we remain quiet > anytime we see SIGPIPE. > > The second line comes from handle_alias itself. It calls > die_errno whenever run_command returns a negative value. > However, only -1 indicates a syscall error where errno has > something useful (note that it says the useless "success" > above). Instead, we treat negative returns from run_command > (except for -1) as a normal code to be passed to exit. > > Signed-off-by: Jeff King <peff@peff.net> > --- > git.c | 2 +- > run-command.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/git.c b/git.c > index 6ed824c..34a18a3 100644 > --- a/git.c > +++ b/git.c > @@ -252,7 +252,7 @@ static int handle_alias(int *argcp, const char ***argv) > alias_argv[argc] = NULL; > > ret = run_command_v_opt(alias_argv, RUN_USING_SHELL); > - if (ret >= 0) /* normal exit */ > + if (ret != -1) /* normal exit */ > exit(ret); > > die_errno("While expanding alias '%s': '%s'", > diff --git a/run-command.c b/run-command.c > index 13fa452..694a6ff 100644 > --- a/run-command.c > +++ b/run-command.c > @@ -245,7 +245,7 @@ static int wait_or_whine(pid_t pid, const char *argv0, int in_signal) > error("waitpid is confused (%s)", argv0); > } else if (WIFSIGNALED(status)) { > code = WTERMSIG(status); > - if (code != SIGINT && code != SIGQUIT) > + if (code != SIGINT && code != SIGQUIT && code != SIGPIPE) > error("%s died of signal %d", argv0, code); > /* > * This return value is chosen so that code & 0xff > -- > 2.7.0.rc2.368.g1cbb535 > -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-23 9:37 ` Jeff King 2015-12-23 10:20 ` Duy Nguyen @ 2015-12-23 16:17 ` Eric Sunshine 2015-12-23 20:37 ` Johannes Sixt 2 siblings, 0 replies; 39+ messages in thread From: Eric Sunshine @ 2015-12-23 16:17 UTC (permalink / raw) To: Jeff King Cc: Junio C Hamano, Duy Nguyen, Git Mailing List, Stefan Beller, Anthony Sottile On Wed, Dec 23, 2015 at 4:37 AM, Jeff King <peff@peff.net> wrote: > Subject: [PATCH] avoid SIGPIPE warnings for aliases > > When git executes an alias that specifies an external > command, it will complain if the alias dies due to a signal. > This is usually a good thing, as signal deaths are > unexpected. However, SIGPIPE is not unexpected for many > commands which produce a lot of output; it is intended that > the user closing the pager would kill them them via SIGPIPE. s/them them/them/ > As a result, the user might see annoying messages in a > scenario like this: > > $ cat ~/.gitconfig > [alias] > lgbase = log --some-options > lg = !git lgbase --more-options > lg2 = !git lgbase --other-options > > $ git lg -p > [user hits 'q' to exit pager] > error: git lgbase --more-options died of signal 13 > fatal: While expanding alias 'lg': 'git lgbase --more-options': Success > > Many users won't see this, because we execute the external > command with the shell, and a POSIX shell will silently > rewrite the signal-death exit code into 128+signal, and we > will treat it like a normal exit code. However, this does > not always happen: > > 1. If the sub-command does not have shell metacharacters, > we will skip the shell and exec it directly, getting > the signal code. > > 2. Some shells do not do this rewriting; for example, > setting SHELL_PATH set to zsh will reveal this problem. > > This patch squelches the message, and lets git exit silently > (with the same exit code that a shell would use in case of a > signal). > > The first line of the message comes from run-command's > wait_or_whine. To silence that message, we remain quiet > anytime we see SIGPIPE. > > The second line comes from handle_alias itself. It calls > die_errno whenever run_command returns a negative value. > However, only -1 indicates a syscall error where errno has > something useful (note that it says the useless "success" > above). Instead, we treat negative returns from run_command > (except for -1) as a normal code to be passed to exit. > > Signed-off-by: Jeff King <peff@peff.net> ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-23 9:37 ` Jeff King 2015-12-23 10:20 ` Duy Nguyen 2015-12-23 16:17 ` Eric Sunshine @ 2015-12-23 20:37 ` Johannes Sixt 2015-12-23 21:31 ` Jeff King 2 siblings, 1 reply; 39+ messages in thread From: Johannes Sixt @ 2015-12-23 20:37 UTC (permalink / raw) To: Jeff King, Junio C Hamano Cc: Duy Nguyen, Git Mailing List, Stefan Beller, Anthony Sottile Am 23.12.2015 um 10:37 schrieb Jeff King: > The second line comes from handle_alias itself. It calls > die_errno whenever run_command returns a negative value. > However, only -1 indicates a syscall error where errno has > something useful (note that it says the useless "success" > above). Instead, we treat negative returns from run_command > (except for -1) as a normal code to be passed to exit. > > Signed-off-by: Jeff King <peff@peff.net> > --- > git.c | 2 +- > run-command.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/git.c b/git.c > index 6ed824c..34a18a3 100644 > --- a/git.c > +++ b/git.c > @@ -252,7 +252,7 @@ static int handle_alias(int *argcp, const char ***argv) > alias_argv[argc] = NULL; > > ret = run_command_v_opt(alias_argv, RUN_USING_SHELL); > - if (ret >= 0) /* normal exit */ > + if (ret != -1) /* normal exit */ Why does this make a difference? We only ever return -1, zero, or a positive value from run_command/finish_command/wait_or_whine, as far as I can see. > exit(ret); > > die_errno("While expanding alias '%s': '%s'", -- Hannes ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-23 20:37 ` Johannes Sixt @ 2015-12-23 21:31 ` Jeff King 2015-12-24 9:35 ` Duy Nguyen 0 siblings, 1 reply; 39+ messages in thread From: Jeff King @ 2015-12-23 21:31 UTC (permalink / raw) To: Johannes Sixt Cc: Junio C Hamano, Duy Nguyen, Git Mailing List, Stefan Beller, Anthony Sottile On Wed, Dec 23, 2015 at 09:37:04PM +0100, Johannes Sixt wrote: > >--- a/git.c > >+++ b/git.c > >@@ -252,7 +252,7 @@ static int handle_alias(int *argcp, const char ***argv) > > alias_argv[argc] = NULL; > > > > ret = run_command_v_opt(alias_argv, RUN_USING_SHELL); > >- if (ret >= 0) /* normal exit */ > >+ if (ret != -1) /* normal exit */ > > Why does this make a difference? We only ever return -1, zero, or a positive > value from run_command/finish_command/wait_or_whine, as far as I can see. Yeah, you're right. This bit predates 709ca73 (run-command: encode signal death as a positive integer, 2013-01-05), which came out of the same discussion. So I'd agree this hunk can simply be dropped. That leaves the ignoring of SIGPIPE in wait_or_whine. I started to rewrite the commit message to drop the first hunk, but I found I couldn't replicate the problem in the second either! Doing: GIT_PAGER=false git -c alias.foo='!git log -p' foo doesn't trigger it. We run the alias through a shell, so we see only the munged "141" value from the shell's exit code. Something like: GIT_PAGER=false git -p -c alias.foo='!yes' foo does generate the error message. But we've redirected stderr into the pager at that point, so by definition it can never be shown. So I think we would need a case where: - the outer git doesn't run the pager that dies; instead the pager is run inside the alias. But... - inside the alias cannot be a shell pipeline, since "foo | less" will report the exit code of "less", not "foo" (we make special arrangements in git to propagate the exit code of "foo"). So it pretty much has to be a git invocation inside the alias. But... - The git invocation will convert signal death in the sub-process into 141, like a shell would. So I'm not sure if this is triggerable at all with an alias. I did manage to trigger it with an external command, like: $ cat $(which git-yes) #!/bin/sh # This _has_ to be exec, otherwise the shell converts SIGPIPE death # into 141. exec yes and then if you run your _own_ pager, like this: $ git yes | false error: git-yes died of signal 13 you see it. But if git starts the pager, you don't: $ GIT_PAGER=false git -p yes Because the stderr of the outer git process is going to the same dead pipe. So my takeaways are: 1. Complaining about signal death in general is going to be flaky, because it's so easy for shells or git to rewrite the exit code and not trigger WIFSIGNALED() in the first place. 2. I doubt anybody is actually seeing this in practice anymore. But maybe I am misunderstanding something in Duy's series that changes this. -Peff ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-23 21:31 ` Jeff King @ 2015-12-24 9:35 ` Duy Nguyen 2015-12-29 8:12 ` Jeff King 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-12-24 9:35 UTC (permalink / raw) To: Jeff King Cc: Johannes Sixt, Junio C Hamano, Git Mailing List, Stefan Beller, Anthony Sottile On Thu, Dec 24, 2015 at 4:31 AM, Jeff King <peff@peff.net> wrote: > 2. I doubt anybody is actually seeing this in practice anymore. But > maybe I am misunderstanding something in Duy's series that changes > this. There are two parts in your patch, one (that you two seemed to focus on) about return code with "!" aliases. Another, suppressing SIGPIPE, affects more than "!" aliases. In my case it's execv_dashed_external(). Non-"!" aliases are now forced to use that function. This is the output with 'pu'. Notice git-log is executed separately > ~/w/git $ GIT_TRACE=2 PAGER=true ./git --exec-path=. l 16:28:19.167040 git.c:567 trace: exec: 'git-l' 16:28:19.167088 run-command.c:345 trace: run_command: 'git-l' 16:28:19.168599 git.c:286 trace: alias expansion: l => 'log' '--stat' 16:28:19.168633 git.c:567 trace: exec: 'git-log' '--stat' 16:28:19.168649 run-command.c:345 trace: run_command: 'git-log' '--stat' 16:28:19.170420 git.c:350 trace: built-in: git 'log' '--stat' 16:28:19.210074 run-command.c:345 trace: run_command: 'true' 16:28:19.210382 run-command.c:204 trace: exec: 'true' error: git-log died of signal 13 With your patch on top, "git-log died of.." goes away. And this is with 'master', where the builtin version of git-log is used > ~/w/git $ GIT_TRACE=2 PAGER=true ./git --exec-path=. l 16:29:17.546382 git.c:561 trace: exec: 'git-l' 16:29:17.546428 run-command.c:343 trace: run_command: 'git-l' 16:29:17.547485 git.c:282 trace: alias expansion: l => 'log' '--stat' 16:29:17.548482 git.c:348 trace: built-in: git 'log' '--stat' 16:29:17.586457 run-command.c:343 trace: run_command: 'true' 16:29:17.586770 run-command.c:202 trace: exec: 'true' So, in practice, people will see "died of signal 13" a lot more often if my series is merged and released (I assume that people often use aliases for paged commands like git-log, git-diff...) -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-24 9:35 ` Duy Nguyen @ 2015-12-29 8:12 ` Jeff King 2015-12-29 21:34 ` Junio C Hamano 0 siblings, 1 reply; 39+ messages in thread From: Jeff King @ 2015-12-29 8:12 UTC (permalink / raw) To: Duy Nguyen Cc: Johannes Sixt, Junio C Hamano, Git Mailing List, Stefan Beller, Anthony Sottile On Thu, Dec 24, 2015 at 04:35:33PM +0700, Duy Nguyen wrote: > On Thu, Dec 24, 2015 at 4:31 AM, Jeff King <peff@peff.net> wrote: > > 2. I doubt anybody is actually seeing this in practice anymore. But > > maybe I am misunderstanding something in Duy's series that changes > > this. > > There are two parts in your patch, one (that you two seemed to focus > on) about return code with "!" aliases. Another, suppressing SIGPIPE, > affects more than "!" aliases. Sorry if I was confusing; most of the examples in my previous message are about the SIGPIPE thing. I was having trouble triggering the message in practice, even for externals (because the error message goes to the pager, too!). > In my case it's execv_dashed_external(). Non-"!" aliases are now > forced to use that function. Thanks, this is the part I was missing. The outer git wrapper doesn't start the pager, so its stderr still gets seen by the user. But the _inner_ git-log does start the pager, and then dies of SIGPIPE. So yeah, I think we want something like this on top of nd/clear-gitenv-upon-use-of-alias. -- >8 -- Subject: [PATCH] run-command: don't warn on SIGPIPE deaths When git executes a sub-command, we print a warning if the command dies due to a signal, but make an exception for "uninteresting" cases like SIGINT and SIGQUIT (since the user presumably just hit ^C). We should make a similar exception for SIGPIPE, because it's an expected and uninteresting return in most cases; it generally means the user quit the pager before git had finished generating all output. This used to be very hard to trigger in practice, because: 1. We only complain if we see a real SIGPIPE death, not the shell-induced 141 exit code. This means that anything we run via the shell does not trigger the warning, which includes most non-trivial aliases. 2. The common case for SIGPIPE is the user quitting the pager before git has finished generating all output. But if the user triggers a pager with "-p", we redirect the git wrapper's stderr to that pager, too. Since the pager is dead, it means that the message goes nowhere. 3. You can see it if you run your own pager, like "git foo | head". But that only happens if "foo" is a non-builtin (so it doesn't work with "log", for example). However, it may become more common after 86d26f2, which teaches alias to re-exec builtins rather than running them in the same process. This case doesn't trigger (1), as we don't need a shell to run a git command. It doesn't trigger (2), because the pager is not started by the original git, but by the inner re-exec of git. And it doesn't trigger (3), because builtins are treated more like non-builtins in this case. Given how flaky this message already is (e.g., you cannot even know whether you will see it, as git optimizes out some shell invocations behind the scenes based on the contents of the command!), and that it is unlikely to ever provide useful information, let's suppress it for all cases of SIGPIPE. Signed-off-by: Jeff King <peff@peff.net> --- run-command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-command.c b/run-command.c index 13fa452..694a6ff 100644 --- a/run-command.c +++ b/run-command.c @@ -245,7 +245,7 @@ static int wait_or_whine(pid_t pid, const char *argv0, int in_signal) error("waitpid is confused (%s)", argv0); } else if (WIFSIGNALED(status)) { code = WTERMSIG(status); - if (code != SIGINT && code != SIGQUIT) + if (code != SIGINT && code != SIGQUIT && code != SIGPIPE) error("%s died of signal %d", argv0, code); /* * This return value is chosen so that code & 0xff -- 2.7.0.rc3.367.g09631da ^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias 2015-12-29 8:12 ` Jeff King @ 2015-12-29 21:34 ` Junio C Hamano 0 siblings, 0 replies; 39+ messages in thread From: Junio C Hamano @ 2015-12-29 21:34 UTC (permalink / raw) To: Jeff King Cc: Duy Nguyen, Johannes Sixt, Git Mailing List, Stefan Beller, Anthony Sottile Jeff King <peff@peff.net> writes: > The outer git wrapper doesn't start the pager, so its stderr still gets > seen by the user. But the _inner_ git-log does start the pager, and then > dies of SIGPIPE. > > So yeah, I think we want something like this on top of > nd/clear-gitenv-upon-use-of-alias. That makes sense to me. > -- >8 -- > Subject: [PATCH] run-command: don't warn on SIGPIPE deaths > > When git executes a sub-command, we print a warning if the > command dies due to a signal, but make an exception for > "uninteresting" cases like SIGINT and SIGQUIT (since the > user presumably just hit ^C). > > We should make a similar exception for SIGPIPE, because it's > an expected and uninteresting return in most cases; it > generally means the user quit the pager before git had > finished generating all output. This used to be very hard > to trigger in practice, because: > > 1. We only complain if we see a real SIGPIPE death, not > the shell-induced 141 exit code. This means that > anything we run via the shell does not trigger the > warning, which includes most non-trivial aliases. > > 2. The common case for SIGPIPE is the user quitting the > pager before git has finished generating all output. > But if the user triggers a pager with "-p", we redirect > the git wrapper's stderr to that pager, too. Since the > pager is dead, it means that the message goes nowhere. > > 3. You can see it if you run your own pager, like > "git foo | head". But that only happens if "foo" is a > non-builtin (so it doesn't work with "log", for > example). > > However, it may become more common after 86d26f2, which > teaches alias to re-exec builtins rather than running them > in the same process. This case doesn't trigger (1), as we > don't need a shell to run a git command. It doesn't trigger > (2), because the pager is not started by the original git, > but by the inner re-exec of git. And it doesn't trigger (3), > because builtins are treated more like non-builtins in this > case. > > Given how flaky this message already is (e.g., you cannot > even know whether you will see it, as git optimizes out some > shell invocations behind the scenes based on the contents of > the command!), and that it is unlikely to ever provide > useful information, let's suppress it for all cases of > SIGPIPE. > > Signed-off-by: Jeff King <peff@peff.net> > --- > run-command.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/run-command.c b/run-command.c > index 13fa452..694a6ff 100644 > --- a/run-command.c > +++ b/run-command.c > @@ -245,7 +245,7 @@ static int wait_or_whine(pid_t pid, const char *argv0, int in_signal) > error("waitpid is confused (%s)", argv0); > } else if (WIFSIGNALED(status)) { > code = WTERMSIG(status); > - if (code != SIGINT && code != SIGQUIT) > + if (code != SIGINT && code != SIGQUIT && code != SIGPIPE) > error("%s died of signal %d", argv0, code); > /* > * This return value is chosen so that code & 0xff ^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" 2015-12-02 17:09 ` Junio C Hamano 2015-12-03 18:17 ` [PATCH 1/2] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy @ 2015-12-21 10:22 ` Nguyễn Thái Ngọc Duy 2015-12-21 17:28 ` Junio C Hamano 1 sibling, 1 reply; 39+ messages in thread From: Nguyễn Thái Ngọc Duy @ 2015-12-21 10:22 UTC (permalink / raw) To: Junio C Hamano; +Cc: git, Nguyễn Thái Ngọc Duy This commit has caused three regression reports so far. All of them are about spawning git subprocesses, where the new presence of GIT_WORK_TREE either changes command behaviour (git-init or git-clone), or how repo/worktree is detected (from aliases), with or without $GIT_DIR. The original bug will be re-fixed another way. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> --- On Thu, Dec 3, 2015 at 12:09 AM, Junio C Hamano <gitster@pobox.com> wrote: > OK, when/if you decide that our first step should be a revert of > d95138e please send in a patch to do so with a brief write-up of a > follow-up plan. Three reports to me are enough. And I obviously could not push the fix out fast enough. So if you want to revert it, here's the patch on maint. environment.c | 2 -- t/t0002-gitfile.sh | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/environment.c b/environment.c index 23a38e4..f1a2a49 100644 --- a/environment.c +++ b/environment.c @@ -238,8 +238,6 @@ void set_git_work_tree(const char *new_work_tree) } git_work_tree_initialized = 1; work_tree = xstrdup(real_path(new_work_tree)); - if (setenv(GIT_WORK_TREE_ENVIRONMENT, work_tree, 1)) - die("could not set GIT_WORK_TREE to '%s'", work_tree); } const char *get_git_work_tree(void) diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index 9670e8c..3afe012 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -99,7 +99,7 @@ test_expect_success 'check rev-list' ' test "$SHA" = "$(git rev-list HEAD)" ' -test_expect_success 'setup_git_dir twice in subdir' ' +test_expect_failure 'setup_git_dir twice in subdir' ' git init sgd && ( cd sgd && -- 2.3.0.rc1.137.g477eb31 ^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" 2015-12-21 10:22 ` [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" Nguyễn Thái Ngọc Duy @ 2015-12-21 17:28 ` Junio C Hamano 2015-12-21 18:31 ` Junio C Hamano 0 siblings, 1 reply; 39+ messages in thread From: Junio C Hamano @ 2015-12-21 17:28 UTC (permalink / raw) To: Nguyễn Thái Ngọc Duy; +Cc: git Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: > This commit has caused three regression reports so far. All of them are > about spawning git subprocesses, where the new presence of GIT_WORK_TREE > either changes command behaviour (git-init or git-clone), or how > repo/worktree is detected (from aliases), with or without $GIT_DIR. > The original bug will be re-fixed another way. > > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> > --- > On Thu, Dec 3, 2015 at 12:09 AM, Junio C Hamano <gitster@pobox.com> wrote: > > OK, when/if you decide that our first step should be a revert of > > d95138e please send in a patch to do so with a brief write-up of a > > follow-up plan. > > Three reports to me are enough. And I obviously could not push the > fix out fast enough. So if you want to revert it, here's the patch on > maint. The timing of this is a bit unfortunate, as d95138e is a regression since v2.5.1 throughout v2.6 series. I'll push this out on maint and onwards for now. I do not think we added new things that rely on the post-d95138e "broken" behaviour in-tree, but this reversion might introduce another unexpected regression X-<. We'll see. Thanks. > > environment.c | 2 -- > t/t0002-gitfile.sh | 2 +- > 2 files changed, 1 insertion(+), 3 deletions(-) > > diff --git a/environment.c b/environment.c > index 23a38e4..f1a2a49 100644 > --- a/environment.c > +++ b/environment.c > @@ -238,8 +238,6 @@ void set_git_work_tree(const char *new_work_tree) > } > git_work_tree_initialized = 1; > work_tree = xstrdup(real_path(new_work_tree)); > - if (setenv(GIT_WORK_TREE_ENVIRONMENT, work_tree, 1)) > - die("could not set GIT_WORK_TREE to '%s'", work_tree); > } > > const char *get_git_work_tree(void) > diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh > index 9670e8c..3afe012 100755 > --- a/t/t0002-gitfile.sh > +++ b/t/t0002-gitfile.sh > @@ -99,7 +99,7 @@ test_expect_success 'check rev-list' ' > test "$SHA" = "$(git rev-list HEAD)" > ' > > -test_expect_success 'setup_git_dir twice in subdir' ' > +test_expect_failure 'setup_git_dir twice in subdir' ' > git init sgd && > ( > cd sgd && ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" 2015-12-21 17:28 ` Junio C Hamano @ 2015-12-21 18:31 ` Junio C Hamano 2015-12-22 1:06 ` Duy Nguyen 0 siblings, 1 reply; 39+ messages in thread From: Junio C Hamano @ 2015-12-21 18:31 UTC (permalink / raw) To: Nguyễn Thái Ngọc Duy; +Cc: git Junio C Hamano <gitster@pobox.com> writes: > Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: > >> This commit has caused three regression reports so far. All of them are >> about spawning git subprocesses, where the new presence of GIT_WORK_TREE >> either changes command behaviour (git-init or git-clone), or how >> repo/worktree is detected (from aliases), with or without $GIT_DIR. >> The original bug will be re-fixed another way. >> >> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> >> --- >> On Thu, Dec 3, 2015 at 12:09 AM, Junio C Hamano <gitster@pobox.com> wrote: >> > OK, when/if you decide that our first step should be a revert of >> > d95138e please send in a patch to do so with a brief write-up of a >> > follow-up plan. >> >> Three reports to me are enough. And I obviously could not push the >> fix out fast enough. So if you want to revert it, here's the patch on >> maint. Also, can you reference these three reports for future reference? Thanks. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" 2015-12-21 18:31 ` Junio C Hamano @ 2015-12-22 1:06 ` Duy Nguyen 2015-12-22 21:50 ` Junio C Hamano 0 siblings, 1 reply; 39+ messages in thread From: Duy Nguyen @ 2015-12-22 1:06 UTC (permalink / raw) To: Junio C Hamano; +Cc: Git Mailing List On Tue, Dec 22, 2015 at 1:31 AM, Junio C Hamano <gitster@pobox.com> wrote: > Junio C Hamano <gitster@pobox.com> writes: > >> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: >> >>> This commit has caused three regression reports so far. All of them are >>> about spawning git subprocesses, where the new presence of GIT_WORK_TREE >>> either changes command behaviour (git-init or git-clone), or how >>> repo/worktree is detected (from aliases), with or without $GIT_DIR. >>> The original bug will be re-fixed another way. >>> >>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> >>> --- >>> On Thu, Dec 3, 2015 at 12:09 AM, Junio C Hamano <gitster@pobox.com> wrote: >>> > OK, when/if you decide that our first step should be a revert of >>> > d95138e please send in a patch to do so with a brief write-up of a >>> > follow-up plan. >>> >>> Three reports to me are enough. And I obviously could not push the >>> fix out fast enough. So if you want to revert it, here's the patch on >>> maint. > > Also, can you reference these three reports for future reference? http://article.gmane.org/gmane.comp.version-control.git/281608 http://article.gmane.org/gmane.comp.version-control.git/281979 http://article.gmane.org/gmane.comp.version-control.git/282691 The last one is not confirmed by the reporter yet. But I'm pretty sure i'll trigger the special case "when GIT_WORK_TREE is set but GIT_DIR is not" in setup code -- Duy ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" 2015-12-22 1:06 ` Duy Nguyen @ 2015-12-22 21:50 ` Junio C Hamano 0 siblings, 0 replies; 39+ messages in thread From: Junio C Hamano @ 2015-12-22 21:50 UTC (permalink / raw) To: Duy Nguyen; +Cc: Git Mailing List Duy Nguyen <pclouds@gmail.com> writes: > On Tue, Dec 22, 2015 at 1:31 AM, Junio C Hamano <gitster@pobox.com> wrote: >> Junio C Hamano <gitster@pobox.com> writes: >> >>> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes: >>> >>>> This commit has caused three regression reports so far. All of them are >>>> about spawning git subprocesses, where the new presence of GIT_WORK_TREE >>>> either changes command behaviour (git-init or git-clone), or how >>>> repo/worktree is detected (from aliases), with or without $GIT_DIR. >>>> The original bug will be re-fixed another way. >>>> >>>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> >>>> --- >>>> On Thu, Dec 3, 2015 at 12:09 AM, Junio C Hamano <gitster@pobox.com> wrote: >>>> > OK, when/if you decide that our first step should be a revert of >>>> > d95138e please send in a patch to do so with a brief write-up of a >>>> > follow-up plan. >>>> >>>> Three reports to me are enough. And I obviously could not push the >>>> fix out fast enough. So if you want to revert it, here's the patch on >>>> maint. >> >> Also, can you reference these three reports for future reference? > > http://article.gmane.org/gmane.comp.version-control.git/281608 > http://article.gmane.org/gmane.comp.version-control.git/281979 > http://article.gmane.org/gmane.comp.version-control.git/282691 > > The last one is not confirmed by the reporter yet. But I'm pretty sure > i'll trigger the special case "when GIT_WORK_TREE is set but GIT_DIR > is not" in setup code Thanks, I'll leave these breadcrumbs in the log message for future reference. I think the last sentence of the original commit is telling how this bug came about. "It does not harm if $GIT_WORK_TREE is set while $GIT_DIR is not." forgets to consider the possibility that scripts may be relying on the "Go to the top of the working tree and setting GIT_DIR would give you a reasonable environment". That is true if GIT_WORK_TREE is not set, and these scripts weren't getting the environment exported [*1*]. These scripts now have to unset GIT_WORK_TREE themselves (or set it to their $cwd if they are indeed at the top), just in case the process that calls them exports it X-<. Thanks. [Footnote] *1* If the end user has GIT_WORK_TREE in the environment, even if Git stops exporting it by reverting d95138e, such a script may break. So in that sense, d95138e did not quite change the rule of the game for these scripts, but made it more obvious when these scripts were written sloppily. ^ permalink raw reply [flat|nested] 39+ messages in thread
end of thread, other threads:[~2015-12-29 21:34 UTC | newest] Thread overview: 39+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <CA+dzEB=2LJXiLSTqyLw8AeHNwdQicwvEiMg=hVEX0-_s1bySpA@mail.gmail.com> 2015-11-24 2:22 ` Fwd: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6) Anthony Sottile 2015-11-24 17:57 ` Stefan Beller 2015-11-25 20:13 ` Duy Nguyen 2015-11-30 19:01 ` Duy Nguyen 2015-11-30 20:16 ` Junio C Hamano 2015-12-01 17:59 ` Duy Nguyen 2015-12-02 17:09 ` Junio C Hamano 2015-12-03 18:17 ` [PATCH 1/2] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy 2015-12-03 18:17 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy 2015-12-04 20:35 ` Junio C Hamano 2015-12-05 5:48 ` Duy Nguyen 2015-12-05 15:32 ` [PATCH 3/2] git.c: make sure we do not leak GIT_* to alias scripts Nguyễn Thái Ngọc Duy 2015-12-07 18:54 ` Junio C Hamano 2015-12-08 16:55 ` Duy Nguyen 2015-12-08 17:20 ` Jeff King 2015-12-08 23:55 ` Junio C Hamano 2015-12-05 19:12 ` [PATCH 2/2] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Duy Nguyen 2015-12-07 18:33 ` Junio C Hamano 2015-12-20 7:50 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 1/3] git.c: make it clear save_env() is for alias handling only Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 2/3] setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when Nguyễn Thái Ngọc Duy 2015-12-20 7:50 ` [PATCH v2 3/3] git.c: make sure we do not leak GIT_* to alias scripts Nguyễn Thái Ngọc Duy 2015-12-21 21:18 ` [PATCH v2 0/3] nd/clear-gitenv-upon-use-of-alias Junio C Hamano 2015-12-22 10:57 ` Duy Nguyen 2015-12-22 11:53 ` Duy Nguyen 2015-12-22 18:13 ` Junio C Hamano 2015-12-23 9:37 ` Jeff King 2015-12-23 10:20 ` Duy Nguyen 2015-12-23 16:17 ` Eric Sunshine 2015-12-23 20:37 ` Johannes Sixt 2015-12-23 21:31 ` Jeff King 2015-12-24 9:35 ` Duy Nguyen 2015-12-29 8:12 ` Jeff King 2015-12-29 21:34 ` Junio C Hamano 2015-12-21 10:22 ` [PATCH] Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR" Nguyễn Thái Ngọc Duy 2015-12-21 17:28 ` Junio C Hamano 2015-12-21 18:31 ` Junio C Hamano 2015-12-22 1:06 ` Duy Nguyen 2015-12-22 21:50 ` Junio C Hamano
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).