All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] request-pull: warn if the remote object is not the same as the local one
@ 2019-05-28 10:15 Paolo Bonzini
  2019-05-28 10:15 ` [PATCH 1/2] request-pull: quote regex metacharacters in local ref Paolo Bonzini
  2019-05-28 10:15 ` [PATCH 2/2] request-pull: warn if the remote object is not the same as the local one Paolo Bonzini
  0 siblings, 2 replies; 3+ messages in thread
From: Paolo Bonzini @ 2019-05-28 10:15 UTC (permalink / raw)
  To: git; +Cc: Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

In some cases, git request-pull might be invoked with remote and
local objects that differ even though they point to the same commit.
For example, the remote object might be a lightweight tag
vs. an annotated tag on the local side, or the user might have
reworded the tag locally and forgotten to push it.

When this happens git-request-pull will not warn, because it only
checks that "git ls-remote" returns an SHA1 that matches the local
commit.  Patch 2 of this series makes git-request-pull remember the tag
object's SHA1 while processing the "git ls-remote" output, so that it
can be matched against the local object.
    
Paolo Bonzini (2):
  request-pull: quote metacharacters in local ref
  request-pull: warn if the remote object is not the same as the local one

 git-request-pull.sh     | 46 ++++++++++++++++++++++-------------
 t/t5150-request-pull.sh | 53 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 17 deletions(-)

-- 
2.21.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] request-pull: quote regex metacharacters in local ref
  2019-05-28 10:15 [PATCH 0/2] request-pull: warn if the remote object is not the same as the local one Paolo Bonzini
@ 2019-05-28 10:15 ` Paolo Bonzini
  2019-05-28 10:15 ` [PATCH 2/2] request-pull: warn if the remote object is not the same as the local one Paolo Bonzini
  1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2019-05-28 10:15 UTC (permalink / raw)
  To: git; +Cc: Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

The local part of the third argument of git-request-pull is used in
a regular expression without quoting it.  Use qr{} and \Q\E to ensure
that e.g. a period in a tag name does not match any character on the
remote side.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 git-request-pull.sh     |  5 ++---
 t/t5150-request-pull.sh | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/git-request-pull.sh b/git-request-pull.sh
index 13c172bd94..0d128be7fd 100755
--- a/git-request-pull.sh
+++ b/git-request-pull.sh
@@ -83,19 +83,18 @@ die "fatal: No commits in common between $base and $head"
 # Otherwise find a random ref that matches $headrev.
 find_matching_ref='
 	my ($head,$headrev) = (@ARGV);
+	my $pattern = qr{/\Q$head\E$};
 	my ($found);
 
 	while (<STDIN>) {
 		chomp;
 		my ($sha1, $ref, $deref) = /^(\S+)\s+([^^]+)(\S*)$/;
-		my ($pattern);
 		next unless ($sha1 eq $headrev);
 
-		$pattern="/$head\$";
 		if ($ref eq $head) {
 			$found = $ref;
 		}
-		if ($ref =~ /$pattern/) {
+		if ($ref =~ $pattern) {
 			$found = $ref;
 		}
 		if ($sha1 eq $head) {
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index fca001eb9b..c1a821a549 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -246,4 +246,22 @@ test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' '
 
 '
 
+test_expect_success 'request-pull quotes regex metacharacters properly' '
+
+	rm -fr downstream.git &&
+	git init --bare downstream.git &&
+	(
+		cd local &&
+		git checkout initial &&
+		git merge --ff-only master &&
+		git tag -mrelease v2.0 &&
+		git push origin refs/tags/v2.0:refs/tags/v2-0 &&
+		test_must_fail git request-pull initial "$downstream_url" tags/v2.0 \
+			2>../err
+	) &&
+	grep "No match for commit .*" err &&
+	grep "Are you sure you pushed" err
+
+'
+
 test_done
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] request-pull: warn if the remote object is not the same as the local one
  2019-05-28 10:15 [PATCH 0/2] request-pull: warn if the remote object is not the same as the local one Paolo Bonzini
  2019-05-28 10:15 ` [PATCH 1/2] request-pull: quote regex metacharacters in local ref Paolo Bonzini
@ 2019-05-28 10:15 ` Paolo Bonzini
  1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2019-05-28 10:15 UTC (permalink / raw)
  To: git; +Cc: Paolo Bonzini

From: Paolo Bonzini <pbonzini@redhat.com>

In some cases, git request-pull might be invoked with remote and
local objects that differ even though they point to the same commit.
For example, the remote object might be a lightweight tag
vs. an annotated tag on the local side; or the user might have
reworded the tag locally and forgotten to push it.

When this happens git-request-pull will not warn, because it only
checks that "git ls-remote" returns an SHA1 that matches the local
commit (known as $headrev in the script).  This patch makes
git-request-pull retrieve the tag object SHA1 while processing
the "git ls-remote" output, so that it can be matched against the
local object.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 git-request-pull.sh     | 43 +++++++++++++++++++++++++++--------------
 t/t5150-request-pull.sh | 35 +++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/git-request-pull.sh b/git-request-pull.sh
index 0d128be7fd..2d0e44656c 100755
--- a/git-request-pull.sh
+++ b/git-request-pull.sh
@@ -65,6 +65,8 @@ test -z "$head" && die "fatal: Not a valid revision: $local"
 headrev=$(git rev-parse --verify --quiet "$head"^0)
 test -z "$headrev" && die "fatal: Ambiguous revision: $local"
 
+local_sha1=$(git rev-parse --verify --quiet "$head")
+
 # Was it a branch with a description?
 branch_name=${head#refs/heads/}
 if test "z$branch_name" = "z$headref" ||
@@ -77,42 +79,53 @@ merge_base=$(git merge-base $baserev $headrev) ||
 die "fatal: No commits in common between $base and $head"
 
 # $head is the refname from the command line.
-# If a ref with the same name as $head exists at the remote
-# and their values match, use that.
-#
-# Otherwise find a random ref that matches $headrev.
+# Find a ref with the same name as $head that exists at the remote
+# and points to the same commit as the local object.
 find_matching_ref='
 	my ($head,$headrev) = (@ARGV);
 	my $pattern = qr{/\Q$head\E$};
-	my ($found);
+	my ($remote_sha1, $found);
 
 	while (<STDIN>) {
 		chomp;
 		my ($sha1, $ref, $deref) = /^(\S+)\s+([^^]+)(\S*)$/;
-		next unless ($sha1 eq $headrev);
 
-		if ($ref eq $head) {
-			$found = $ref;
-		}
-		if ($ref =~ $pattern) {
-			$found = $ref;
-		}
 		if ($sha1 eq $head) {
-			$found = $sha1;
+			$found = $remote_sha1 = $sha1;
+			break;
+		}
+
+		if ($ref eq $head || $ref =~ $pattern) {
+			if ($deref eq "") {
+				# Remember the matching object on the remote side
+				$remote_sha1 = $sha1;
+			}
+			if ($sha1 eq $headrev) {
+				$found = $ref;
+				break;
+			}
 		}
 	}
 	if ($found) {
-		print "$found\n";
+		$remote_sha1 = $headrev if ! defined $remote_sha1;
+		print "$remote_sha1 $found\n";
 	}
 '
 
-ref=$(git ls-remote "$url" | @@PERL@@ -e "$find_matching_ref" "${remote:-HEAD}" "$headrev")
+set fnord $(git ls-remote "$url" | @@PERL@@ -e "$find_matching_ref" "${remote:-HEAD}" "$headrev")
+remote_sha1=$2
+ref=$3
 
 if test -z "$ref"
 then
 	echo "warn: No match for commit $headrev found at $url" >&2
 	echo "warn: Are you sure you pushed '${remote:-HEAD}' there?" >&2
 	status=1
+elif test "$local_sha1" != "$remote_sha1"
+then
+	echo "warn: $head found at $url but points to a different object" >&2
+	echo "warn: Are you sure you pushed '${remote:-HEAD}' there?" >&2
+	status=1
 fi
 
 # Special case: turn "for_linus" to "tags/for_linus" when it is correct
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index c1a821a549..852dcd913f 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -264,4 +264,39 @@ test_expect_success 'request-pull quotes regex metacharacters properly' '
 
 '
 
+test_expect_success 'pull request with mismatched object' '
+
+	rm -fr downstream.git &&
+	git init --bare downstream.git &&
+	(
+		cd local &&
+		git checkout initial &&
+		git merge --ff-only master &&
+		git push origin HEAD:refs/tags/full &&
+		test_must_fail git request-pull initial "$downstream_url" tags/full \
+			2>../err
+	) &&
+	grep "points to a different object" err &&
+	grep "Are you sure you pushed" err
+
+'
+
+test_expect_success 'pull request with stale object' '
+
+	rm -fr downstream.git &&
+	git init --bare downstream.git &&
+	(
+		cd local &&
+		git checkout initial &&
+		git merge --ff-only master &&
+		git push origin refs/tags/full &&
+		git tag -f -m"Thirty-one days" full &&
+		test_must_fail git request-pull initial "$downstream_url" tags/full \
+			2>../err
+	) &&
+	grep "points to a different object" err &&
+	grep "Are you sure you pushed" err
+
+'
+
 test_done
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-05-28 10:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-28 10:15 [PATCH 0/2] request-pull: warn if the remote object is not the same as the local one Paolo Bonzini
2019-05-28 10:15 ` [PATCH 1/2] request-pull: quote regex metacharacters in local ref Paolo Bonzini
2019-05-28 10:15 ` [PATCH 2/2] request-pull: warn if the remote object is not the same as the local one Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.