From 05dd8e2ee2ecba1b4ef1dbbde5c81281152604b4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 25 Sep 2005 22:54:23 -0700 Subject: [PATCH] Fix default pull not to do an unintended Octopus. The refspecs specified in the .git/remotes/ on the "Pull: " lines are for fetching multiple heads in one go, but most of the time making an Octopus out of them is not what is wanted. Make git-fetch leave the marker in .git/FETCH_HEAD file so that later stages can tell which heads are for merging and which are not. Tom Prince made me realize how stupid the original behaviour was. Signed-off-by: Junio C Hamano --- git-fetch.sh | 32 ++++++++++++++++++++++++++++---- git-fmt-merge-msg.perl | 4 +++- git-parse-remote.sh | 11 +++++++++-- git-pull.sh | 4 +++- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/git-fetch.sh b/git-fetch.sh index e4a6a6805..82d897231 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -54,6 +54,10 @@ 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 @@ -78,10 +82,11 @@ append_fetch_head () { if git-cat-file commit "$head_" >/dev/null 2>&1 then headc_=$(git-rev-parse --verify "$head_^0") || exit - echo "$headc_ $note_" >>$GIT_DIR/FETCH_HEAD + echo "$headc_ $not_for_merge_ $note_" >>$GIT_DIR/FETCH_HEAD echo >&2 "* committish: $head_" echo >&2 " $note_" else + echo "$head_ not-for-merge $note_" >>$GIT_DIR/FETCH_HEAD echo >&2 "* non-commit: $head_" echo >&2 " $note_" fi @@ -157,6 +162,13 @@ do # These are relative path from $GIT_DIR, typically starting at refs/ # but may be HEAD + if expr "$ref" : '\.' >/dev/null + then + not_for_merge=t + ref=$(expr "$ref" : '\.\(.*\)') + else + not_for_merge= + fi if expr "$ref" : '\+' >/dev/null then single_force=t @@ -216,7 +228,8 @@ do continue ;; esac - append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name" + append_fetch_head "$head" "$remote" \ + "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" done @@ -241,16 +254,27 @@ http://* | https://* | rsync://* ) 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 "$found" : '[^:]*:\(.*\)') - append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name" + append_fetch_head "$sha1" "$remote" \ + "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" done || exit ;; esac diff --git a/git-fmt-merge-msg.perl b/git-fmt-merge-msg.perl index f0f3100eb..778388e25 100755 --- a/git-fmt-merge-msg.perl +++ b/git-fmt-merge-msg.perl @@ -31,6 +31,8 @@ while (<>) { my ($bname, $tname, $gname, $src); chomp; s/^[0-9a-f]* //; + next if (/^not-for-merge/); + s/^ //; if (s/ of (.*)$//) { $src = $1; } else { @@ -86,7 +88,7 @@ for my $src (@src) { $src{$src}{GENERIC}); my $this = join(', ', @this); if ($src ne '.') { - $this .= " from $src"; + $this .= " of $src"; } push @msg, $this; } diff --git a/git-parse-remote.sh b/git-parse-remote.sh index a9db0cd82..4d8a572a9 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -65,8 +65,11 @@ get_remote_default_refs_for_push () { esac } -# Subroutine to canonicalize remote:local notation +# Subroutine to canonicalize remote:local notation. canon_refs_list_for_fetch () { + # Leave only the first one alone; add prefix . to the rest + # to prevent the secondary branches to be merged by default. + dot_prefix= for ref do force= @@ -91,7 +94,8 @@ canon_refs_list_for_fetch () { heads/* | tags/* ) local="refs/$local" ;; *) local="refs/heads/$local" ;; esac - echo "${force}${remote}:${local}" + echo "${dot_prefix}${force}${remote}:${local}" + dot_prefix=. done } @@ -107,6 +111,9 @@ get_remote_default_refs_for_fetch () { echo "refs/heads/${remote_branch}:refs/heads/$1" ;; remotes) + # This prefixes the second and later default refspecs + # with a '.', to signal git-fetch to mark them + # not-for-merge. canon_refs_list_for_fetch $(sed -ne '/^Pull: */{ s///p }' "$GIT_DIR/remotes/$1") diff --git a/git-pull.sh b/git-pull.sh index e3d11961b..67c7f9562 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -24,7 +24,9 @@ then die "You need to first update your working tree." fi -merge_head=$(sed -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | tr '\012' ' ') +merge_head=$(sed -e '/ not-for-merge /d' \ + -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | \ + tr '\012' ' ') case "$merge_head" in '') -- 2.30.2