[PATCH/RFC/GSoC 1/2] count recursion depth

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]