git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pang Yan Han <pangyanhan@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	"Shawn O. Pearce" <spearce@spearce.org>,
	Jeff King <peff@peff.net>, Sitaram Chamarty <sitaramc@gmail.com>,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	Pang Yan Han <pangyanhan@gmail.com>
Subject: [PATCH/RFC 2/2] receive-pack: Don't run update hook for corrupt or nonexistent ref
Date: Sun, 25 Sep 2011 13:06:22 +0800	[thread overview]
Message-ID: <1316927182-14212-3-git-send-email-pangyanhan@gmail.com> (raw)
In-Reply-To: <1316927182-14212-1-git-send-email-pangyanhan@gmail.com>

Teach receive-pack not to run update hook for a corrupt or nonexistent ref.

In addition, update the warning message for deleting a corrupt or nonexistent
ref from:

"Allowing deletion of corrupt ref"

to:

"Allowing deletion of corrupt/nonexistent ref"

Noticed-by: Sitaram Chamarty <sitaramc@gmail.com>
Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
---
 builtin/receive-pack.c |   50 +++++++++++++++++++++++++++--------------------
 t/t5516-fetch-push.sh  |   33 +++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index ae164da..a9385cf 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -346,6 +346,17 @@ static void refuse_unconfigured_deny_delete_current(void)
 		rp_error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
 }
 
+static const char *delete_null_sha1_ref(const char *namespaced_name,
+										const char *name,
+										unsigned char *old_sha1)
+{
+	if (delete_ref(namespaced_name, old_sha1, 0)) {
+		rp_error("failed to delete %s", name);
+		return "failed to delete";
+	}
+	return NULL; /* good */
+}
+
 static const char *update(struct command *cmd)
 {
 	const char *name = cmd->ref_name;
@@ -438,33 +449,30 @@ static const char *update(struct command *cmd)
 			return "non-fast-forward";
 		}
 	}
+
+	/* Don't run update hook for corrupt/nonexistent ref */
+	if (is_null_sha1(new_sha1) && !parse_object(old_sha1)) {
+		rp_warning("Allowing deletion of corrupt/nonexistent ref.");
+		old_sha1 = NULL;
+		return delete_null_sha1_ref(namespaced_name, name, old_sha1);
+	}
+
 	if (run_update_hook(cmd)) {
 		rp_error("hook declined to update %s", name);
 		return "hook declined";
 	}
 
-	if (is_null_sha1(new_sha1)) {
-		if (!parse_object(old_sha1)) {
-			rp_warning("Allowing deletion of corrupt ref.");
-			old_sha1 = NULL;
-		}
-		if (delete_ref(namespaced_name, old_sha1, 0)) {
-			rp_error("failed to delete %s", name);
-			return "failed to delete";
-		}
-		return NULL; /* good */
-	}
-	else {
-		lock = lock_any_ref_for_update(namespaced_name, old_sha1, 0);
-		if (!lock) {
-			rp_error("failed to lock %s", name);
-			return "failed to lock";
-		}
-		if (write_ref_sha1(lock, new_sha1, "push")) {
-			return "failed to write"; /* error() already called */
-		}
-		return NULL; /* good */
+	if (is_null_sha1(new_sha1))
+		return delete_null_sha1_ref(namespaced_name, name, old_sha1);
+
+	lock = lock_any_ref_for_update(namespaced_name, old_sha1, 0);
+	if (!lock) {
+		rp_error("failed to lock %s", name);
+		return "failed to lock";
 	}
+	if (write_ref_sha1(lock, new_sha1, "push"))
+		return "failed to write"; /* error() already called */
+	return NULL; /* good */
 }
 
 static char update_post_hook[] = "hooks/post-update";
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 3abb290..b7a74e3 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -40,6 +40,20 @@ mk_test () {
 	)
 }
 
+mk_test_with_update_hook () {
+	mk_test "$@" &&
+	(
+		cd testrepo &&
+		mkdir .git/hooks &&
+		cd .git/hooks &&
+		cat >update <<'EOF'
+#!/bin/sh
+printf %s "$@" >>update.args
+EOF
+		chmod u+x update
+	)
+}
+
 mk_child() {
 	rm -rf "$1" &&
 	git clone testrepo "$1"
@@ -559,6 +573,25 @@ test_expect_success 'allow deleting an invalid remote ref' '
 
 '
 
+test_expect_success 'deleting existing ref triggers update hook' '
+	mk_test_with_update_hook heads/master &&
+	(
+	cd testrepo &&
+	git rev-parse --verify refs/heads/master &&
+	git config receive.denyDeleteCurrent warn
+	) &&
+	git push testrepo :refs/heads/master &&
+	(cd testrepo && test_must_fail git rev-parse --verify refs/heads/master) &&
+	(cd testrepo/.git && test -s update.args)
+'
+
+test_expect_success 'deleting nonexistent ref does not trigger update hook' '
+	mk_test_with_update_hook heads/master &&
+	rm -f testrepo/.git/objects/??/* &&
+	git push testrepo :refs/heads/master &&
+	(cd testrepo/.git && ! test -f update.args)
+'
+
 test_expect_success 'allow deleting a ref using --delete' '
 	mk_test heads/master &&
 	(cd testrepo && git config receive.denyDeleteCurrent warn) &&
-- 
1.7.7.rc3.2.g29f2e6

  parent reply	other threads:[~2011-09-25  5:10 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-25  5:06 [PATCH/RFC 0/2] Teach receive-pack not to run update hook for corrupt/non existent ref Pang Yan Han
2011-09-25  5:06 ` [PATCH/RFC 1/2] is_url: Remove redundant assignment Pang Yan Han
2011-09-25  9:26   ` Tay Ray Chuan
2011-09-26 16:52     ` Junio C Hamano
2011-09-26 21:32       ` Jeff King
2011-09-25  5:06 ` Pang Yan Han [this message]
2011-09-25 17:37   ` [PATCH/RFCv2 2/2] run post-receive and post-update hooks with empty stdin/no args for invalid ref deletion Pang Yan Han
2011-09-25  7:58 ` [PATCH/RFC 0/2] Teach receive-pack not to run update hook for corrupt/non existent ref Sitaram Chamarty
2011-09-25  9:48   ` Pang Yan Han
2011-09-25 12:05     ` Sitaram Chamarty
2011-09-26 23:23       ` Junio C Hamano
2011-09-26 23:44         ` Sitaram Chamarty
2011-09-26 23:49           ` Junio C Hamano
2011-09-27  0:04             ` Junio C Hamano
2011-09-27  9:02               ` Pang Yan Han
2011-09-27 16:56                 ` Junio C Hamano
2011-09-27 22:55                   ` Pang Yan Han
2011-09-27  0:05             ` Sitaram Chamarty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1316927182-14212-3-git-send-email-pangyanhan@gmail.com \
    --to=pangyanhan@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    --cc=sitaramc@gmail.com \
    --cc=spearce@spearce.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).