summaryrefslogtreecommitdiff
path: root/submodule.c
diff options
context:
space:
mode:
authorJens Lehmann <Jens.Lehmann@web.de>2011-03-06 22:12:58 (GMT)
committerJunio C Hamano <gitster@pobox.com>2011-03-09 21:10:35 (GMT)
commitc16c3e40b5908ecf28be12b1caf266c7ab8de3c6 (patch)
tree9ce602aebbccf20d66dd73d10b613d85bead1988 /submodule.c
parentbf42b384058ee2b34f587426d0788353ffa9012a (diff)
downloadgit-c16c3e40b5908ecf28be12b1caf266c7ab8de3c6.zip
git-c16c3e40b5908ecf28be12b1caf266c7ab8de3c6.tar.gz
git-c16c3e40b5908ecf28be12b1caf266c7ab8de3c6.tar.bz2
fetch/pull: Don't recurse into a submodule when commits are already present
When looking for submodules where new commits have been recorded in the superproject ignore those cases where the submodules commits are already present locally. This can happen e.g. when the submodule has been rewound to an earlier state. Then there is no need to fetch the submodule again as the commit recorded in the newly fetched superproject commit has already been fetched earlier into the submodule. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'submodule.c')
-rw-r--r--submodule.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/submodule.c b/submodule.c
index 924b156..88c7488 100644
--- a/submodule.c
+++ b/submodule.c
@@ -263,6 +263,33 @@ void set_config_fetch_recurse_submodules(int value)
config_fetch_recurse_submodules = value;
}
+static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
+{
+ int is_present = 0;
+ if (!add_submodule_odb(path) && lookup_commit_reference(sha1)) {
+ /* Even if the submodule is checked out and the commit is
+ * present, make sure it is reachable from a ref. */
+ struct child_process cp;
+ const char *argv[] = {"rev-list", "-n", "1", NULL, "--not", "--all", NULL};
+ struct strbuf buf = STRBUF_INIT;
+
+ argv[3] = sha1_to_hex(sha1);
+ memset(&cp, 0, sizeof(cp));
+ cp.argv = argv;
+ cp.env = local_repo_env;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.out = -1;
+ cp.dir = path;
+ if (!run_command(&cp) && !strbuf_read(&buf, cp.out, 1024))
+ is_present = 1;
+
+ close(cp.out);
+ strbuf_release(&buf);
+ }
+ return is_present;
+}
+
static void submodule_collect_changed_cb(struct diff_queue_struct *q,
struct diff_options *options,
void *data)
@@ -280,7 +307,7 @@ static void submodule_collect_changed_cb(struct diff_queue_struct *q,
* being moved around. */
struct string_list_item *path;
path = unsorted_string_list_lookup(&changed_submodule_paths, p->two->path);
- if (!path)
+ if (!path && !is_submodule_commit_present(p->two->path, p->two->sha1))
string_list_append(&changed_submodule_paths, xstrdup(p->two->path));
} else {
/* Submodule is new or was moved here */