Skip to contentSkip to conversation

git-fetch: Only fetch in fetch

PATCH/RFC Santi Béjar 2 participants 4 messages Jun 15, 2016 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

---

Hi *,

I've tried to separate the fetch and merge logic. At the same time it has removed 40 lines of code to the git-*.sh.

What do you think?

Santi

P.D.: I supose it is too late for v1.5.0.

 git-fetch.sh             |   41 +++++++-------------------
 git-parse-remote.sh      |   71 ++++++----------------------------------------
 git-pull.sh              |   40 +++++++++++++++++++++++--
 t/t5510-fetch.sh         |    6 ++--
 t/t6200-fmt-merge-msg.sh |   23 ++++++++++-----
 5 files changed, 74 insertions(+), 107 deletions(-)
git-fetch.sh +11 -30
index 87b940b..564d633 100755
@@ -74,9 +74,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 ;;
@@ -88,6 +88,12 @@ refs=
 rref=
 rsync_slurped_objects=
 
+cat > $GIT_DIR/FETCH_REMOTE <<EOF
+remote: $remote_nick
+url: $remote
+default: $origin
+refspec: $@
+EOF
 if test "" = "$append"
 then
 	: >"$GIT_DIR/FETCH_HEAD"
@@ -103,10 +109,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
@@ -137,10 +139,8 @@ 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"
     fi
+    echo "$headc_	$remote_name	$note_" >>"$GIT_DIR/FETCH_HEAD"
 
     update_local_ref "$local_name_" "$head_" "$note_"
 }
@@ -283,13 +283,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
@@ -370,7 +363,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
 
@@ -413,28 +406,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 ;;
@@ -458,7 +439,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
git-parse-remote.sh +9 -62

122 lines not on this page · raw message

git-pull.sh +36 -4
index a3665d7..cc1295a 100755
@@ -77,9 +77,41 @@ to recover.'
 
 fi
 
-merge_head=$(sed -e '/	not-for-merge	/d' \
-	-e 's/	.*//' "$GIT_DIR"/FETCH_HEAD | \
-	tr '\012' ' ')
+remote=$(grep "^remote: " $GIT_DIR/FETCH_REMOTE)
+remote=${remote#remote: }
+url=$(grep "^url: " $GIT_DIR/FETCH_REMOTE)
+url=${url#url: }
+default=$(grep "^default: " $GIT_DIR/FETCH_REMOTE)
+default=${default#default: }
+refspec=$(grep "^refspec: " $GIT_DIR/FETCH_REMOTE)
+refspec=${refspec#refspec: $remote}
+
+merge_head=
+merge_branches=
+if test ",$remote,$refspec," == ",$default,," ; then
+	curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
+	merge_branches=$(git-repo-config \
+		--get-all "branch.${curr_branch}.merge")
+elif test -n "$refspec" ; then
+	merge_branches=$(for ref in $refspec ; do
+		expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
+		echo " $(expr "z$ref" : 'z\([^:]*\):')"; done)
+elif test "$remote" == "$url" ; then
+	merge_branches=HEAD
+fi
+
+for branch in $merge_branches
+do
+	case "$branch" in
+	HEAD | refs/heads/* | refs/tags/* | refs/remotes/*) ;;
+	heads/* | tags/* | remotes/* ) branch="refs/$branch" ;;
+	*) branch="refs/heads/$branch" ;;
+	esac
+	grep "	$branch	"  "$GIT_DIR"/FETCH_HEAD | \
+		sed -e 's@	'"$branch"'	@		@'
+done > "$GIT_DIR"/FETCH_MERGE
+
+merge_head=$(sed -e 's/	.*//' "$GIT_DIR"/FETCH_MERGE | tr '\012' ' ')
 
 case "$merge_head" in
 '')
@@ -115,6 +147,6 @@ then
 	exit
 fi
 
-merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
+merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_MERGE") || exit
 exec git-merge $no_summary $no_commit $squash $strategy_args \
 	"$merge_name" HEAD $merge_head
t/t5510-fetch.sh +3 -3
index 3ce9446..2e196de 100755
@@ -50,7 +50,7 @@ test_expect_success "fetch test" '
 	test "z$mine" = "z$his"
 '
 
-test_expect_success "fetch test for-merge" '
+test_expect_success "fetch test FETCH_HEAD" '
 	cd "$D" &&
 	cd three &&
 	git fetch &&
@@ -59,8 +59,8 @@ test_expect_success "fetch test for-merge" '
 	master_in_two=`cd ../two && git rev-parse master` &&
 	one_in_two=`cd ../two && git rev-parse one` &&
 	{
-		echo "$master_in_two	not-for-merge"
-		echo "$one_in_two	"
+		echo "$master_in_two	refs/heads/master"
+		echo "$one_in_two	refs/heads/one"
 	} >expected &&
 	cut -f -2 .git/FETCH_HEAD >actual &&
 	diff expected actual'
t/t6200-fmt-merge-msg.sh +15 -8
index 63e49f3..7776823 100755
@@ -77,8 +77,9 @@ test_expect_success 'merge-msg test #1' '
 
 	git checkout master &&
 	git fetch . left &&
-
-	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+	sed -e "s/	.*	/		/" \
+		.git/FETCH_HEAD >.git/FETCH_MERGE &&
+	git fmt-merge-msg <.git/FETCH_MERGE >actual &&
 	diff -u actual expected
 '
 
@@ -90,8 +91,9 @@ test_expect_success 'merge-msg test #2' '
 
 	git checkout master &&
 	git fetch ../trash left &&
-
-	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+	sed -e "s/	.*	/		/" \
+		.git/FETCH_HEAD >.git/FETCH_MERGE &&
+	git fmt-merge-msg <.git/FETCH_MERGE >actual &&
 	diff -u actual expected
 '
 
@@ -113,8 +115,9 @@ test_expect_success 'merge-msg test #3' '
 	git checkout master &&
 	setdate &&
 	git fetch . left &&
-
-	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+	sed -e "s/	.*	/		/" \
+		.git/FETCH_HEAD >.git/FETCH_MERGE &&
+	git fmt-merge-msg <.git/FETCH_MERGE >actual &&
 	diff -u actual expected
 '
 
@@ -143,8 +146,10 @@ test_expect_success 'merge-msg test #4' '
 	git checkout master &&
 	setdate &&
 	git fetch . left right &&
+	sed -e "s/	.*	/		/" \
+		.git/FETCH_HEAD >.git/FETCH_MERGE &&
 
-	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+	git fmt-merge-msg <.git/FETCH_MERGE >actual &&
 	diff -u actual expected
 '
 
@@ -155,8 +160,10 @@ test_expect_success 'merge-msg test #5' '
 	git checkout master &&
 	setdate &&
 	git fetch . left right &&
+	sed -e "s/	.*	/		/" \
+		.git/FETCH_HEAD >.git/FETCH_MERGE &&
 
-	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+	git fmt-merge-msg <.git/FETCH_MERGE >actual &&
 	diff -u actual expected
 '
 
Signature · 1 line
1.5.0.rc2.g7dd4c-dirty
#1 lore raw
Quoted 2 lines · Santi Béjar

I've tried to separate the fetch and merge logic. At the same time it has removed 40 lines of code to the git-*.sh.

Just some words for the basic idea.

git-fetch: fetches the branches from the remote and save this information in .git/FETCH_HEAD. In .git/FETCH_REMOTE it save additional information, as the remote nick, the remote url, the refspec used and the default remote.

git-pull: uses this information to select the branches to merge and save them in .git/FETCH_MERGE.

See you.

Santi

#2 lore raw
Quoted 6 lines · Santi Béjar
Quoted 2 lines · Santi Béjar

I've tried to separate the fetch and merge logic. At the same time it has removed 40 lines of code to the git-*.sh.

Just some words for the basic idea.

Quoted 7 lines

git-fetch: fetches the branches from the remote and save this information in .git/FETCH_HEAD. In .git/FETCH_REMOTE it save additional information, as the remote nick, the remote url, the refspec used and the default remote.

git-pull: uses this information to select the branches to merge and save them in .git/FETCH_MERGE.

One thing I suspect is problematic is that this would make fmt-merge-message much less useful after running git-fetch. You have to go all the way to git-pull and replace reading from FETCH_HEAD with reading from FETCH_MERGE (just like you had to do that in git-pull). In other words, this may break people's scripts and workflows.

This is probably a good clean-up at the conceptual level. If you had done this before v1.0.0 there would have been no question about its inclusion.

Please discuss this patch post 1.5.0.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw

Reply to all :)

Santi

Quoted 6 lines · Santi Béjar
Quoted 3 lines · Junio C Hamano

Please discuss this patch post 1.5.0.

OK. Just a patch that was left in the working directory.