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
* 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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.