From: Jonathan Tan <jonathantanmy@google.com>
To: git@vger.kernel.org
Cc: sbeller@google.com, gitster@pobox.com, jacob.keller@gmail.com,
Jonathan Tan <jonathantanmy@google.com>
Subject: [WIP 1/2] submodule: refactor acquisition of superproject info
Date: Fri, 1 Dec 2017 14:50:06 -0800 [thread overview]
Message-ID: <14e821d45e4ac2faea1f9023d43c43c4675672e7.1512168087.git.jonathantanmy@google.com> (raw)
In-Reply-To: <cover.1512168087.git.jonathantanmy@google.com>
In-Reply-To: <cover.1512168087.git.jonathantanmy@google.com>
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
---
submodule.c | 76 +++++++++++++++++++++++++++++++++++++------------------------
submodule.h | 3 +++
2 files changed, 49 insertions(+), 30 deletions(-)
diff --git a/submodule.c b/submodule.c
index bb531e0e5..ce511180e 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1977,16 +1977,24 @@ void absorb_git_dir_into_superproject(const char *prefix,
}
}
-const char *get_superproject_working_tree(void)
+/*
+ * Get the full filename of the gitlink entry corresponding to the
+ * superproject having this repo as a submodule.
+ *
+ * full_name will point to an internal buffer upon success.
+ *
+ * Return 0 if successful, 1 if not (for example, if the parent
+ * directory is not a repo or an unrelated one).
+ */
+int get_superproject_entry(const char **full_name)
{
+ static struct strbuf sb = STRBUF_INIT;
+
struct child_process cp = CHILD_PROCESS_INIT;
- struct strbuf sb = STRBUF_INIT;
const char *one_up = real_path_if_valid("../");
const char *cwd = xgetcwd();
- const char *ret = NULL;
const char *subpath;
int code;
- ssize_t len;
if (!is_inside_work_tree())
/*
@@ -1994,11 +2002,15 @@ const char *get_superproject_working_tree(void)
* We might have a superproject, but it is harder
* to determine.
*/
- return NULL;
+ return 1;
if (!one_up)
- return NULL;
+ return 1;
+ /*
+ * No need to reset sb, since relative_path() will do it if
+ * necessary.
+ */
subpath = relative_path(cwd, one_up, &sb);
prepare_submodule_repo_env(&cp.env_array);
@@ -2017,45 +2029,49 @@ const char *get_superproject_working_tree(void)
if (start_command(&cp))
die(_("could not start ls-files in .."));
- len = strbuf_read(&sb, cp.out, PATH_MAX);
+ strbuf_read(&sb, cp.out, PATH_MAX);
close(cp.out);
- if (starts_with(sb.buf, "160000")) {
- int super_sub_len;
- int cwd_len = strlen(cwd);
- char *super_sub, *super_wt;
+ code = finish_command(&cp);
+ if (starts_with(sb.buf, "160000")) {
/*
* There is a superproject having this repo as a submodule.
* The format is <mode> SP <hash> SP <stage> TAB <full name> \0,
* We're only interested in the name after the tab.
*/
- super_sub = strchr(sb.buf, '\t') + 1;
- super_sub_len = sb.buf + sb.len - super_sub - 1;
-
- if (super_sub_len > cwd_len ||
- strcmp(&cwd[cwd_len - super_sub_len], super_sub))
- die (_("BUG: returned path string doesn't match cwd?"));
-
- super_wt = xstrdup(cwd);
- super_wt[cwd_len - super_sub_len] = '\0';
-
- ret = real_path(super_wt);
- free(super_wt);
+ char *tab = strchr(sb.buf, '\t');
+ if (!tab)
+ die("BUG: ls-files returned line with no tab");
+ *full_name = tab + 1;
+ return 0;
}
- strbuf_release(&sb);
-
- code = finish_command(&cp);
if (code == 128)
/* '../' is not a git repository */
- return NULL;
- if (code == 0 && len == 0)
+ return 1;
+ if (code == 0)
/* There is an unrelated git repository at '../' */
+ return 1;
+ die(_("ls-tree returned unexpected return code %d"), code);
+}
+
+const char *get_superproject_working_tree(void)
+{
+ const char *full_name;
+ char *super_wt;
+ size_t len;
+ const char *ret;
+
+ if (get_superproject_entry(&full_name))
return NULL;
- if (code)
- die(_("ls-tree returned unexpected return code %d"), code);
+ super_wt = xstrdup(xgetcwd());
+ if (!strip_suffix(super_wt, full_name, &len))
+ die("BUG: returned path string doesn't match cwd?");
+ super_wt[len] = '\0';
+ ret = real_path(super_wt);
+ free(super_wt);
return ret;
}
diff --git a/submodule.h b/submodule.h
index f0da0277a..29ab302cc 100644
--- a/submodule.h
+++ b/submodule.h
@@ -134,6 +134,9 @@ extern void absorb_git_dir_into_superproject(const char *prefix,
* 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.
+ *
+ * The return value, if not NULL, points to the same shared buffer as the one
+ * returned by real_path().
*/
extern const char *get_superproject_working_tree(void);
--
2.15.0.531.g2ccb3012c9-goog
next prev parent reply other threads:[~2017-12-01 22:50 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-01 22:50 [WIP 0/2] Submodule ref backend that mirrors superproject Jonathan Tan
2017-12-01 22:50 ` Jonathan Tan [this message]
2017-12-05 19:57 ` [WIP 1/2] submodule: refactor acquisition of superproject info Stefan Beller
2017-12-01 22:50 ` [WIP 2/2] submodule: read-only super-backed ref backend Jonathan Tan
2017-12-05 22:28 ` Stefan Beller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=14e821d45e4ac2faea1f9023d43c43c4675672e7.1512168087.git.jonathantanmy@google.com \
--to=jonathantanmy@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jacob.keller@gmail.com \
--cc=sbeller@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).