[RFC PATCH] rev-parse: add --show-superproject-working-tree

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

 



Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx>
---

Marking this as RFC as documentation and tests are missing.

 builtin/rev-parse.c |  7 +++++
 submodule.c         | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 submodule.h         |  8 +++++
 3 files changed, 102 insertions(+)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index e08677e559..2549643267 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -12,6 +12,7 @@
 #include "diff.h"
 #include "revision.h"
 #include "split-index.h"
+#include "submodule.h"
 
 #define DO_REVS		1
 #define DO_NOREV	2
@@ -779,6 +780,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 					puts(work_tree);
 				continue;
 			}
+			if (!strcmp(arg, "--show-superproject-working-tree")) {
+				const char *superproject = get_superproject_working_tree();
+				if (superproject)
+					puts(superproject);
+				continue;
+			}
 			if (!strcmp(arg, "--show-prefix")) {
 				if (prefix)
 					puts(prefix);
diff --git a/submodule.c b/submodule.c
index 3b98766a6b..a63aef2c6b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1514,3 +1514,90 @@ void absorb_git_dir_into_superproject(const char *prefix,
 		strbuf_release(&sb);
 	}
 }
+
+static int superproject_exists(void)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+	struct strbuf sb = STRBUF_INIT;
+	struct strbuf buf = STRBUF_INIT;
+	const char *one_up = real_path_if_valid("../");
+	const char *dirname;
+	int code, has_superproject = 0;
+
+	if (!one_up)
+		/* At the root of the file system. */
+		return 0;
+
+	dirname = relative_path(xgetcwd(), one_up, &sb);
+	prepare_submodule_repo_env(&cp.env_array);
+	argv_array_pop(&cp.env_array);
+	argv_array_pushl(&cp.args, "--literal-pathspecs", "-C", "..",
+			"ls-tree", "HEAD", "--", dirname, NULL);
+
+	cp.no_stdin = 1;
+	cp.no_stderr = 1;
+	cp.out = -1;
+	cp.git_cmd = 1;
+
+	if (start_command(&cp))
+		die(_("could not start ls-tree in .."));
+
+	strbuf_read(&buf, cp.out, 7);
+	close(cp.out);
+	if (starts_with(buf.buf, "160000"))
+		/* there is a superproject having this as a submodule */
+		has_superproject = 1;
+
+	code = finish_command(&cp);
+
+	if (code == 128)
+		/* not a git repository */
+		goto out;
+	if (code == 0 && !has_superproject)
+		/* there is an unrelated git repository */
+		goto out;
+
+	if (code)
+		die(_("ls-tree returned unexpected return code"));
+
+	return 1;
+
+out:
+	strbuf_release(&sb);
+
+	return 0;
+}
+
+const char *get_superproject_working_tree()
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+	struct strbuf sb = STRBUF_INIT;
+
+	if (!superproject_exists())
+		return NULL;
+
+	prepare_submodule_repo_env(&cp.env_array);
+	argv_array_pop(&cp.env_array);
+
+	argv_array_pushl(&cp.args, "-C", "..",
+			"rev-parse", "--show-toplevel", NULL);
+
+	cp.no_stdin = 1;
+	cp.no_stderr = 1;
+	cp.out = -1;
+	cp.git_cmd = 1;
+
+	if (start_command(&cp))
+		die(_("could not start rev-parse in .."));
+
+	strbuf_reset(&sb);
+	strbuf_read(&sb, cp.out, PATH_MAX);
+
+	/* remove trailing new line */
+	strbuf_rtrim(&sb);
+
+	if (finish_command(&cp))
+		die(_("rev-parse died unexpectedly"));
+
+	return strbuf_detach(&sb, NULL);
+}
diff --git a/submodule.h b/submodule.h
index 05ab674f06..f207bb8d5f 100644
--- a/submodule.h
+++ b/submodule.h
@@ -93,4 +93,12 @@ extern void prepare_submodule_repo_env(struct argv_array *out);
 extern void absorb_git_dir_into_superproject(const char *prefix,
 					     const char *path,
 					     unsigned flags);
+
+/*
+ * Return the absolute path of the working tree of the superproject, which this
+ * project is a submodule of. If this repository is not a submodule of
+ * another repository, return NULL.
+ */
+extern const char *get_superproject_working_tree();
+
 #endif
-- 
2.12.0.189.g3bc53220cb.dirty




[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]