From 97af7ff0553ed81bb905dbc0c8b0f9a0c10bfb3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santi=20B=C3=A9jar?= Date: Fri, 12 Jun 2009 00:39:18 +0200 Subject: [PATCH 1/3] parse-remote: function to get the tracking branch to be merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only user of get_remote_refs_for_fetch was "git pull --rebase" and it only wanted the tracking branch to be merge. So, add a simple function (get_remote_merge_branch) with this new meaning. No behavior changes. The new function behaves like the old code in "git pull --rebase". In particular, it only works with the default refspec mapping and with remote branches, not tags. Signed-off-by: Santi Béjar Signed-off-by: Junio C Hamano --- git-parse-remote.sh | 29 +++++++++++++++++++++++++++++ git-pull.sh | 7 ++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/git-parse-remote.sh b/git-parse-remote.sh index a29671986..a991564b9 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -229,6 +229,34 @@ get_remote_refs_for_fetch () { esac } +get_remote_merge_branch () { + case "$#" in + 0|1) + die "internal error: get-remote-merge-branch." ;; + *) + repo=$1 + shift + ref=$1 + # FIXME: It should return the tracking branch + # Currently only works with the default mapping + case "$ref" in + +*) + ref=$(expr "z$ref" : 'z+\(.*\)') + ;; + esac + expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:" + remote=$(expr "z$ref" : 'z\([^:]*\):') + case "$remote" in + '' | HEAD ) remote=HEAD ;; + heads/*) remote=${remote#heads/} ;; + refs/heads/*) remote=${remote#refs/heads/} ;; + refs/* | tags/* | remotes/* ) remote= + esac + + [ -n "$remote" ] && echo "refs/remotes/$repo/$remote" + esac +} + resolve_alternates () { # original URL (xxx.git) top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'` @@ -262,3 +290,4 @@ get_uploadpack () { ;; esac } + diff --git a/git-pull.sh b/git-pull.sh index 35261539a..3cf26634a 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -125,12 +125,9 @@ test true = "$rebase" && { die "refusing to pull with rebase: your working tree is not up-to-date" . git-parse-remote && - origin="$1" - test -z "$origin" && origin=$(get_default_remote) - reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null | - sed "s|refs/heads/\(.*\):|\1|")" && + reflist="$(get_remote_merge_branch "$@" 2>/dev/null)" && oldremoteref="$(git rev-parse -q --verify \ - "refs/remotes/$origin/$reflist")" + "$reflist")" } orig_head=$(git rev-parse -q --verify HEAD) git fetch $verbosity --update-head-ok "$@" || exit 1 From e9460a66e0d11b718757cd88eb0c927f2b79e1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santi=20B=C3=A9jar?= Date: Fri, 12 Jun 2009 00:39:19 +0200 Subject: [PATCH 2/3] parse-remote: support default reflist in get_remote_merge_branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expand get_remote_merge_branch to compute the tracking branch to merge when called without arguments (or only the remote name). This allows "git pull --rebase" without arguments (default upstream branch) to work with a rebased upstream. With explicit arguments it already worked. Also add a test to check for this case. Signed-off-by: Santi Béjar Signed-off-by: Junio C Hamano --- git-parse-remote.sh | 8 +++++++- t/t5520-pull.sh | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/git-parse-remote.sh b/git-parse-remote.sh index a991564b9..75e125464 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -232,7 +232,13 @@ get_remote_refs_for_fetch () { get_remote_merge_branch () { case "$#" in 0|1) - die "internal error: get-remote-merge-branch." ;; + origin="$1" + default=$(get_default_remote) + test -z "$origin" && origin=$default + curr_branch=$(git symbolic-ref -q HEAD) + [ "$origin" = "$default" ] && + echo $(git for-each-ref --format='%(upstream)' $curr_branch) + ;; *) repo=$1 shift diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 725771fac..c5a2e66a0 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -92,20 +92,34 @@ test_expect_success '--rebase with rebased upstream' ' git remote add -f me . && git checkout copy && + git tag copy-orig && git reset --hard HEAD^ && echo conflicting modification > file && git commit -m conflict file && git checkout to-rebase && echo file > file2 && git commit -m to-rebase file2 && + git tag to-rebase-orig && git pull --rebase me copy && test "conflicting modification" = "$(cat file)" && test file = $(cat file2) ' +test_expect_success '--rebase with rebased default upstream' ' + + git update-ref refs/remotes/me/copy copy-orig && + git checkout --track -b to-rebase2 me/copy && + git reset --hard to-rebase-orig && + git pull --rebase && + test "conflicting modification" = "$(cat file)" && + test file = $(cat file2) + +' + test_expect_success 'pull --rebase dies early with dirty working directory' ' + git checkout to-rebase && git update-ref refs/remotes/me/copy copy^ && COPY=$(git rev-parse --verify me/copy) && git rebase --onto $COPY copy && From 62d955fd435273dcd9fffed0c0d83bbe90006a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santi=20B=C3=A9jar?= Date: Fri, 12 Jun 2009 00:39:21 +0200 Subject: [PATCH 3/3] parse-remote: remove unused functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Santi Béjar Signed-off-by: Junio C Hamano --- Documentation/git-parse-remote.txt | 20 --- git-parse-remote.sh | 204 ----------------------------- 2 files changed, 224 deletions(-) diff --git a/Documentation/git-parse-remote.txt b/Documentation/git-parse-remote.txt index cd4306987..39d9daa7e 100644 --- a/Documentation/git-parse-remote.txt +++ b/Documentation/git-parse-remote.txt @@ -17,26 +17,6 @@ routines to parse files under $GIT_DIR/remotes/ and $GIT_DIR/branches/ and configuration variables that are related to fetching, pulling and pushing. -The primary entry points are: - -get_remote_refs_for_fetch:: - Given the list of user-supplied ` ...`, - return the list of refs to fetch after canonicalizing - them into `$GIT_DIR` relative paths - (e.g. `refs/heads/foo`). When `...` is empty - the returned list of refs consists of the defaults - for the given ``, if specified in - `$GIT_DIR/remotes/`, `$GIT_DIR/branches/`, or `remote.*.fetch` - configuration. - -get_remote_refs_for_push:: - Given the list of user-supplied ` ...`, - return the list of refs to push in a form suitable to be - fed to the 'git-send-pack' command. When `...` - is empty the returned list of refs consists of the - defaults for the given ``, if specified in - `$GIT_DIR/remotes/`. - Author ------ Written by Junio C Hamano. diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 75e125464..5f47b1814 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -60,175 +60,6 @@ get_default_remote () { echo ${origin:-origin} } -get_remote_default_refs_for_push () { - data_source=$(get_data_source "$1") - case "$data_source" in - '' | branches | self) - ;; # no default push mapping, just send matching refs. - config) - git config --get-all "remote.$1.push" ;; - remotes) - sed -ne '/^Push: */{ - s///p - }' "$GIT_DIR/remotes/$1" ;; - *) - die "internal error: get-remote-default-ref-for-push $1" ;; - esac -} - -# Called from canon_refs_list_for_fetch -d "$remote", which -# is 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 -# of refs available at remote. -# -# The first token returned is either "explicit" or "glob"; this -# is to help prevent randomly "globbed" ref from being chosen as -# a merge candidate -expand_refs_wildcard () { - echo "$ls_remote_result" | - git fetch--tool 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= - case "$ref" in - +*) - ref=$(expr "z$ref" : 'z+\(.*\)') - force=+ - ;; - esac - 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/* | tags/* | remotes/* ) remote="refs/$remote" ;; - *) remote="refs/heads/$remote" ;; - esac - case "$local" in - '') local= ;; - refs/*) ;; - heads/* | tags/* | remotes/* ) local="refs/$local" ;; - *) local="refs/heads/$local" ;; - esac - - if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)') - then - git check-ref-format "$local_ref_name" || - die "* refusing to create funny ref '$local_ref_name' locally" - fi - echo "${dot_prefix}${force}${remote}:${local}" - done -} - -# Returns list of src: (no store), or src:dst (store) -get_remote_default_refs_for_fetch () { - data_source=$(get_data_source "$1") - case "$data_source" in - '') - echo "HEAD:" ;; - self) - canon_refs_list_for_fetch -d "$1" \ - $(git for-each-ref --format='%(refname):') - ;; - config) - canon_refs_list_for_fetch -d "$1" \ - $(git 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" - ;; - remotes) - canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{ - s///p - }' "$GIT_DIR/remotes/$1") - ;; - *) - die "internal error: get-remote-default-ref-for-fetch $1" ;; - esac -} - -get_remote_refs_for_push () { - case "$#" in - 0) die "internal error: get-remote-refs-for-push." ;; - 1) get_remote_default_refs_for_push "$@" ;; - *) shift; echo "$@" ;; - esac -} - -get_remote_refs_for_fetch () { - case "$#" in - 0) - die "internal error: get-remote-refs-for-fetch." ;; - 1) - get_remote_default_refs_for_fetch "$@" ;; - *) - shift - tag_just_seen= - for ref - do - if test "$tag_just_seen" - then - echo "refs/tags/${ref}:refs/tags/${ref}" - tag_just_seen= - continue - else - case "$ref" in - tag) - tag_just_seen=yes - continue - ;; - esac - fi - canon_refs_list_for_fetch "$ref" - done - ;; - esac -} - get_remote_merge_branch () { case "$#" in 0|1) @@ -262,38 +93,3 @@ get_remote_merge_branch () { [ -n "$remote" ] && echo "refs/remotes/$repo/$remote" esac } - -resolve_alternates () { - # original URL (xxx.git) - top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'` - while read path - do - case "$path" in - \#* | '') - continue ;; - /*) - echo "$top_$path/" ;; - ../*) - # relative -- ugly but seems to work. - echo "$1/objects/$path/" ;; - *) - # exit code may not be caught by the reader. - echo "bad alternate: $path" - exit 1 ;; - esac - done -} - -get_uploadpack () { - data_source=$(get_data_source "$1") - case "$data_source" in - config) - uplp=$(git config --get "remote.$1.uploadpack") - echo ${uplp:-git-upload-pack} - ;; - *) - echo "git-upload-pack" - ;; - esac -} -