From: Stefan Beller <sbeller@google.com>
To: jrnieder@gmail.com
Cc: git@vger.kernel.org, mfick@codeaurora.org,
Stefan Beller <sbeller@google.com>
Subject: [PATCH 1/3] submodule.c: port is_submodule_modified to use porcelain 2
Date: Mon, 20 Mar 2017 17:11:54 -0700 [thread overview]
Message-ID: <20170321001156.21915-2-sbeller@google.com> (raw)
In-Reply-To: <20170321001156.21915-1-sbeller@google.com>
Migrate 'is_submodule_modified' to the new porcelain format of
git-status.
As the old porcelain only reported ' M' for submodules, no
matter what happened inside the submodule (untracked files,
changes to tracked files or move of HEAD), the new API
properly reports the different scenarios.
In a followup patch we will make use of these finer grained
reporting for git-status.
While porting this to the new API, add another extension
point that will get used in the future: When a submodule
is broken (e.g. the .git file pointing to a wrong directory,
not containing a git dir, as fallout of e.g. f8eaa0ba98
(submodule--helper, module_clone: always operate on absolute
paths, 2016-03-31)), we can chose to not die and report it
differently.
Signed-off-by: Stefan Beller <sbeller@google.com>
---
submodule.c | 85 +++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 49 insertions(+), 36 deletions(-)
diff --git a/submodule.c b/submodule.c
index 3200b7bb2b..81d44cb7e9 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1041,67 +1041,80 @@ int fetch_populated_submodules(const struct argv_array *options,
unsigned is_submodule_modified(const char *path, int ignore_untracked)
{
- ssize_t len;
struct child_process cp = CHILD_PROCESS_INIT;
- const char *argv[] = {
- "status",
- "--porcelain",
- NULL,
- NULL,
- };
struct strbuf buf = STRBUF_INIT;
unsigned dirty_submodule = 0;
- const char *line, *next_line;
const char *git_dir;
+ int error_code = 0;
strbuf_addf(&buf, "%s/.git", path);
- git_dir = read_gitfile(buf.buf);
- if (!git_dir)
- git_dir = buf.buf;
- if (!is_directory(git_dir)) {
- strbuf_release(&buf);
- /* The submodule is not checked out, so it is not modified */
- return 0;
+ git_dir = resolve_gitdir_gently(buf.buf, &error_code);
+ if (!git_dir) {
+ switch (error_code) {
+ case READ_GITFILE_ERR_STAT_FAILED:
+ case READ_GITFILE_ERR_NOT_A_FILE:
+ /* We may have an uninitialized repo here */
+ return 0;
+ default:
+ case READ_GITFILE_ERR_OPEN_FAILED:
+ case READ_GITFILE_ERR_READ_FAILED:
+ case READ_GITFILE_ERR_INVALID_FORMAT:
+ case READ_GITFILE_ERR_NO_PATH:
+ case READ_GITFILE_ERR_NOT_A_REPO:
+ case READ_GITFILE_ERR_TOO_LARGE:
+ /*
+ * All these other error codes are indicating
+ * a broken submodule. We do not know what is
+ * right here. Resolve again triggering die()
+ * inside of the parsing.
+ */
+ read_gitfile_gently(buf.buf, NULL);
+ die("BUG: read_gitfile_gently should have died.");
+ }
}
+
strbuf_reset(&buf);
+ argv_array_pushl(&cp.args, "status", "--porcelain=2", NULL);
if (ignore_untracked)
- argv[2] = "-uno";
+ argv_array_push(&cp.args, "-uno");
- cp.argv = argv;
prepare_submodule_repo_env(&cp.env_array);
cp.git_cmd = 1;
cp.no_stdin = 1;
cp.out = -1;
cp.dir = path;
if (start_command(&cp))
- die("Could not run 'git status --porcelain' in submodule %s", path);
+ die("Could not run 'git status --porcelain=2' in submodule %s", path);
- len = strbuf_read(&buf, cp.out, 1024);
- line = buf.buf;
- while (len > 2) {
- if ((line[0] == '?') && (line[1] == '?')) {
+ while (strbuf_getwholeline_fd(&buf, cp.out, '\n') != EOF) {
+ /* regular untracked files */
+ if (buf.buf[0] == '?')
dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED;
- if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED)
- break;
- } else {
- dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
- if (ignore_untracked ||
- (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED))
- break;
+
+ /* regular unmerged and renamed files */
+ if (buf.buf[0] == 'u' ||
+ buf.buf[0] == '1' ||
+ buf.buf[0] == '2') {
+ if (buf.buf[5] == 'S') {
+ /* nested submodule handling */
+ if (buf.buf[6] == 'C' || buf.buf[7] == 'M')
+ dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
+ if (buf.buf[8] == 'U')
+ dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED;
+ } else
+ dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
}
- next_line = strchr(line, '\n');
- if (!next_line)
- break;
- next_line++;
- len -= (next_line - line);
- line = next_line;
+
+ if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED &&
+ dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)
+ break;
}
close(cp.out);
if (finish_command(&cp))
- die("'git status --porcelain' failed in submodule %s", path);
+ die("'git status --porcelain=2' failed in submodule %s", path);
strbuf_release(&buf);
return dirty_submodule;
--
2.12.0.402.g4b3201c2d6.dirty
next prev parent reply other threads:[~2017-03-21 0:18 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-21 0:11 [PATCH 0/3] git-describe deals gracefully with broken submodules Stefan Beller
2017-03-21 0:11 ` Stefan Beller [this message]
2017-03-21 0:11 ` [PATCH 2/3] revision machinery: gentle submodule errors Stefan Beller
2017-03-21 0:11 ` [PATCH 3/3] builtin/describe: introduce --submodule-error-as-dirty flag Stefan Beller
2017-03-21 6:28 ` [PATCH 0/3] git-describe deals gracefully with broken submodules Junio C Hamano
2017-03-21 6:54 ` Junio C Hamano
2017-03-21 18:51 ` [PATCH] builtin/describe: introduce --broken flag Stefan Beller
2017-03-21 21:51 ` Junio C Hamano
2017-03-21 22:27 ` Stefan Beller
2017-03-21 22:41 ` Junio C Hamano
2017-03-21 22:50 ` Stefan Beller
2017-03-21 22:57 ` [PATCH v2] " Stefan Beller
2017-03-22 17:21 ` Junio C Hamano
2017-03-22 21:50 ` Jakub Narębski
2017-03-21 17:46 ` [PATCH 0/3] git-describe deals gracefully with broken submodules Stefan Beller
-- strict thread matches above, loose matches on Subject: below --
2017-03-23 0:43 [PATCHv3 0/3] short status: improve reporting for submodule changes Stefan Beller
2017-03-23 0:43 ` [PATCH 1/3] submodule.c: port is_submodule_modified to use porcelain 2 Stefan Beller
2017-03-23 0:53 ` Jonathan Nieder
2017-03-23 6:09 ` Junio C Hamano
2017-03-23 18:47 ` 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=20170321001156.21915-2-sbeller@google.com \
--to=sbeller@google.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=mfick@codeaurora.org \
/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).