@@ -1514,3 +1514,85 @@ void absorb_git_dir_into_superproject(const char *prefix,
15141514 strbuf_release (& sb );
15151515 }
15161516}
1517+
1518+ const char * get_superproject_working_tree (void )
1519+ {
1520+ struct child_process cp = CHILD_PROCESS_INIT ;
1521+ struct strbuf sb = STRBUF_INIT ;
1522+ const char * one_up = real_path_if_valid ("../" );
1523+ const char * cwd = xgetcwd ();
1524+ const char * ret = NULL ;
1525+ const char * subpath ;
1526+ int code ;
1527+ ssize_t len ;
1528+
1529+ if (!is_inside_work_tree ())
1530+ /*
1531+ * FIXME:
1532+ * We might have a superproject, but it is harder
1533+ * to determine.
1534+ */
1535+ return NULL ;
1536+
1537+ if (!one_up )
1538+ return NULL ;
1539+
1540+ subpath = relative_path (cwd , one_up , & sb );
1541+
1542+ prepare_submodule_repo_env (& cp .env_array );
1543+ argv_array_pop (& cp .env_array );
1544+
1545+ argv_array_pushl (& cp .args , "--literal-pathspecs" , "-C" , ".." ,
1546+ "ls-files" , "-z" , "--stage" , "--full-name" , "--" ,
1547+ subpath , NULL );
1548+ strbuf_reset (& sb );
1549+
1550+ cp .no_stdin = 1 ;
1551+ cp .no_stderr = 1 ;
1552+ cp .out = -1 ;
1553+ cp .git_cmd = 1 ;
1554+
1555+ if (start_command (& cp ))
1556+ die (_ ("could not start ls-files in .." ));
1557+
1558+ len = strbuf_read (& sb , cp .out , PATH_MAX );
1559+ close (cp .out );
1560+
1561+ if (starts_with (sb .buf , "160000" )) {
1562+ int super_sub_len ;
1563+ int cwd_len = strlen (cwd );
1564+ char * super_sub , * super_wt ;
1565+
1566+ /*
1567+ * There is a superproject having this repo as a submodule.
1568+ * The format is <mode> SP <hash> SP <stage> TAB <full name> \0,
1569+ * We're only interested in the name after the tab.
1570+ */
1571+ super_sub = strchr (sb .buf , '\t' ) + 1 ;
1572+ super_sub_len = sb .buf + sb .len - super_sub - 1 ;
1573+
1574+ if (super_sub_len > cwd_len ||
1575+ strcmp (& cwd [cwd_len - super_sub_len ], super_sub ))
1576+ die (_ ("BUG: returned path string doesn't match cwd?" ));
1577+
1578+ super_wt = xstrdup (cwd );
1579+ super_wt [cwd_len - super_sub_len ] = '\0' ;
1580+
1581+ ret = real_path (super_wt );
1582+ free (super_wt );
1583+ }
1584+ strbuf_release (& sb );
1585+
1586+ code = finish_command (& cp );
1587+
1588+ if (code == 128 )
1589+ /* '../' is not a git repository */
1590+ return NULL ;
1591+ if (code == 0 && len == 0 )
1592+ /* There is an unrelated git repository at '../' */
1593+ return NULL ;
1594+ if (code )
1595+ die (_ ("ls-tree returned unexpected return code %d" ), code );
1596+
1597+ return ret ;
1598+ }
0 commit comments