Skip to contentSkip to conversation

git-fetch: Split fetch and merge logic

PATCH In review Santi Béjar 2 participants 2 messages Jun 15, 2016

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 git-fetch: Split fetch and merge logic

It makes git-parse-remote.sh and almost all git-fetch independent of the merge logic.

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

The current merge behaviour is unchanged.

---
Hi *,

I've addressed all the comments, now prepared to even more comments :)

Junio, from your "What's cooking in git.git (topics)" I undestand that the jc/fetch topic is not going to be in next soon (even for the first commit?). Anyway, the simple question is: Which branch (or commit) you want me to base this patch?

 git-fetch.sh        |   80 +++++++++++++++++++++++++++++++-------------------
 git-parse-remote.sh |   65 ++++++++++++-----------------------------
 2 files changed, 68 insertions(+), 77 deletions(-)
git-fetch.sh +49 -31
index d230995..fccfc7d 100755
@@ -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,8 @@ if test "" = "$append"
 then
 	: >"$GIT_DIR/FETCH_HEAD"
 fi
+: >"$GIT_DIR/FETCH_FETCHED"
+trap 'rm -f "$GIT_DIR"/FETCH_FETCHED' 0 1 2 3 15
 
 # Global that is reused later
 ls_remote_result=$(git ls-remote $exec "$remote") ||
@@ -112,10 +114,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 +144,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_"
@@ -265,7 +261,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
@@ -288,13 +284,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
@@ -375,7 +364,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
 
@@ -418,28 +407,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 ;;
@@ -463,7 +440,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
@@ -491,3 +468,44 @@ 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-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)
+	test -n "$merge_branches" && test -n "$fetch_branches" &&
+	merge_branches=$(printf '%s\n%s' "$merge_branches" "$fetch_branches" | sort | uniq -d)
+	[ -z "$merge_branches" ] ||
+	test "$(get_data_source $remote_nick)" = 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')
+
+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_FETCHED >> "$GIT_DIR/FETCH_HEAD"
git-parse-remote.sh +19 -46

107 lines not on this page · raw message

Signature · 1 line
1.5.0.1.576.g78541
#1 lore raw
Quoted 6 lines · Santi Béjar

I've addressed all the comments, now prepared to even more comments :)

Junio, from your "What's cooking in git.git (topics)" I undestand that the jc/fetch topic is not going to be in next soon (even for the first commit?). Anyway, the simple question is: Which branch (or commit) you want me to base this patch?

For now this is fine.

I might have to postpone rebasing jc/fetch on top of this one depending on my workload, but I'd want this clean-up first.

Thanks.