git-fetch: Split fetch and merge logic
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
@@ -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
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.