All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Santi Béjar" <sbejar@gmail.com>
To: Git Mailing List <git@vger.kernel.org>
Subject: [PATCH/RFC 2/3] git-fetch: Split fetch and merge logic
Date: Fri, 16 Feb 2007 09:09:30 +0100	[thread overview]
Message-ID: <87vei2o75x.fsf@gmail.com> (raw)
In-Reply-To: <874ppmplw7.fsf@gmail.com> (Santi =?utf-8?Q?B=C3=A9jar's?= message of "Fri, 16 Feb 2007 09:06:00 +0100")


git-fetch fetches the branches from the remote and saves this
information in .git/FETCH_FETCHED, and at the end it generates
the file .git/FETCH_HEAD.

There are two cases where the behaviour is changed:

1) branch.*.merge no longer must exactly match the remote part
   of the branch fetched. Both are expanded in full (as refs/heads/...)
   and matched afterwards.
2) When the remote is specified with $GIT_DIR/branches/... and there is
   a branch.*.merge, the remote branch name must match to get them merged.
   Before the branch in $GIT_DIR/branches/... was always merged.
   In the documentation the $GIT_DIR/branches/ is documented as a
   short-hand for a corresponding file in $GIT_DIR/remotes/, so I think
   this makes the new behaviour consistent.

Signed-off-by: Santi Béjar <sbejar@gmail.com>
---
 Documentation/config.txt |    2 +-
 git-fetch.sh             |   74 ++++++++++++++++++++++++++-------------------
 git-parse-remote.sh      |   60 +++++++++----------------------------
 t/t5510-fetch.sh         |   16 ++++++++++
 4 files changed, 75 insertions(+), 77 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9620126..e695de5 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -238,7 +238,7 @@ branch.<name>.remote::
 
 branch.<name>.merge::
 	When in branch <name>, it tells `git fetch` the default refspec to
-	be marked for merging in FETCH_HEAD. The value has exactly to match
+	be marked for merging in FETCH_HEAD. The value has to match
 	a remote part of one of the refspecs which are fetched from the remote
 	given by "branch.<name>.remote".
 	The merge information is used by `git pull` (which at first calls
diff --git a/git-fetch.sh b/git-fetch.sh
index ca984e7..727538d 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -77,9 +77,9 @@ do
 	shift
 done
 
+origin=$(get_default_remote)
 case "$#" in
 0)
-	origin=$(get_default_remote)
 	test -n "$(get_remote_url ${origin})" ||
 		die "Where do you want to fetch from today?"
 	set x $origin ; shift ;;
@@ -101,6 +101,7 @@ if test "" = "$append"
 then
 	: >"$GIT_DIR/FETCH_HEAD"
 fi
+: >"$GIT_DIR/FETCH_FETCHED"
 
 # Global that is reused later
 ls_remote_result=$(git ls-remote $exec "$remote") ||
@@ -112,10 +113,6 @@ append_fetch_head () {
     remote_name_="$3"
     remote_nick_="$4"
     local_name_="$5"
-    case "$6" in
-    t) not_for_merge_='not-for-merge' ;;
-    '') not_for_merge_= ;;
-    esac
 
     # remote-nick is the URL given on the command line (or a shorthand)
     # remote-name is the $GIT_DIR relative refs/ path we computed
@@ -146,9 +143,7 @@ append_fetch_head () {
     if git-cat-file commit "$head_" >/dev/null 2>&1
     then
 	headc_=$(git-rev-parse --verify "$head_^0") || exit
-	echo "$headc_	$not_for_merge_	$note_" >>"$GIT_DIR/FETCH_HEAD"
-    else
-	echo "$head_	not-for-merge	$note_" >>"$GIT_DIR/FETCH_HEAD"
+	echo "$headc_	$remote_name_:$local_name_	$note_" >>"$GIT_DIR/FETCH_FETCHED"
     fi
 
     update_local_ref "$local_name_" "$head_" "$note_"
@@ -256,7 +251,7 @@ then
 		  git-show-ref --exclude-existing=refs/tags/ |
 	          while read sha1 name
 		  do
-			echo ".${name}:${name}"
+			echo "${name}:${name}"
 		  done` || exit
 	if test "$#" -gt 1
 	then
@@ -279,13 +274,6 @@ fetch_main () {
 
       # These are relative path from $GIT_DIR, typically starting at refs/
       # but may be HEAD
-      if expr "z$ref" : 'z\.' >/dev/null
-      then
-	  not_for_merge=t
-	  ref=$(expr "z$ref" : 'z\.\(.*\)')
-      else
-	  not_for_merge=
-      fi
       if expr "z$ref" : 'z+' >/dev/null
       then
 	  single_force=t
@@ -366,7 +354,7 @@ fetch_main () {
       esac
 
       append_fetch_head "$head" "$remote" \
-	  "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" || exit
+	  "$remote_name" "$remote_nick" "$local_name" || exit
 
   done
 
@@ -409,28 +397,16 @@ fetch_main () {
 	      case "$ref" in
 	      +$remote_name:*)
 		  single_force=t
-		  not_for_merge=
-		  found="$ref"
-		  break ;;
-	      .+$remote_name:*)
-		  single_force=t
-		  not_for_merge=t
-		  found="$ref"
-		  break ;;
-	      .$remote_name:*)
-		  not_for_merge=t
 		  found="$ref"
 		  break ;;
 	      $remote_name:*)
-		  not_for_merge=
 		  found="$ref"
 		  break ;;
 	      esac
 	  done
 	  local_name=$(expr "z$found" : 'z[^:]*:\(.*\)')
 	  append_fetch_head "$sha1" "$remote" \
-		  "$remote_name" "$remote_nick" "$local_name" \
-		  "$not_for_merge" || exit
+		  "$remote_name" "$remote_nick" "$local_name" || exit
         done
       )
     ) || exit ;;
@@ -454,7 +430,7 @@ case "$no_tags$tags" in
 		do
 			git-cat-file -t "$sha1" >/dev/null 2>&1 || continue
 			echo >&2 "Auto-following $name"
-			echo ".${name}:${name}"
+			echo "${name}:${name}"
 		done)
 	esac
 	case "$taglist" in
@@ -482,3 +458,39 @@ case "$orig_head" in
 	fi
 	;;
 esac
+
+# Generate $GIT_DIR/FETCH_HEAD
+case ",$#,$remote_nick," in
+,1,$origin,)
+	curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
+	merge_branches=$(git-repo-config \
+		--get-all "branch.${curr_branch}.merge")
+	[ -z "$merge_branches" ] && merge_first=yes;;
+,1,$remote,) merge_branches=HEAD;;
+,1,*)merge_first=yes ;;
+*)
+	shift
+	merge_branches=$(for ref; do
+		expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
+		echo "$(expr "z$ref" : 'z\([^:]*\):')"; done);;
+esac
+
+test "$merge_first" == "yes" &&
+test "$(get_remote_default_refs_for_fetch -t $remote_nick)" != "explicit" &&
+merge_branches= && merge_first=
+
+merge_branches=$(canon_refs_list_for_fetch $merge_branches | sed 's/:.*$//g')
+
+cat "$GIT_DIR"/FETCH_FETCHED | while IFS='	' read sha1 ref note ; do
+	remote_branch=$(expr "z$ref" : 'z\([^:]*\):')
+	for merge_branch in $merge_branches ; do
+		[ "$merge_branch" == "$remote_branch" ] &&
+			echo "$sha1		$note" && continue 2
+	done
+	if ! test "$merge_first" || test "$merge_first" == "done" ; then
+		echo "$sha1	not-for-merge	$note"
+	else
+		echo "$sha1		$note"
+		merge_first=done
+	fi
+done >> "$GIT_DIR/FETCH_HEAD"
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 5208ee6..212b3bc 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -70,8 +70,7 @@ get_remote_default_refs_for_push () {
 	esac
 }
 
-# Called from canon_refs_list_for_fetch -d "$remote", which
-# is called from get_remote_default_refs_for_fetch to grok
+# Called from get_remote_default_refs_for_fetch to grok
 # refspecs that are retrieved from the configuration, but not
 # from get_remote_refs_for_fetch when it deals with refspecs
 # supplied on the command line.  $ls_remote_result has the list
@@ -130,30 +129,6 @@ expand_refs_wildcard () {
 
 # Subroutine to canonicalize remote:local notation.
 canon_refs_list_for_fetch () {
-	# If called from get_remote_default_refs_for_fetch
-	# leave the branches in branch.${curr_branch}.merge alone,
-	# or the first one otherwise; add prefix . to the rest
-	# to prevent the secondary branches to be merged by default.
-	merge_branches=
-	curr_branch=
-	if test "$1" = "-d"
-	then
-		shift ; remote="$1" ; shift
-		set $(expand_refs_wildcard "$remote" "$@")
-		is_explicit="$1"
-		shift
-		if test "$remote" = "$(get_default_remote)"
-		then
-			curr_branch=$(git-symbolic-ref -q HEAD | \
-			    sed -e 's|^refs/heads/||')
-			merge_branches=$(git-config \
-			    --get-all "branch.${curr_branch}.merge")
-		fi
-		if test -z "$merge_branches" && test $is_explicit != explicit
-		then
-			merge_branches=..this.will.never.match.any.ref..
-		fi
-	fi
 	for ref
 	do
 		force=
@@ -166,18 +141,6 @@ canon_refs_list_for_fetch () {
 		expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
 		remote=$(expr "z$ref" : 'z\([^:]*\):')
 		local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
-		dot_prefix=.
-		if test -z "$merge_branches"
-		then
-			merge_branches=$remote
-			dot_prefix=
-		else
-			for merge_branch in $merge_branches
-			do
-			    [ "$remote" = "$merge_branch" ] &&
-			    dot_prefix= && break
-			done
-		fi
 		case "$remote" in
 		'' | HEAD ) remote=HEAD ;;
 		refs/heads/* | refs/tags/* | refs/remotes/*) ;;
@@ -196,32 +159,39 @@ canon_refs_list_for_fetch () {
 		   git-check-ref-format "$local_ref_name" ||
 		   die "* refusing to create funny ref '$local_ref_name' locally"
 		fi
-		echo "${dot_prefix}${force}${remote}:${local}"
+		echo "${force}${remote}:${local}"
 	done
 }
 
 # Returns list of src: (no store), or src:dst (store)
 get_remote_default_refs_for_fetch () {
+	test "$1" == -t && type=yes && shift
 	data_source=$(get_data_source "$1")
 	case "$data_source" in
 	'')
-		echo "HEAD:" ;;
+		set explicit "HEAD:" ;;
 	config)
-		canon_refs_list_for_fetch -d "$1" \
-			$(git-config --get-all "remote.$1.fetch") ;;
+		set $(expand_refs_wildcard "$1" \
+			$(git-repo-config --get-all "remote.$1.fetch")) ;;
 	branches)
 		remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
 		case "$remote_branch" in '') remote_branch=master ;; esac
-		echo "refs/heads/${remote_branch}:refs/heads/$1"
+		set explicit "refs/heads/${remote_branch}:refs/heads/$1"
 		;;
 	remotes)
-		canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
+		set $(expand_refs_wildcard "$1" $(sed -ne '/^Pull: */{
 						s///p
-					}' "$GIT_DIR/remotes/$1")
+					}' "$GIT_DIR/remotes/$1"))
 		;;
 	*)
 		die "internal error: get-remote-default-ref-for-push $1" ;;
 	esac
+	if [ "$type" ] ; then
+		echo $1
+	else
+		shift
+		canon_refs_list_for_fetch "$@"
+	fi
 }
 
 get_remote_refs_for_push () {
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 50c6485..0a19a7d 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -50,6 +50,22 @@ test_expect_success "fetch test" '
 	test "z$mine" = "z$his"
 '
 
+test_expect_success "fetch test fetched" '
+	cd "$D" &&
+	cd three &&
+	git fetch &&
+	test -f .git/refs/heads/two &&
+	test -f .git/refs/heads/one &&
+	master_in_two=`cd ../two && git rev-parse master` &&
+	one_in_two=`cd ../two && git rev-parse one` &&
+	{
+		echo "$master_in_two	refs/heads/master:refs/heads/two"
+		echo "$one_in_two	refs/heads/one:refs/heads/one"
+	} >expected &&
+	cut -f -2 .git/FETCH_FETCHED >actual &&
+	diff expected actual'
+
+
 test_expect_success "fetch test for-merge" '
 	cd "$D" &&
 	cd three &&
-- 
1.5.0.35.gaaba

  reply	other threads:[~2007-02-16  8:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-16  8:06 [PATCH/RFC 0/3] Split fetch and merge logic Santi Béjar
2007-02-16  8:09 ` Santi Béjar [this message]
2007-02-19 20:44   ` [PATCH/RFC 2/3] git-fetch: " Junio C Hamano
2007-02-19 22:13     ` Santi Béjar
2007-02-19 23:27       ` Junio C Hamano
2007-02-20 11:21         ` Santi Béjar
2007-02-16  8:10 ` [PATCH/RFC 3/3] t/t5515: fixes for the separate " Santi Béjar
2007-02-16  8:22 ` [PATCH/RFC 0/3] Split " Junio C Hamano
2007-02-16  8:40   ` Santi Béjar
2007-02-16 20:10     ` Junio C Hamano
2007-02-16 20:30       ` Santi Béjar
2007-02-16 21:14         ` Junio C Hamano
2007-02-19  9:47           ` Santi Béjar
     [not found] ` <87zm7eo78x.fsf@gmail.com>
2007-02-16  8:23   ` [PATCH/RFC 1/3] t/t5515-fetch-merge-logic.sh: Added tests for the merge login in git-fetch Santi Béjar

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=87vei2o75x.fsf@gmail.com \
    --to=sbejar@gmail.com \
    --cc=git@vger.kernel.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.