git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jens Lehmann <Jens.Lehmann@web.de>
To: Git Mailing List <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: [PATCH 1/2] fetch/pull: Recursively fetch populated submodules
Date: Sun, 29 Aug 2010 17:50:32 +0200	[thread overview]
Message-ID: <4C7A81C8.9070402@web.de> (raw)
In-Reply-To: <4C7A819B.3000403@web.de>

Until now you had to call "git submodule update" (without the using the
-N|--no-fetch option) or something like "git submodule foreach git fetch"
to fetch new commits in populated submodules from their remote.

This could lead to "(commits not present)" messages in the output of "git
diff --submodule" (and in "git gui" and "gitk") after fetching/pulling new
commits in the superproject and is an obstacle for implementing recursive
checkout of submodules.

This patch recursively fetches each populated submodule from the url
configured in the .git/config of the submodule at the end of each "git
fetch" or during "git pull" in the superproject. This new behavior can be
disabled by using the new --no-recursive option.

t7403 had to be changed to use the --no-recursive option for pull.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---
 Documentation/fetch-options.txt |    5 +++
 builtin/fetch.c                 |   11 ++++++-
 git-pull.sh                     |   10 +++++-
 submodule.c                     |   43 +++++++++++++++++++++++++-
 submodule.h                     |    2 +
 t/t5526-fetch-submodules.sh     |   64 +++++++++++++++++++++++++++++++++++++++
 t/t7403-submodule-sync.sh       |    2 +-
 7 files changed, 132 insertions(+), 5 deletions(-)
 create mode 100755 t/t5526-fetch-submodules.sh

diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 470ac31..1d875be 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -64,6 +64,11 @@ endif::git-pull[]
 	specified with the remote.<name>.tagopt setting. See
 	linkgit:git-config[1].

+--[no-]recursive::
+	By default new commits of all populated submodules will be fetched
+	too. This option can be used to disable/enable recursive fetching of
+	submodules.
+
 -u::
 --update-head-ok::
 	By default 'git fetch' refuses to update the head which
diff --git a/builtin/fetch.c b/builtin/fetch.c
index fab3fce..da5fc9a 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -12,6 +12,7 @@
 #include "parse-options.h"
 #include "sigchain.h"
 #include "transport.h"
+#include "submodule.h"

 static const char * const builtin_fetch_usage[] = {
 	"git fetch [<options>] [<repository> [<refspec>...]]",
@@ -27,7 +28,7 @@ enum {
 	TAGS_SET = 2
 };

-static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
+static int all, append, dry_run, force, keep, multiple, prune, recursive = -1, update_head_ok, verbosity;
 static int progress;
 static int tags = TAGS_DEFAULT;
 static const char *depth;
@@ -53,6 +54,8 @@ static struct option builtin_fetch_options[] = {
 		    "do not fetch all tags (--no-tags)", TAGS_UNSET),
 	OPT_BOOLEAN('p', "prune", &prune,
 		    "prune tracking branches no longer on remote"),
+	OPT_BOOLEAN(0, "recursive", &recursive,
+		    "control recursive fetching of submodules"),
 	OPT_BOOLEAN(0, "dry-run", &dry_run,
 		    "dry run"),
 	OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
@@ -921,6 +924,12 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 		}
 	}

+	if (!result && recursive) {
+		gitmodules_config();
+		git_config(submodule_config, NULL);
+		result = fetch_populated_submodules();
+	}
+
 	/* All names were strdup()ed or strndup()ed */
 	list.strdup_strings = 1;
 	string_list_clear(&list, 0);
diff --git a/git-pull.sh b/git-pull.sh
index 8eb74d4..4bc8a60 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -38,7 +38,7 @@ test -z "$(git ls-files -u)" || die_conflict
 test -f "$GIT_DIR/MERGE_HEAD" && die_merge

 strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
-log_arg= verbosity= progress=
+log_arg= verbosity= progress= recursive=
 merge_args=
 curr_branch=$(git symbolic-ref -q HEAD)
 curr_branch_short="${curr_branch#refs/heads/}"
@@ -105,6 +105,12 @@ do
 	--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
 		rebase=false
 		;;
+	--recursive)
+		recursive=--recursive
+		;;
+	--no-recursive)
+		recursive=--no-recursive
+		;;
 	--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
 		dry_run=--dry-run
 		;;
@@ -220,7 +226,7 @@ test true = "$rebase" && {
 	done
 }
 orig_head=$(git rev-parse -q --verify HEAD)
-git fetch $verbosity $progress $dry_run --update-head-ok "$@" || exit 1
+git fetch $verbosity $progress $dry_run $recursive --update-head-ok "$@" || exit 1
 test -z "$dry_run" || exit 0

 curr_head=$(git rev-parse -q --verify HEAD)
diff --git a/submodule.c b/submodule.c
index 91a4758..e4f2419 100644
--- a/submodule.c
+++ b/submodule.c
@@ -63,7 +63,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
 	}
 }

-static int submodule_config(const char *var, const char *value, void *cb)
+int submodule_config(const char *var, const char *value, void *cb)
 {
 	if (!prefixcmp(var, "submodule."))
 		return parse_submodule_config_option(var, value);
@@ -229,6 +229,47 @@ void show_submodule_summary(FILE *f, const char *path,
 	strbuf_release(&sb);
 }

+int fetch_populated_submodules()
+{
+	int result = 0;
+	struct child_process cp;
+	const char *argv[] = {
+		"fetch",
+		NULL,
+	};
+	struct string_list_item *name_for_path;
+	const char *work_tree = get_git_work_tree();
+	if (!work_tree)
+		return 0;
+
+	memset(&cp, 0, sizeof(cp));
+	cp.argv = argv;
+	cp.env = local_repo_env;
+	cp.git_cmd = 1;
+	cp.no_stdin = 1;
+	cp.out = -1;
+
+	for_each_string_list_item(name_for_path, &config_name_for_path) {
+		struct strbuf submodule_path = STRBUF_INIT;
+		struct strbuf submodule_git_dir = STRBUF_INIT;
+		const char *git_dir;
+		strbuf_addf(&submodule_path, "%s/%s", work_tree, name_for_path->string);
+		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
+		git_dir = read_gitfile_gently(submodule_git_dir.buf);
+		if (!git_dir)
+			git_dir = submodule_git_dir.buf;
+		if (is_directory(git_dir)) {
+			printf("Fetching submodule %s\n", name_for_path->string);
+			cp.dir = submodule_path.buf;
+			if (run_command(&cp))
+				result = 1;
+		}
+		strbuf_release(&submodule_path);
+		strbuf_release(&submodule_git_dir);
+	}
+	return result;
+}
+
 unsigned is_submodule_modified(const char *path, int ignore_untracked)
 {
 	ssize_t len;
diff --git a/submodule.h b/submodule.h
index 386f410..380878c 100644
--- a/submodule.h
+++ b/submodule.h
@@ -5,6 +5,7 @@ struct diff_options;

 void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
 		const char *path);
+int submodule_config(const char *var, const char *value, void *cb);
 void gitmodules_config();
 int parse_submodule_config_option(const char *var, const char *value);
 void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
@@ -12,6 +13,7 @@ void show_submodule_summary(FILE *f, const char *path,
 		unsigned char one[20], unsigned char two[20],
 		unsigned dirty_submodule,
 		const char *del, const char *add, const char *reset);
+int fetch_populated_submodules();
 unsigned is_submodule_modified(const char *path, int ignore_untracked);
 int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
 		    const unsigned char a[20], const unsigned char b[20]);
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
new file mode 100755
index 0000000..da5d5fd
--- /dev/null
+++ b/t/t5526-fetch-submodules.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# Copyright (c) 2010, Jens Lehmann
+
+test_description='Recursive "git fetch" for submodules'
+
+. ./test-lib.sh
+
+pwd=$(pwd)
+
+add_upstream_commit() {
+	(
+		cd submodule &&
+		head1=$(git rev-parse --short HEAD) &&
+		echo new >> subfile &&
+		test_tick &&
+		git add subfile &&
+		git commit -m new subfile &&
+		head2=$(git rev-parse --short HEAD) &&
+		echo "From $pwd/submodule" > ../expect.err
+		echo "   $head1..$head2  master     -> origin/master" >> ../expect.err
+	)
+}
+
+test_expect_success setup '
+	mkdir submodule &&
+	(
+		cd submodule &&
+		git init &&
+		echo subcontent > subfile &&
+		git add subfile &&
+		git commit -m new subfile
+	) &&
+	git submodule add "$pwd/submodule" submodule &&
+	git commit -am initial &&
+	git clone . downstream &&
+	(
+		cd downstream &&
+		git submodule init &&
+		git submodule update
+	) &&
+	echo "Fetching submodule submodule" > expect.out
+'
+
+test_expect_success "fetch recurses into submodules" '
+	add_upstream_commit &&
+	(
+		cd downstream &&
+		git fetch >../actual.out 2>../actual.err
+	) &&
+	test_cmp expect.out actual.out &&
+	test_cmp expect.err actual.err
+'
+
+test_expect_success "fetch --no-recursive only fetches superproject" '
+	add_upstream_commit &&
+	(
+		cd downstream &&
+		git fetch --no-recursive >../actual.out 2>../actual.err
+	) &&
+	! test -s actual.out &&
+	! test -s actual.err
+'
+
+test_done
diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh
index 02522f9..6f3e966 100755
--- a/t/t7403-submodule-sync.sh
+++ b/t/t7403-submodule-sync.sh
@@ -50,7 +50,7 @@ test_expect_success 'change submodule url' '

 test_expect_success '"git submodule sync" should update submodule URLs' '
 	(cd super-clone &&
-	 git pull &&
+	 git pull --no-recursive &&
 	 git submodule sync
 	) &&
 	test -d "$(git config -f super-clone/submodule/.git/config \
-- 
1.7.2.2.527.gdf3084

  reply	other threads:[~2010-08-29 15:50 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-29 15:49 [RFC PATCH 0/2] Teach fetch and pull to recursively fetch submodules too Jens Lehmann
2010-08-29 15:50 ` Jens Lehmann [this message]
2010-08-29 15:51 ` [PATCH 2/2] Submodules: Add the new "fetch" config option Jens Lehmann
2010-08-30  7:34   ` Junio C Hamano
2010-08-30 17:37     ` [PATCH 2/2 v2] Submodules: Add the new "fetch" config option for fetch and pull Jens Lehmann
2010-08-29 17:29 ` [RFC PATCH 0/2] Teach fetch and pull to recursively fetch submodules too Ævar Arnfjörð Bjarmason
2010-08-29 22:34   ` Jens Lehmann
2010-08-30  5:58 ` Junio C Hamano
2010-08-30 17:41   ` Jens Lehmann
2010-09-15  0:18   ` Kevin Ballard
2010-09-15  2:40     ` Kevin Ballard
2010-09-16 13:55       ` [PATCH] fetch: Get submodule paths from index and not from .gitmodules Jens Lehmann
2010-09-16 19:29         ` Kevin Ballard
2010-09-17 11:31           ` Jens Lehmann
2010-09-17 12:06             ` Johannes Sixt
2010-09-17 12:22               ` Jens Lehmann
2010-09-17 12:32                 ` Johannes Sixt
2010-09-17 14:01                   ` Jens Lehmann
2010-09-17 14:14                     ` Johannes Sixt
2010-09-18  0:29                 ` Kevin Ballard
2010-09-18 22:32                   ` [PATCH 0/2] fix problems with recursive submodule fetching Jens Lehmann
2010-09-18 22:33                     ` [PATCH 1/2] fetch: Fix a bug swallowing the output of " Jens Lehmann
2010-09-18 22:35                     ` [PATCH 2/2] fetch: Get submodule paths from index and not from .gitmodules Jens Lehmann
2010-09-19  3:54                     ` [PATCH 0/2] fix problems with recursive submodule fetching Kevin Ballard
2010-09-19 16:40                       ` Jens Lehmann
2010-09-20  6:40                         ` Kevin Ballard
2010-10-05 20:43                           ` [PATCH v2 0/3] Teach fetch and pull to recursively fetch submodules too Jens Lehmann
2010-10-05 20:43                             ` [PATCH 1/3] fetch/pull: Recursively fetch populated submodules Jens Lehmann
2010-10-05 20:44                             ` [PATCH 2/3] Submodules: Add the new "fetch" config option for fetch and pull Jens Lehmann
2010-10-07 13:33                               ` Jon Seymour
2010-10-09 19:22                                 ` Jens Lehmann
2010-10-09 19:54                                   ` Jonathan Nieder
2010-10-09 20:12                                     ` Jens Lehmann
2010-10-05 20:45                             ` [PATCH 3/3] Add the 'fetch.recursive' config setting Jens Lehmann
2010-10-05 21:06                             ` [PATCH v2 0/3] Teach fetch and pull to recursively fetch submodules too Junio C Hamano
2010-10-06 22:52                             ` Kevin Ballard
2010-10-06 23:22                               ` Jonathan Nieder
2010-10-09 19:28                                 ` Jens Lehmann
2010-10-09 20:02                                   ` Jonathan Nieder
2010-10-09 20:37                                     ` Jens Lehmann
2010-10-21 18:29                                       ` Jonathan Nieder
2010-10-21 21:15                                         ` Jens Lehmann
2010-10-09 19:17                               ` Jens Lehmann
2010-10-13 14:48                                 ` Marc Branchaud
2010-10-13 19:32                                   ` Jens Lehmann
2010-10-13 19:34                                     ` Kevin Ballard
2010-10-13 20:06                                       ` Jens Lehmann
2010-10-13 20:11                                         ` Kevin Ballard
2010-10-14  1:01                                         ` Chris Packham
2010-10-14 18:14                                           ` Jens Lehmann
2010-10-14 18:31                                             ` Chris Packham
2010-10-13 21:27                                       ` Marc Branchaud
2010-10-13 21:31                                         ` Kevin Ballard
2010-09-15 11:32     ` [RFC PATCH 0/2] " Jens Lehmann
2010-09-15 23:12       ` Kevin Ballard

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=4C7A81C8.9070402@web.de \
    --to=jens.lehmann@web.de \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.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.
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).