git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH, 2nd version] git-fetch, git-branch: Support local --track via a special remote `.'
@ 2007-03-12 17:14 Paolo Bonzini
  2007-03-13  9:29 ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2007-03-12 17:14 UTC (permalink / raw
  To: git

This patch adds support for a dummy remote `.' to avoid having to declare
a fake remote like

	[remote "local"]
		url = .
		fetch = refs/heads/*:refs/heads/*

Such a builtin remote simplifies the operation of "git-fetch", which
will populate FETCH_HEAD but will not pretend that two repositories are
in use, will not create a thin pack, and will not perform any useless
remapping of names.  The speed improvement is around 20%, and it should
improve more if "git-fetch" is converted to a builtin.

To this end, git-parse-remote is grown with a new kind of remote, `builtin'.
In git-fetch.sh, we treat the builtin remote specially in that it needs no
pack/store operations.  In fact, doing git-fetch on a builtin remote will
simply populate FETCH_HEAD appropriately.

The patch also improves of the --track/--no-track support, extending
it so that branch.<name>.remote items referring `.' can be created.

Signed-off-by: Paolo Bonzini  <bonzini@gnu.org>
---
 Documentation/config.txt |    4 ++++
 builtin-branch.c         |   39 +++++++++++++++++++++++++--------------
 git-fetch.sh             |    9 +++++++--
 git-parse-remote.sh      |   22 +++++++++++++++++++++-
 t/t3200-branch.sh        |    6 ++++++
 t/t5520-pull.sh          |   13 +++++++++++++
 6 files changed, 76 insertions(+), 17 deletions(-)

	I hope this is what you meant in your reply to my message.

	I removed completely the configuration variable since it made
	no sense to me, either.

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5408dd6..28899d9 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -272,6 +272,10 @@ branch.<name>.merge::
 	`git fetch`) to lookup the default branch for merging. Without
 	this option, `git pull` defaults to merge the first refspec fetched.
 	Specify multiple values to get an octopus merge.
+	If you wish to setup `git pull` so that it merges into <name> from
+	another branch in the local repository, you can point
+	branch.<name>.merge to the desired branch, and use the special setting
+	`.` (a period) for branch.<name>.remote.
 
 color.branch::
 	A boolean to enable/disable color in the output of
diff --git a/builtin-branch.c b/builtin-branch.c
index 42b1ff1..14c4219 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -372,9 +372,26 @@ static int get_remote_config(const char *key, const char *value)
 	return 0;
 }
 
-static void set_branch_defaults(const char *name, const char *real_ref)
+static void set_branch_merge(const char *name, const char *config_remote,
+			     const char *config_repo)
 {
 	char key[1024];
+	if (sizeof(key) <=
+	    snprintf(key, sizeof(key), "branch.%s.remote", name))
+		die("what a long branch name you have!");
+	git_config_set(key, config_remote);
+
+	/*
+	 * We do not have to check if we have enough space for
+	 * the 'merge' key, since it's shorter than the
+	 * previous 'remote' key, which we already checked.
+	 */
+	snprintf(key, sizeof(key), "branch.%s.merge", name);
+	git_config_set(key, config_repo);
+}
+
+static void set_branch_defaults(const char *name, const char *real_ref)
+{
 	const char *slash = strrchr(real_ref, '/');
 
 	if (!slash)
@@ -384,21 +401,15 @@ static void set_branch_defaults(const char *name, const char *real_ref)
 	start_len = strlen(real_ref);
 	base_len = slash - real_ref;
 	git_config(get_remote_config);
+	if (!config_repo && !config_remote &&
+	    !prefixcmp(real_ref, "refs/heads/")) {
+		set_branch_merge(name, ".", real_ref);
+		printf("Branch %s set up to track local branch %s.\n",
+		       name, real_ref);
+	}
 
 	if (config_repo && config_remote) {
-		if (sizeof(key) <=
-		    snprintf(key, sizeof(key), "branch.%s.remote", name))
-			die("what a long branch name you have!");
-		git_config_set(key, config_remote);
-
-		/*
-		 * We do not have to check if we have enough space for
-		 * the 'merge' key, since it's shorter than the
-		 * previous 'remote' key, which we already checked.
-		 */
-		snprintf(key, sizeof(key), "branch.%s.merge", name);
-		git_config_set(key, config_repo);
-
+		set_branch_merge(name, config_remote, config_repo);
 		printf("Branch %s set up to track remote branch %s.\n",
 		       name, real_ref);
 	}
diff --git a/git-fetch.sh b/git-fetch.sh
index b9d7a75..e2a6878 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -164,6 +164,12 @@ then
 fi
 
 fetch_native () {
+  if test "$(get_data_source $remote_nick)" = builtin; then
+    for name in $(get_remote_fetch_branches "$remote_nick"); do
+      append_fetch_head $(git-rev-parse "$name") . "$name" "$name" || exit
+    done
+    return
+  fi
 
   eval=$(echo "$1" | git-fetch--tool parse-reflist "-")
   eval "$eval"
@@ -353,8 +359,7 @@ case ",$#,$remote_nick," in
 	curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
 	merge_branches=$(git-config \
 		--get-all "branch.${curr_branch}.merge" | sort -u)
-	fetch_branches=$(get_remote_default_refs_for_fetch -n $remote_nick |
-		sed -e 's/:.*$//g' -e 's/^+//' | sort -u)
+	fetch_branches=$(get_remote_fetch_branches $remote_nick)
 	test -n "$merge_branches" && test -n "$fetch_branches" &&
 	merge_branches=$(printf '%s\n%s' "$merge_branches" "$fetch_branches" |
 		sort | uniq -d)
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 99e7184..bc7533a 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -9,6 +9,9 @@ get_data_source () {
 	*/*)
 		echo ''
 		;;
+	.)
+		echo builtin
+		;;
 	*)
 		if test "$(git-config --get "remote.$1.url")"
 		then
@@ -31,6 +34,9 @@ get_remote_url () {
 	'')
 		echo "$1"
 		;;
+	builtin)
+		echo "$1"
+		;;
 	config)
 		git-config --get "remote.$1.url"
 		;;
@@ -57,7 +63,7 @@ get_default_remote () {
 get_remote_default_refs_for_push () {
 	data_source=$(get_data_source "$1")
 	case "$data_source" in
-	'' | branches)
+	'' | branches | builtin)
 		;; # no default push mapping, just send matching refs.
 	config)
 		git-config --get-all "remote.$1.push" ;;
@@ -128,6 +134,8 @@ get_remote_default_refs_for_fetch () {
 	case "$data_source" in
 	'')
 		set explicit "HEAD:" ;;
+	builtin)
+		set glob ;;
 	config)
 		set $(expand_refs_wildcard "$1" \
 			$(git-config --get-all "remote.$1.fetch")) ;;
@@ -154,6 +162,18 @@ get_remote_default_refs_for_fetch () {
 	fi
 }
 
+# Returns list of sources
+get_remote_fetch_branches () {
+	data_source=$(get_data_source "$1")
+	case "$data_source" in
+	builtin)
+	        git-show-ref --heads | sed -n 's,.*[      ]refs/,refs/,p' ;;
+	*)
+		get_remote_default_refs_for_fetch -n "$1" | \
+			sed -e 's/:.*$//g' -e 's/^+//' | sort -u ;;
+	esac
+}
+
 get_remote_refs_for_push () {
 	case "$#" in
 	0) die "internal error: get-remote-refs-for-push." ;;
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 75c000a..9558bdb 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -145,9 +145,15 @@ test_expect_success 'test overriding tracking setup via --no-track' \
      git-config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
      (git-show-ref -q refs/remotes/local/master || git-fetch local) &&
      git-branch --no-track my2 local/master &&
+     git-config branch.autosetupmerge false &&
      ! test $(git-config branch.my2.remote) = local &&
      ! test $(git-config branch.my2.merge) = refs/heads/master'
 
+test_expect_success 'test local tracking setup' \
+    'git branch --track my6 s &&
+     test $(git-config branch.my6.remote) = . &&
+     test $(git-config branch.my6.merge) = refs/heads/s'
+
 # Keep this test last, as it changes the current branch
 cat >expect <<EOF
 0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000	branch: Created from master
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 7eb3783..c424e5b 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -29,5 +29,18 @@ test_expect_success 'checking the results' '
 	diff file cloned/file
 '
 
+test_expect_success 'test . as a remote' '
+
+	git branch copy master &&
+	git config branch.copy.remote . &&
+	git config branch.copy.merge refs/heads/master &&
+	echo updated >file &&
+	git commit -a -m updated &&
+	git checkout copy &&
+	test `cat file` = file &&
+	git pull &&
+	test `cat file` = updated
+'
+
 test_done
 

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH, 2nd version] git-fetch, git-branch: Support local --track via a special remote `.'
  2007-03-12 17:14 [PATCH, 2nd version] git-fetch, git-branch: Support local --track via a special remote `.' Paolo Bonzini
@ 2007-03-13  9:29 ` Junio C Hamano
  2007-03-13 12:29   ` [PATCH, fixed " Paolo Bonzini
  0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2007-03-13  9:29 UTC (permalink / raw
  To: bonzini; +Cc: git

Paolo Bonzini <paolo.bonzini@lu.unisi.ch> writes:

> 	I hope this is what you meant in your reply to my message.

Almost, except I wouldn't have made this part of fetch_native()
like this:

> diff --git a/git-fetch.sh b/git-fetch.sh
> index b9d7a75..e2a6878 100755
> --- a/git-fetch.sh
> +++ b/git-fetch.sh
> @@ -164,6 +164,12 @@ then
>  fi
>  
>  fetch_native () {
> +  if test "$(get_data_source $remote_nick)" = builtin; then
> +    for name in $(get_remote_fetch_branches "$remote_nick"); do
> +      append_fetch_head $(git-rev-parse "$name") . "$name" "$name" || exit
> +    done
> +    return
> +  fi
>  
>    eval=$(echo "$1" | git-fetch--tool parse-reflist "-")
>    eval "$eval"

but probably would have created another sub, fetch_fake.

> 	I removed completely the configuration variable since it made
> 	no sense to me, either.

I think that is sensible.

Currently the patch is parked at the tip of 'pu' after merging
all the other topics, as the test t9101 seems to expose breakage
in "git pull . remotes/git-svn".

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH, fixed version] git-fetch, git-branch: Support local --track via a special remote `.'
  2007-03-13  9:29 ` Junio C Hamano
@ 2007-03-13 12:29   ` Paolo Bonzini
  2007-03-13 16:24     ` Santi Béjar
  2007-03-14 11:20     ` Junio C Hamano
  0 siblings, 2 replies; 6+ messages in thread
From: Paolo Bonzini @ 2007-03-13 12:29 UTC (permalink / raw
  To: Junio C Hamano; +Cc: bonzini, git

This patch on top of next adds support for a dummy remote `.' to
avoid having to declare a fake remote like

	[remote "local"]
		url = .
		fetch = refs/heads/*:refs/heads/*

Such a builtin remote simplifies the operation of "git-fetch", which
will populate FETCH_HEAD but will not pretend that two repositories are
in use, will not create a thin pack, and will not perform any useless
remapping of names.  The speed improvement is around 20%, and it should
improve more if "git-fetch" is converted to a builtin.

To this end, git-parse-remote is grown with a new kind of remote, `builtin'.
In git-fetch.sh, we treat the builtin remote specially in that it needs no
pack/store operations.  In fact, doing git-fetch on a builtin remote will
simply populate FETCH_HEAD appropriately.

The patch also improves of the --track/--no-track support, extending
it so that branch.<name>.remote items referring `.' can be created.
Finally, it fixes a typo in git-checkout.sh.

The patch was tested including the git-svn tests and has no regression.

Signed-off-by: Paolo Bonzini  <bonzini@gnu.org>
---
 Documentation/config.txt |    4 ++++
 builtin-branch.c         |   39 +++++++++++++++++++++++++--------------
 git-checkout.sh          |    2 +-
 git-fetch.sh             |   30 +++++++++++++++++++-----------
 git-parse-remote.sh      |   22 +++++++++++++++++++++-
 t/t3200-branch.sh        |    6 ++++++
 t/t5520-pull.sh          |   13 +++++++++++++
 t/t9109-git-svn-pull.sh  |   31 +++++++++++++++++++++++++++++++
 8 files changed, 120 insertions(+), 27 deletions(-)

	The failure, which I didn't see because I didn't have svn-perl
	bindings installed, was caused by my usage of "git-show-ref --heads"
	where I should have used plain "git-show-ref".

	I include a smaller testcase for the same problem, t9109.

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5408dd6..28899d9 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -272,6 +272,10 @@ branch.<name>.merge::
 	`git fetch`) to lookup the default branch for merging. Without
 	this option, `git pull` defaults to merge the first refspec fetched.
 	Specify multiple values to get an octopus merge.
+	If you wish to setup `git pull` so that it merges into <name> from
+	another branch in the local repository, you can point
+	branch.<name>.merge to the desired branch, and use the special setting
+	`.` (a period) for branch.<name>.remote.
 
 color.branch::
 	A boolean to enable/disable color in the output of
diff --git a/builtin-branch.c b/builtin-branch.c
index 42b1ff1..14c4219 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -372,9 +372,26 @@ static int get_remote_config(const char *key, const char *value)
 	return 0;
 }
 
-static void set_branch_defaults(const char *name, const char *real_ref)
+static void set_branch_merge (const char *name, const char *config_remote,
+			      const char *config_repo)
 {
 	char key[1024];
+	if (sizeof(key) <=
+	    snprintf(key, sizeof(key), "branch.%s.remote", name))
+		die("what a long branch name you have!");
+	git_config_set(key, config_remote);
+
+	/*
+	 * We do not have to check if we have enough space for
+	 * the 'merge' key, since it's shorter than the
+	 * previous 'remote' key, which we already checked.
+	 */
+	snprintf(key, sizeof(key), "branch.%s.merge", name);
+	git_config_set(key, config_repo);
+}
+
+static void set_branch_defaults(const char *name, const char *real_ref)
+{
 	const char *slash = strrchr(real_ref, '/');
 
 	if (!slash)
@@ -384,21 +401,15 @@ static void set_branch_defaults(const char *name, const char *real_ref)
 	start_len = strlen(real_ref);
 	base_len = slash - real_ref;
 	git_config(get_remote_config);
+	if (!config_repo && !config_remote &&
+	    !prefixcmp (real_ref, "refs/heads/")) {
+		set_branch_merge (name, ".", real_ref);
+		printf("Branch %s set up to track local branch %s.\n",
+		       name, real_ref);
+	}
 
 	if (config_repo && config_remote) {
-		if (sizeof(key) <=
-		    snprintf(key, sizeof(key), "branch.%s.remote", name))
-			die("what a long branch name you have!");
-		git_config_set(key, config_remote);
-
-		/*
-		 * We do not have to check if we have enough space for
-		 * the 'merge' key, since it's shorter than the
-		 * previous 'remote' key, which we already checked.
-		 */
-		snprintf(key, sizeof(key), "branch.%s.merge", name);
-		git_config_set(key, config_repo);
-
+		set_branch_merge (name, config_remote, config_repo);
 		printf("Branch %s set up to track remote branch %s.\n",
 		       name, real_ref);
 	}
diff --git a/git-checkout.sh b/git-checkout.sh
index 6caa9fd..b292ff0 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -89,7 +89,7 @@ while [ "$#" != "0" ]; do
     esac
 done
 
-case "$new_branch,$track" in
+case "$newbranch,$track" in
 ,--*)
 	die "git checkout: --track and --no-track require -b"
 esac
diff --git a/git-fetch.sh b/git-fetch.sh
index b9d7a75..f06fa59 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -163,8 +163,13 @@ then
 	fi
 fi
 
-fetch_native () {
+fetch_builtin () {
+    for name in $(get_remote_fetch_branches "$remote_nick"); do
+      append_fetch_head $(git-rev-parse "$name") . "$name" "$name" || exit
+    done
+}
 
+fetch_native () {
   eval=$(echo "$1" | git-fetch--tool parse-reflist "-")
   eval "$eval"
 
@@ -291,14 +296,18 @@ fetch_dumb () {
 }
 
 fetch_main () {
-	case "$remote" in
-	http://* | https://* | ftp://* | rsync://* )
-		fetch_dumb "$@"
-		;;
-	*)
-		fetch_native "$@"
-		;;
-	esac
+	if test "$(get_data_source $remote_nick)" = builtin; then
+		fetch_builtin "$@"
+	else
+		case "$remote" in
+		http://* | https://* | ftp://* | rsync://* )
+			fetch_dumb "$@"
+			;;
+		*)
+			fetch_native "$@"
+			;;
+		esac
+	fi
 }
 
 fetch_main "$reflist" || exit
@@ -353,8 +362,7 @@ case ",$#,$remote_nick," in
 	curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
 	merge_branches=$(git-config \
 		--get-all "branch.${curr_branch}.merge" | sort -u)
-	fetch_branches=$(get_remote_default_refs_for_fetch -n $remote_nick |
-		sed -e 's/:.*$//g' -e 's/^+//' | sort -u)
+	fetch_branches=$(get_remote_fetch_branches $remote_nick)
 	test -n "$merge_branches" && test -n "$fetch_branches" &&
 	merge_branches=$(printf '%s\n%s' "$merge_branches" "$fetch_branches" |
 		sort | uniq -d)
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 99e7184..4964810 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -9,6 +9,9 @@ get_data_source () {
 	*/*)
 		echo ''
 		;;
+	.)
+		echo builtin
+		;;
 	*)
 		if test "$(git-config --get "remote.$1.url")"
 		then
@@ -31,6 +34,9 @@ get_remote_url () {
 	'')
 		echo "$1"
 		;;
+	builtin)
+		echo "$1"
+		;;
 	config)
 		git-config --get "remote.$1.url"
 		;;
@@ -57,7 +63,7 @@ get_default_remote () {
 get_remote_default_refs_for_push () {
 	data_source=$(get_data_source "$1")
 	case "$data_source" in
-	'' | branches)
+	'' | branches | builtin)
 		;; # no default push mapping, just send matching refs.
 	config)
 		git-config --get-all "remote.$1.push" ;;
@@ -128,6 +134,8 @@ get_remote_default_refs_for_fetch () {
 	case "$data_source" in
 	'')
 		set explicit "HEAD:" ;;
+	builtin)
+		set explicit ;;
 	config)
 		set $(expand_refs_wildcard "$1" \
 			$(git-config --get-all "remote.$1.fetch")) ;;
@@ -154,6 +162,18 @@ get_remote_default_refs_for_fetch () {
 	fi
 }
 
+# Returns list of sources
+get_remote_fetch_branches () {
+	data_source=$(get_data_source "$1")
+	case "$data_source" in
+	builtin)
+	        git-show-ref | sed -n 's,.*[      ]refs/,refs/,p' ;;
+	*)
+		get_remote_default_refs_for_fetch -n "$1" | \
+			sed -e 's/:.*$//g' -e 's/^+//' | sort -u ;;
+	esac
+}
+
 get_remote_refs_for_push () {
 	case "$#" in
 	0) die "internal error: get-remote-refs-for-push." ;;
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 75c000a..9558bdb 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -145,9 +145,15 @@ test_expect_success 'test overriding tracking setup via --no-track' \
      git-config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
      (git-show-ref -q refs/remotes/local/master || git-fetch local) &&
      git-branch --no-track my2 local/master &&
+     git-config branch.autosetupmerge false &&
      ! test $(git-config branch.my2.remote) = local &&
      ! test $(git-config branch.my2.merge) = refs/heads/master'
 
+test_expect_success 'test local tracking setup' \
+    'git branch --track my6 s &&
+     test $(git-config branch.my6.remote) = . &&
+     test $(git-config branch.my6.merge) = refs/heads/s'
+
 # Keep this test last, as it changes the current branch
 cat >expect <<EOF
 0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000	branch: Created from master
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 7eb3783..c424e5b 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -29,5 +29,18 @@ test_expect_success 'checking the results' '
 	diff file cloned/file
 '
 
+test_expect_success 'test . as a remote' '
+
+	git branch copy master &&
+	git config branch.copy.remote . &&
+	git config branch.copy.merge refs/heads/master &&
+	echo updated >file &&
+	git commit -a -m updated &&
+	git checkout copy &&
+	test `cat file` = file &&
+	git pull &&
+	test `cat file` = updated
+'
+
 test_done
 
diff --git a/t/t9109-git-svn-pull.sh b/t/t9109-git-svn-pull.sh
new file mode 100755
index 0000000..4d59f60
--- /dev/null
+++ b/t/t9109-git-svn-pull.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Paolo Bonzini
+#
+
+test_description='git-svn pull test'
+. ./lib-git-svn.sh
+
+mkdir import
+
+cd import
+	echo Hello World > motd
+	svn import -m 'import for git-svn' . "$svnrepo" >/dev/null
+cd ..
+
+test_expect_success 'initialize git-svn and fetch' "
+	git-svn init $svnrepo
+	git-svn fetch"
+
+svn co $svnrepo test_wc > /dev/null
+cd test_wc
+	echo Goodbye World > motd
+	svn commit -m "another svn commit" > /dev/null
+cd ..
+
+test_expect_success 'fetch and pull latest from svn' \
+	'git-svn fetch &&
+	 git pull . remotes/git-svn &&
+	 grep Goodbye motd'
+
+test_done

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH, fixed version] git-fetch, git-branch: Support local --track via a special remote `.'
  2007-03-13 12:29   ` [PATCH, fixed " Paolo Bonzini
@ 2007-03-13 16:24     ` Santi Béjar
  2007-03-14 11:20     ` Junio C Hamano
  1 sibling, 0 replies; 6+ messages in thread
From: Santi Béjar @ 2007-03-13 16:24 UTC (permalink / raw
  To: bonzini; +Cc: Junio C Hamano, git

Paolo Bonzini <paolo.bonzini@lu.unisi.ch> writes:

I've done it different, please see the mail:

Subject: [PATCH 2/3] git-fetch: Support the local remote "."

I've done it only modifying git-parse-remote.

[...]

>
> 	The failure, which I didn't see because I didn't have svn-perl
> 	bindings installed, was caused by my usage of "git-show-ref --heads"
> 	where I should have used plain "git-show-ref".

But it should be test in t5515. I've added tests for this.

Thanks,

  Santi

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH, fixed version] git-fetch, git-branch: Support local --track via a special remote `.'
  2007-03-13 12:29   ` [PATCH, fixed " Paolo Bonzini
  2007-03-13 16:24     ` Santi Béjar
@ 2007-03-14 11:20     ` Junio C Hamano
  2007-03-14 12:52       ` [PATCH, respin] " Paolo Bonzini
  1 sibling, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2007-03-14 11:20 UTC (permalink / raw
  To: bonzini; +Cc: git

Paolo Bonzini <paolo.bonzini@lu.unisi.ch> writes:

>  t/t9109-git-svn-pull.sh  |   31 +++++++++++++++++++++++++++++++
>  8 files changed, 120 insertions(+), 27 deletions(-)
>
> 	The failure, which I didn't see because I didn't have svn-perl
> 	bindings installed, was caused by my usage of "git-show-ref --heads"
> 	where I should have used plain "git-show-ref".
>
> 	I include a smaller testcase for the same problem, t9109.

I'd prefer dropping the t9109 test, as it seems to be redundant.
Existing t9101 seems to cover pulling from remote tracking
branch maintained by git-svn already.

Also I'll be reverting a couple of patches from 'next', so this
no longer applies.  Would appreciate a re-spin.

Sorry about that.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH, respin] git-fetch, git-branch: Support local --track via a special remote `.'
  2007-03-14 11:20     ` Junio C Hamano
@ 2007-03-14 12:52       ` Paolo Bonzini
  0 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2007-03-14 12:52 UTC (permalink / raw
  To: Junio C Hamano; +Cc: git

This patch adds support for a dummy remote `.' to avoid having to declare
a fake remote like

        [remote "local"]
                url = .
                fetch = refs/heads/*:refs/heads/*

Such a builtin remote simplifies the operation of "git-fetch", which
will populate FETCH_HEAD but will not pretend that two repositories are
in use, will not create a thin pack, and will not perform any useless
remapping of names.  The speed improvement is around 20%, and it should
improve more if "git-fetch" is converted to a builtin.

To this end, git-parse-remote is grown with a new kind of remote, `builtin'.
In git-fetch.sh, we treat the builtin remote specially in that it needs no
pack/store operations.  In fact, doing git-fetch on a builtin remote will
simply populate FETCH_HEAD appropriately.

The patch also improves of the --track/--no-track support, extending
it so that branch.<name>.remote items referring `.' can be created.
Finally, it fixes a typo in git-checkout.sh.

Signed-off-by: Paolo Bonzini  <bonzini@gnu.org>
---
 Documentation/config.txt |    4 ++++
 builtin-branch.c         |   39 +++++++++++++++++++++++++--------------
 git-checkout.sh          |    2 +-
 git-fetch.sh             |   28 ++++++++++++++++++++--------
 git-parse-remote.sh      |   12 ++++++++++--
 t/t3200-branch.sh        |    6 ++++++
 t/t5520-pull.sh          |   13 +++++++++++++
 7 files changed, 79 insertions(+), 25 deletions(-)

	> I'd prefer dropping the t9109 test, as it seems to be redundant.

	As you wish.

	> Also I'll be reverting a couple of patches from 'next', so this
	> no longer applies.  Would appreciate a re-spin.
	> 
	> Sorry about that.

	No problem.

	I must say that from a clarity point of view I preferred the
	older code.  It did encapsulate fetching in a pretty easy to
	understand way.  OTOH, my patch is smaller now.

	Just my 0.02 cents, or something to remember once the
	git-fetch--tool conversion proceeds and possibly the merge logic
	is written in C.


diff --git a/Documentation/config.txt b/Documentation/config.txt
index aaae9ac..953acae 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -272,6 +272,10 @@ branch.<name>.merge::
 	`git fetch`) to lookup the default branch for merging. Without
 	this option, `git pull` defaults to merge the first refspec fetched.
 	Specify multiple values to get an octopus merge.
+	If you wish to setup `git pull` so that it merges into <name> from
+	another branch in the local repository, you can point
+	branch.<name>.merge to the desired branch, and use the special setting
+	`.` (a period) for branch.<name>.remote.
 
 color.branch::
 	A boolean to enable/disable color in the output of
diff --git a/builtin-branch.c b/builtin-branch.c
index 42b1ff1..14c4219 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -372,9 +372,26 @@ static int get_remote_config(const char *key, const char *value)
 	return 0;
 }
 
-static void set_branch_defaults(const char *name, const char *real_ref)
+static void set_branch_merge(const char *name, const char *config_remote,
+			     const char *config_repo)
 {
 	char key[1024];
+	if (sizeof(key) <=
+	    snprintf(key, sizeof(key), "branch.%s.remote", name))
+		die("what a long branch name you have!");
+	git_config_set(key, config_remote);
+
+	/*
+	 * We do not have to check if we have enough space for
+	 * the 'merge' key, since it's shorter than the
+	 * previous 'remote' key, which we already checked.
+	 */
+	snprintf(key, sizeof(key), "branch.%s.merge", name);
+	git_config_set(key, config_repo);
+}
+
+static void set_branch_defaults(const char *name, const char *real_ref)
+{
 	const char *slash = strrchr(real_ref, '/');
 
 	if (!slash)
@@ -384,21 +401,15 @@ static void set_branch_defaults(const char *name, const char *real_ref)
 	start_len = strlen(real_ref);
 	base_len = slash - real_ref;
 	git_config(get_remote_config);
+	if (!config_repo && !config_remote &&
+	    !prefixcmp(real_ref, "refs/heads/")) {
+		set_branch_merge(name, ".", real_ref);
+		printf("Branch %s set up to track local branch %s.\n",
+		       name, real_ref);
+	}
 
 	if (config_repo && config_remote) {
-		if (sizeof(key) <=
-		    snprintf(key, sizeof(key), "branch.%s.remote", name))
-			die("what a long branch name you have!");
-		git_config_set(key, config_remote);
-
-		/*
-		 * We do not have to check if we have enough space for
-		 * the 'merge' key, since it's shorter than the
-		 * previous 'remote' key, which we already checked.
-		 */
-		snprintf(key, sizeof(key), "branch.%s.merge", name);
-		git_config_set(key, config_repo);
-
+		set_branch_merge(name, config_remote, config_repo);
 		printf("Branch %s set up to track remote branch %s.\n",
 		       name, real_ref);
 	}
diff --git a/git-checkout.sh b/git-checkout.sh
index 6caa9fd..b292ff0 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -89,7 +89,7 @@ while [ "$#" != "0" ]; do
     esac
 done
 
-case "$new_branch,$track" in
+case "$newbranch,$track" in
 ,--*)
 	die "git checkout: --track and --no-track require -b"
 esac
diff --git a/git-fetch.sh b/git-fetch.sh
index ebe6c33..88bf64d 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -161,6 +161,14 @@ then
 	fi
 fi
 
+fetch_builtin () {
+    for ref in $(get_remote_default_refs_for_fetch "$remote_nick"); do
+      name=$(expr "z$ref" : 'z\([^:]*\):')
+      append_fetch_head $(git-rev-parse "$name") "$remote" \
+	  "$name" "$remote_nick" "$name" "" || exit
+    done
+}
+
 fetch_native () {
   eval=$(echo "$1" | git-fetch--tool parse-reflist "-")
   eval "$eval"
@@ -296,14 +303,18 @@ fetch_dumb () {
 }
 
 fetch_main () {
-	case "$remote" in
-	http://* | https://* | ftp://* | rsync://* )
-		fetch_dumb "$@"
-		;;
-	*)
-		fetch_native "$@"
-		;;
-	esac
+	if test "$(get_data_source $remote_nick)" = builtin; then
+		fetch_builtin
+	else
+		case "$remote" in
+		http://* | https://* | ftp://* | rsync://* )
+			fetch_dumb "$@"
+			;;
+		*)
+			fetch_native "$@"
+			;;
+		esac
+	fi
 }
 
 fetch_main "$reflist" || exit
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index c46131f..1b96ec6 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -9,6 +9,9 @@ get_data_source () {
 	*/*)
 		echo ''
 		;;
+	.)
+		echo builtin
+		;;
 	*)
 		if test "$(git-config --get "remote.$1.url")"
 		then
@@ -31,6 +34,9 @@ get_remote_url () {
 	'')
 		echo "$1"
 		;;
+	builtin)
+		echo "$1"
+		;;
 	config)
 		git-config --get "remote.$1.url"
 		;;
@@ -57,7 +63,7 @@ get_default_remote () {
 get_remote_default_refs_for_push () {
 	data_source=$(get_data_source "$1")
 	case "$data_source" in
-	'' | branches)
+	'' | branches | builtin)
 		;; # no default push mapping, just send matching refs.
 	config)
 		git-config --get-all "remote.$1.push" ;;
@@ -163,6 +169,8 @@ get_remote_default_refs_for_fetch () {
 	case "$data_source" in
 	'')
 		echo "HEAD:" ;;
+	builtin)
+	        git-show-ref | sed -n 's,.*[      ]\(refs/.*\),\1:,p' ;;
 	config)
 		canon_refs_list_for_fetch -d "$1" \
 			$(git-config --get-all "remote.$1.fetch") ;;
@@ -177,7 +185,7 @@ get_remote_default_refs_for_fetch () {
 					}' "$GIT_DIR/remotes/$1")
 		;;
 	*)
-		die "internal error: get-remote-default-ref-for-push $1" ;;
+		die "internal error: get-remote-default-ref-for-fetch $1" ;;
 	esac
 }
 
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 75c000a..9558bdb 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -145,9 +145,15 @@ test_expect_success 'test overriding tracking setup via --no-track' \
      git-config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
      (git-show-ref -q refs/remotes/local/master || git-fetch local) &&
      git-branch --no-track my2 local/master &&
+     git-config branch.autosetupmerge false &&
      ! test $(git-config branch.my2.remote) = local &&
      ! test $(git-config branch.my2.merge) = refs/heads/master'
 
+test_expect_success 'test local tracking setup' \
+    'git branch --track my6 s &&
+     test $(git-config branch.my6.remote) = . &&
+     test $(git-config branch.my6.merge) = refs/heads/s'
+
 # Keep this test last, as it changes the current branch
 cat >expect <<EOF
 0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000	branch: Created from master
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 7eb3783..c424e5b 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -29,5 +29,17 @@ test_expect_success 'checking the results' '
 	diff file cloned/file
 '
 
+test_expect_success 'test . as a remote' '
+	git branch copy master &&
+	git config branch.copy.remote . &&
+	git config branch.copy.merge refs/heads/master &&
+	echo updated >file &&
+	git commit -a -m updated &&
+	git checkout copy &&
+	test `cat file` = file &&
+	git pull &&
+	test `cat file` = updated
+'
+
 test_done
 

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2007-03-14 12:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-12 17:14 [PATCH, 2nd version] git-fetch, git-branch: Support local --track via a special remote `.' Paolo Bonzini
2007-03-13  9:29 ` Junio C Hamano
2007-03-13 12:29   ` [PATCH, fixed " Paolo Bonzini
2007-03-13 16:24     ` Santi Béjar
2007-03-14 11:20     ` Junio C Hamano
2007-03-14 12:52       ` [PATCH, respin] " Paolo Bonzini

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).