request-pull: update the "pull" command generation logic
authorJunio C Hamano <gitster@pobox.com>
Fri, 16 Dec 2011 17:00:11 +0000 (09:00 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 16 Dec 2011 17:25:20 +0000 (09:25 -0800)
The old code that insisted on asking for the tip of a branch to be pulled
were not updated when we started allowing for a tag to be pulled. When a
tag points at an older part of the history and there is no branch that
points at the tagged commit, the script failed to say which ref is to be
pulled.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-request-pull.sh
t/t5150-request-pull.sh

index c6a5b7a6b38adaafdebb4b0991cc5ee8c14c3796..7b5c777f0b137d9050dfed02eebe78f1a2ebd6c9 100755 (executable)
@@ -57,12 +57,40 @@ headrev=$(git rev-parse --verify "$head"^0) || exit
 merge_base=$(git merge-base $baserev $headrev) ||
 die "fatal: No commits in common between $base and $head"
 
-find_matching_branch="/^$headrev       "'refs\/heads\//{
-       s/^.*   refs\/heads\///
-       p
-       q
-}'
-branch=$(git ls-remote "$url" | sed -n -e "$find_matching_branch")
+# $head is the token given from the command line. If a ref with that
+# name exists at the remote and their values match, we should use it.
+# Otherwise find a ref that matches $headrev.
+find_matching_ref='
+       sub abbr {
+               my $ref = shift;
+               if ($ref =~ s|refs/heads/||) {
+                       return $ref;
+               } elsif ($ref =~ s|refs/tags/||) {
+                       return "tag $ref";
+               } else {
+                       return $ref;
+               }
+       }
+
+       my ($exact, $found);
+       while (<STDIN>) {
+               my ($sha1, $ref, $deref) = /^(\S+)\s+(\S+?)(\^\{\})?$/;
+               next unless ($sha1 eq $ARGV[1]);
+               $found = abbr($ref);
+               if ($ref =~ m|/\Q$ARGV[0]\E$|) {
+                       $exact = $found;
+                       last;
+               }
+       }
+       if ($exact) {
+               print "$exact\n";
+       } elsif ($found) {
+               print "$found\n";
+       }
+'
+
+ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev")
+
 url=$(git ls-remote --get-url "$url")
 
 git show -s --format='The following changes since commit %H:
@@ -71,7 +99,7 @@ git show -s --format='The following changes since commit %H:
 
 are available in the git repository at:
 ' $baserev &&
-echo "  $url${branch+ $branch}" &&
+echo "  $url${ref+ $ref}" &&
 git show -s --format='
 for you to fetch changes up to %H:
 
@@ -81,7 +109,7 @@ for you to fetch changes up to %H:
 
 if test -n "$branch_name"
 then
-       echo "(from the branch description for $branch local branch)"
+       echo "(from the branch description for $branch_name local branch)"
        echo
        git config "branch.$branch_name.description"
 fi &&
@@ -101,7 +129,7 @@ fi &&
 git shortlog ^$baserev $headrev &&
 git diff -M --stat --summary $patch $merge_base..$headrev || status=1
 
-if test -z "$branch"
+if test -z "$ref"
 then
        echo "warn: No branch of $url is at:" >&2
        git show -s --format='warn:   %h: %s' $headrev >&2
index ea6f692bafa9f2c4f81985a50ed79a1c5016b493..aec842fa33707308c24c340eca7367e8aaf5c20f 100755 (executable)
@@ -67,9 +67,11 @@ test_expect_success 'setup: two scripts for reading pull requests' '
 
        cat <<-\EOT >read-request.sed &&
        #!/bin/sed -nf
+       # Note that a request could ask for "tag $tagname"
        / in the git repository at:$/!d
        n
        /^$/ n
+       s/ tag \([^ ]*\)$/ tag--\1/
        s/^[    ]*\(.*\) \([^ ]*\)/please pull\
        \1\
        \2/p
@@ -178,6 +180,7 @@ test_expect_success 'request names an appropriate branch' '
                read branch
        } <digest &&
        {
+               test "$branch" = tag--full ||
                test "$branch" = master ||
                test "$branch" = for-upstream
        }