From: Stefan Beller <sbeller@google.com>
To: unlisted-recipients:; (no To-header on input)
Cc: git@vger.kernel.org, bmwill@google.com, gitster@pobox.com,
jrnieder@gmail.com, mogulguy10@gmail.com,
David.Turner@twosigma.com, Stefan Beller <sbeller@google.com>
Subject: [PATCH 13/16] submodule: teach unpack_trees() to update submodules
Date: Tue, 15 Nov 2016 15:06:48 -0800 [thread overview]
Message-ID: <20161115230651.23953-14-sbeller@google.com> (raw)
In-Reply-To: <20161115230651.23953-1-sbeller@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
entry.c | 7 +++--
unpack-trees.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++----------
unpack-trees.h | 1 +
3 files changed, 86 insertions(+), 19 deletions(-)
diff --git a/entry.c b/entry.c
index 2330b6e..dd829ec 100644
--- a/entry.c
+++ b/entry.c
@@ -270,7 +270,7 @@ int checkout_entry(struct cache_entry *ce,
if (!check_path(path.buf, path.len, &st, state->base_dir_len)) {
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
- if (!changed)
+ if (!changed && (!S_ISDIR(st.st_mode) || !S_ISGITLINK(ce->ce_mode)))
return 0;
if (!state->force) {
if (!state->quiet)
@@ -287,9 +287,10 @@ int checkout_entry(struct cache_entry *ce,
* just do the right thing)
*/
if (S_ISDIR(st.st_mode)) {
- /* If it is a gitlink, leave it alone! */
- if (S_ISGITLINK(ce->ce_mode))
+ if (S_ISGITLINK(ce->ce_mode)) {
+ schedule_submodule_for_update(ce, 1);
return 0;
+ }
if (!state->force)
return error("%s is a directory", path.buf);
remove_subtree(&path);
diff --git a/unpack-trees.c b/unpack-trees.c
index 576e1d5..c5c22ed 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -29,6 +29,9 @@ static const char *unpack_plumbing_errors[NB_UNPACK_TREES_ERROR_TYPES] = {
/* ERROR_NOT_UPTODATE_DIR */
"Updating '%s' would lose untracked files in it",
+ /* ERROR_NOT_UPTODATE_SUBMODULE */
+ "Updating submodule '%s' would lose modifications in it",
+
/* ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN */
"Untracked working tree file '%s' would be overwritten by merge.",
@@ -80,6 +83,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
msgs[ERROR_NOT_UPTODATE_DIR] =
_("Updating the following directories would lose untracked files in it:\n%s");
+ msgs[ERROR_NOT_UPTODATE_SUBMODULE] =
+ _("Updating the following submodules would lose modifications in it:\n%s");
if (!strcmp(cmd, "checkout"))
msg = advice_commit_before_merge
@@ -1315,19 +1320,18 @@ static int verify_uptodate_1(const struct cache_entry *ce,
return 0;
if (!lstat(ce->name, &st)) {
- int flags = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE;
- unsigned changed = ie_match_stat(o->src_index, ce, &st, flags);
- if (!changed)
- return 0;
- /*
- * NEEDSWORK: the current default policy is to allow
- * submodule to be out of sync wrt the superproject
- * index. This needs to be tightened later for
- * submodules that are marked to be automatically
- * checked out.
- */
- if (S_ISGITLINK(ce->ce_mode))
- return 0;
+ if (!S_ISGITLINK(ce->ce_mode)) {
+ int flags = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE;
+ unsigned changed = ie_match_stat(o->src_index, ce, &st, flags);
+ if (!changed)
+ return 0;
+ } else {
+ if (!submodule_is_interesting(ce->name, null_sha1))
+ return 0;
+ if (ce_stage(ce) ? is_submodule_checkout_safe(ce->name, &ce->oid)
+ : !is_submodule_modified(ce->name, 1))
+ return 0;
+ }
errno = 0;
}
if (errno == ENOENT)
@@ -1350,6 +1354,59 @@ static int verify_uptodate_sparse(const struct cache_entry *ce,
return verify_uptodate_1(ce, o, ERROR_SPARSE_NOT_UPTODATE_FILE);
}
+/*
+ * When a submodule gets turned into an unmerged entry, we want it to be
+ * up-to-date regarding the merge changes.
+ */
+static int verify_uptodate_submodule(const struct cache_entry *old,
+ const struct cache_entry *new,
+ struct unpack_trees_options *o)
+{
+ struct stat st;
+
+ if (o->index_only
+ || (!((old->ce_flags & CE_VALID) || ce_skip_worktree(old))
+ && (o->reset || ce_uptodate(old))))
+ return 0;
+ if (!submodule_is_interesting(new->name, null_sha1))
+ return 0;
+ if (!lstat(old->name, &st)) {
+ unsigned changed = ie_match_stat(o->src_index, old, &st,
+ CE_MATCH_IGNORE_VALID|
+ CE_MATCH_IGNORE_SKIP_WORKTREE);
+ if (!changed) {
+ /* old is always a submodule */
+ if (S_ISGITLINK(new->ce_mode)) {
+ /*
+ * new is also a submodule, so check if we care
+ * and then if can checkout the new sha1 safely
+ */
+ if (submodule_is_interesting(old->name, null_sha1)
+ && is_submodule_checkout_safe(new->name, &new->oid))
+ return 0;
+ } else {
+ /*
+ * new is not a submodule any more, so only
+ * care if we care:
+ */
+ if (submodule_is_interesting(old->name, null_sha1)
+ && ok_to_remove_submodule(old->name))
+ return 0;
+ }
+ } else {
+ if (S_ISGITLINK(new->ce_mode))
+ return !is_submodule_checkout_safe(new->name, &new->oid);
+ else
+ return !ok_to_remove_submodule(old->name);
+ }
+ errno = 0;
+ }
+ if (errno == ENOENT)
+ return 0;
+ return o->gently ? -1 :
+ add_rejected_path(o, ERROR_NOT_UPTODATE_SUBMODULE, old->name);
+}
+
static void invalidate_ce_path(const struct cache_entry *ce,
struct unpack_trees_options *o)
{
@@ -1608,9 +1665,17 @@ static int merged_entry(const struct cache_entry *ce,
copy_cache_entry(merge, old);
update = 0;
} else {
- if (verify_uptodate(old, o)) {
- free(merge);
- return -1;
+ if (S_ISGITLINK(old->ce_mode) ||
+ S_ISGITLINK(merge->ce_mode)) {
+ if (verify_uptodate_submodule(old, merge, o)) {
+ free(merge);
+ return -1;
+ }
+ } else {
+ if (verify_uptodate(old, o)) {
+ free(merge);
+ return -1;
+ }
}
/* Migrate old flags over */
update |= old->ce_flags & (CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE);
diff --git a/unpack-trees.h b/unpack-trees.h
index 36a73a6..bee8740 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -15,6 +15,7 @@ enum unpack_trees_error_types {
ERROR_WOULD_OVERWRITE = 0,
ERROR_NOT_UPTODATE_FILE,
ERROR_NOT_UPTODATE_DIR,
+ ERROR_NOT_UPTODATE_SUBMODULE,
ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN,
ERROR_WOULD_LOSE_UNTRACKED_REMOVED,
ERROR_BIND_OVERLAP,
--
2.10.1.469.g00a8914
next prev parent reply other threads:[~2016-11-15 23:07 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-15 23:06 [RFC PATCH 00/16] Checkout aware of Submodules! Stefan Beller
2016-11-15 23:06 ` [PATCH 01/16] submodule.h: add extern keyword to functions, break line before 80 Stefan Beller
2016-11-16 19:08 ` Junio C Hamano
2016-11-17 18:29 ` Stefan Beller
2016-11-15 23:06 ` [PATCH 02/16] submodule: modernize ok_to_remove_submodule to use argv_array Stefan Beller
2016-11-15 23:11 ` David Turner
2016-11-16 19:03 ` Junio C Hamano
2016-11-17 18:36 ` Stefan Beller
2016-11-15 23:06 ` [PATCH 03/16] submodule: use absolute path for computing relative path connecting Stefan Beller
2016-11-15 23:06 ` [PATCH 04/16] update submodules: add is_submodule_populated Stefan Beller
2016-11-15 23:20 ` Brandon Williams
2016-11-15 23:06 ` [PATCH 05/16] update submodules: add submodule config parsing Stefan Beller
2016-11-15 23:06 ` [PATCH 06/16] update submodules: add a config option to determine if submodules are updated Stefan Beller
2016-11-15 23:06 ` [PATCH 07/16] update submodules: introduce submodule_is_interesting Stefan Beller
2016-11-15 23:34 ` Brandon Williams
2016-11-16 0:14 ` David Turner
2016-11-17 20:03 ` Stefan Beller
[not found] ` <20161117105715.GC39230@book.hvoigt.net>
2016-11-17 20:08 ` Stefan Beller
2016-11-15 23:06 ` [PATCH 08/16] update submodules: add depopulate_submodule Stefan Beller
2016-11-15 23:44 ` Brandon Williams
2016-11-17 22:23 ` Stefan Beller
2016-11-17 22:29 ` Brandon Williams
2016-11-17 22:42 ` Stefan Beller
2016-11-18 0:16 ` Stefan Beller
2016-11-18 17:46 ` Brandon Williams
2016-11-18 18:25 ` Stefan Beller
[not found] ` <20161117111337.GD39230@book.hvoigt.net>
2016-11-17 22:28 ` Stefan Beller
2016-11-15 23:06 ` [PATCH 09/16] update submodules: add scheduling to update submodules Stefan Beller
2016-11-16 0:02 ` Brandon Williams
2016-11-16 0:07 ` David Turner
2016-11-18 0:28 ` Stefan Beller
2016-11-15 23:06 ` [PATCH 10/16] update submodules: is_submodule_checkout_safe Stefan Beller
2016-11-16 0:06 ` Brandon Williams
2016-11-15 23:06 ` [PATCH 11/16] teach unpack_trees() to remove submodule contents Stefan Beller
2016-11-16 0:14 ` Brandon Williams
[not found] ` <20161117133538.GF39230@book.hvoigt.net>
2016-11-18 19:25 ` Stefan Beller
2016-11-15 23:06 ` [PATCH 12/16] entry: write_entry to write populate submodules Stefan Beller
2016-11-15 23:06 ` Stefan Beller [this message]
2016-11-16 0:22 ` [PATCH 13/16] submodule: teach unpack_trees() to update submodules David Turner
2016-11-18 23:33 ` Stefan Beller
2016-11-21 18:12 ` David Turner
2016-11-16 0:25 ` Brandon Williams
2016-11-18 23:39 ` Stefan Beller
2016-11-15 23:06 ` [PATCH 14/16] checkout: recurse into submodules if asked to Stefan Beller
2016-11-16 0:33 ` Brandon Williams
2016-11-16 17:03 ` David Turner
2016-11-16 17:05 ` David Turner
2016-11-15 23:06 ` [PATCH 15/16] completion: add '--recurse-submodules' to checkout Stefan Beller
2016-11-15 23:06 ` [PATCH 16/16] checkout: add config option to recurse into submodules by default Stefan Beller
2016-12-03 6:13 ` [RFC PATCH 00/16] Checkout aware of Submodules! Xiaodong Qi
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=20161115230651.23953-14-sbeller@google.com \
--to=sbeller@google.com \
--cc=David.Turner@twosigma.com \
--cc=bmwill@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jrnieder@gmail.com \
--cc=mogulguy10@gmail.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.
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.