Re: [WIP 1/2] submodule: refactor acquisition of superproject info

2017-12-05 Thread Stefan Beller
On Fri, Dec 1, 2017 at 2:50 PM, Jonathan Tan  wrote:
> Signed-off-by: Jonathan Tan 
> ---
>  submodule.c | 76 
> +
>  submodule.h |  3 +++


This patch reads very similar to [1], which was a preparation part of the series
"[RFC PATCH 0/4] git-status reports relation to superproject"; there
we also need
the same information about the superproject. I'll take a closer look
and compare these
two patches if it turns out we want to go this way long term.

[1] https://public-inbox.org/git/20171108195509.7839-3-sbel...@google.com/


[WIP 1/2] submodule: refactor acquisition of superproject info

2017-12-01 Thread Jonathan Tan
Signed-off-by: Jonathan Tan 
---
 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, );
 
prepare_submodule_repo_env(_array);
@@ -2017,45 +2029,49 @@ const char *get_superproject_working_tree(void)
if (start_command())
die(_("could not start ls-files in .."));
 
-   len = strbuf_read(, cp.out, PATH_MAX);
+   strbuf_read(, cp.out, PATH_MAX);
close(cp.out);
 
-   if (starts_with(sb.buf, "16")) {
-   int super_sub_len;
-   int cwd_len = strlen(cwd);
-   char *super_sub, *super_wt;
+   code = finish_command();
 
+   if (starts_with(sb.buf, "16")) {
/*
 * There is a superproject having this repo as a submodule.
 * The format is  SP  SP  TAB  \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_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();
-
-   code = finish_command();
 
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(_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, ))
+   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