Some commands may want to act differently when called transitively by other git commands in contrast to when called by the user directly. The variable recursion_depth provides all built-ins with a way to tell these cases apart. Scripts can use the underlying environment variable GIT_RECURSION_DEPTH to the same purpose. Wrappers around git can intentionally set GIT_RECURSION_DEPTH to ensure a command acts as if it was called internally. Signed-off-by: XZS <d.f.fischer@xxxxxx> --- cache.h | 1 + git.c | 17 +++++++++++++++++ t/t0001-init.sh | 1 + t/t0120-recursion-depth.sh | 17 +++++++++++++++++ 4 files changed, 36 insertions(+) create mode 100755 t/t0120-recursion-depth.sh diff --git a/cache.h b/cache.h index 9f09540..105607c 100644 --- a/cache.h +++ b/cache.h @@ -1777,6 +1777,7 @@ struct startup_info { const char *prefix; }; extern struct startup_info *startup_info; +extern int recursion_depth; /* merge.c */ struct commit_list; diff --git a/git.c b/git.c index 968a8a4..0bcc7b4 100644 --- a/git.c +++ b/git.c @@ -25,6 +25,7 @@ static const char *env_names[] = { }; static char *orig_env[4]; static int save_restore_env_balance; +int recursion_depth; static void save_env_before_alias(void) { @@ -630,12 +631,28 @@ static void restore_sigpipe_to_default(void) signal(SIGPIPE, SIG_DFL); } +static int get_recursion_depth(void) +{ + const char *envrec = getenv("GIT_RECURSION_DEPTH"); + return envrec ? strtol(envrec, NULL, 10) : 0; +} + +static int set_recursion_depth(int depth) +{ + char number[10]; // TODO compute length + snprintf(number, sizeof(number), "%i", depth); + return setenv("GIT_RECURSION_DEPTH", number, 1); +} + int main(int argc, char **av) { const char **argv = (const char **) av; const char *cmd; int done_help = 0; + recursion_depth = get_recursion_depth(); + set_recursion_depth(recursion_depth + 1); + cmd = git_extract_argv0_path(argv[0]); if (!cmd) cmd = "git-help"; diff --git a/t/t0001-init.sh b/t/t0001-init.sh index a5b9e7a..69e7532 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -93,6 +93,7 @@ test_expect_success 'No extra GIT_* on alias scripts' ' sed -n \ -e "/^GIT_PREFIX=/d" \ -e "/^GIT_TEXTDOMAINDIR=/d" \ + -e "/^GIT_RECURSION_DEPTH=/d" \ -e "/^GIT_/s/=.*//p" | sort EOF diff --git a/t/t0120-recursion-depth.sh b/t/t0120-recursion-depth.sh new file mode 100755 index 0000000..5aeb71a --- /dev/null +++ b/t/t0120-recursion-depth.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +test_description='recursion counter' + +. ./test-lib.sh + +test_expect_success 'recursion counter is 1 on direct run' ' + git config alias.one "!echo \$GIT_RECURSION_DEPTH" && + test "$(git one)" -eq 1 +' + +test_expect_success 'recursion counter is greater 1 on transitive run' ' + git config alias.two "!git one" && + test "$(git two)" -gt 1 +' + +test_done -- 2.8.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html