git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/5] Improve test coverage of update-ref error messages
@ 2016-06-07 11:50 Michael Haggerty
  2016-06-07 11:50 ` [PATCH 1/5] t1404: rename file to t1404-update-ref-errors.sh Michael Haggerty
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Michael Haggerty @ 2016-06-07 11:50 UTC (permalink / raw)
  To: Junio C Hamano, David Turner
  Cc: Jeff King, Nguyễn Thái Ngọc Duy, git,
	Michael Haggerty

The logic for deciding what error to emit under various update-ref
failure scenarios is nontrivial. Add a bunch of tests of these error
messages. Then improve a few error messages that were not ideal. One
or two other error messages could still be improved, but that would
take more work so I will skip it for now.

This patch series applies on top of mh/split-under-lock. Improving the
testing of that patch series was in fact the main motivation for this
one. It didn't turn up any serious errors, so I don't think that this
patch series needs to hold up the other one. On the other hand, each
of the patch series changes some error messages, so if possible it
would be preferable to ship them in the same Git release.

Happily, this branch doesn't conflict with either of the other large
patch series that are queued up in this area (mh/ref-iterators [2] and
ref-store [3]).

These patches are also available from my GitHub account [4] as branch
update-ref-errors.

Michael

[1] http://thread.gmane.org/gmane.comp.version-control.git/293800
[2] http://thread.gmane.org/gmane.comp.version-control.git/296322
[3] http://thread.gmane.org/gmane.comp.version-control.git/296409
[4] https://github.com/mhagger/git

Michael Haggerty (5):
  t1404: rename file to t1404-update-ref-errors.sh
  t1404: document function test_update_rejected
  t1404: add more tests of update-ref error handling
  lock_ref_for_update(): make error handling more uniform
  lock_ref_for_update(): avoid a symref resolution

 refs/files-backend.c               |  77 ++++---
 t/t1404-update-ref-df-conflicts.sh | 181 -----------------
 t/t1404-update-ref-errors.sh       | 402 +++++++++++++++++++++++++++++++++++++
 3 files changed, 447 insertions(+), 213 deletions(-)
 delete mode 100755 t/t1404-update-ref-df-conflicts.sh
 create mode 100755 t/t1404-update-ref-errors.sh

-- 
2.8.1

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

* [PATCH 1/5] t1404: rename file to t1404-update-ref-errors.sh
  2016-06-07 11:50 [PATCH 0/5] Improve test coverage of update-ref error messages Michael Haggerty
@ 2016-06-07 11:50 ` Michael Haggerty
  2016-06-07 11:50 ` [PATCH 2/5] t1404: document function test_update_rejected Michael Haggerty
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Michael Haggerty @ 2016-06-07 11:50 UTC (permalink / raw)
  To: Junio C Hamano, David Turner
  Cc: Jeff King, Nguyễn Thái Ngọc Duy, git,
	Michael Haggerty

I want to broaden the scope of this test file, so rename it accordingly.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/{t1404-update-ref-df-conflicts.sh => t1404-update-ref-errors.sh} | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename t/{t1404-update-ref-df-conflicts.sh => t1404-update-ref-errors.sh} (98%)

diff --git a/t/t1404-update-ref-df-conflicts.sh b/t/t1404-update-ref-errors.sh
similarity index 98%
rename from t/t1404-update-ref-df-conflicts.sh
rename to t/t1404-update-ref-errors.sh
index 6d869d1..2818460 100755
--- a/t/t1404-update-ref-df-conflicts.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-test_description='Test git update-ref with D/F conflicts'
+test_description='Test git update-ref error handling'
 . ./test-lib.sh
 
 test_update_rejected () {
-- 
2.8.1

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

* [PATCH 2/5] t1404: document function test_update_rejected
  2016-06-07 11:50 [PATCH 0/5] Improve test coverage of update-ref error messages Michael Haggerty
  2016-06-07 11:50 ` [PATCH 1/5] t1404: rename file to t1404-update-ref-errors.sh Michael Haggerty
@ 2016-06-07 11:50 ` Michael Haggerty
  2016-06-07 16:57   ` Johannes Sixt
  2016-06-07 11:50 ` [PATCH 3/5] t1404: add more tests of update-ref error handling Michael Haggerty
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Michael Haggerty @ 2016-06-07 11:50 UTC (permalink / raw)
  To: Junio C Hamano, David Turner
  Cc: Jeff King, Nguyễn Thái Ngọc Duy, git,
	Michael Haggerty

And declare its variables to be local.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/t1404-update-ref-errors.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh
index 2818460..a62d62a 100755
--- a/t/t1404-update-ref-errors.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -3,7 +3,11 @@
 test_description='Test git update-ref error handling'
 . ./test-lib.sh
 
+# Create some references, perhaps run pack-refs --all, then try to
+# create some more references. Ensure that the second creation fails
+# with the correct error message.
 test_update_rejected () {
+	local prefix before pack create error &&
 	prefix="$1" &&
 	before="$2" &&
 	pack="$3" &&
-- 
2.8.1

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

* [PATCH 3/5] t1404: add more tests of update-ref error handling
  2016-06-07 11:50 [PATCH 0/5] Improve test coverage of update-ref error messages Michael Haggerty
  2016-06-07 11:50 ` [PATCH 1/5] t1404: rename file to t1404-update-ref-errors.sh Michael Haggerty
  2016-06-07 11:50 ` [PATCH 2/5] t1404: document function test_update_rejected Michael Haggerty
@ 2016-06-07 11:50 ` Michael Haggerty
  2016-06-07 11:50 ` [PATCH 4/5] lock_ref_for_update(): make error handling more uniform Michael Haggerty
  2016-06-07 11:50 ` [PATCH 5/5] lock_ref_for_update(): avoid a symref resolution Michael Haggerty
  4 siblings, 0 replies; 11+ messages in thread
From: Michael Haggerty @ 2016-06-07 11:50 UTC (permalink / raw)
  To: Junio C Hamano, David Turner
  Cc: Jeff King, Nguyễn Thái Ngọc Duy, git,
	Michael Haggerty

Some of the error messages will be improved in subsequent commits.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/t1404-update-ref-errors.sh | 221 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 219 insertions(+), 2 deletions(-)

diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh
index a62d62a..0dcc16c 100755
--- a/t/t1404-update-ref-errors.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -34,8 +34,9 @@ test_expect_success 'setup' '
 	git commit --allow-empty -m Initial &&
 	C=$(git rev-parse HEAD) &&
 	git commit --allow-empty -m Second &&
-	D=$(git rev-parse HEAD)
-
+	D=$(git rev-parse HEAD) &&
+	git commit --allow-empty -m Third &&
+	E=$(git rev-parse HEAD)
 '
 
 test_expect_success 'existing loose ref is a simple prefix of new' '
@@ -182,4 +183,220 @@ test_expect_success 'empty directory should not fool 1-arg delete' '
 	git update-ref --stdin
 '
 
+# Test various errors when reading the old values of references...
+
+test_expect_success 'missing old value blocks update' '
+	prefix=refs/missing-update &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+	EOF
+	printf "%s\n" "update $prefix/foo $E $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'incorrect old value blocks update' '
+	prefix=refs/incorrect-update &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
+	EOF
+	printf "%s\n" "update $prefix/foo $E $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'existing old value blocks create' '
+	prefix=refs/existing-create &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: reference already exists
+	EOF
+	printf "%s\n" "create $prefix/foo $E" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'incorrect old value blocks delete' '
+	prefix=refs/incorrect-delete &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
+	EOF
+	printf "%s\n" "delete $prefix/foo $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'missing old value blocks indirect update' '
+	prefix=refs/missing-indirect-update &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+	EOF
+	printf "%s\n" "update $prefix/symref $E $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'incorrect old value blocks indirect update' '
+	prefix=refs/incorrect-indirect-update &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+	EOF
+	printf "%s\n" "update $prefix/symref $E $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'existing old value blocks indirect create' '
+	prefix=refs/existing-indirect-create &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
+	EOF
+	printf "%s\n" "create $prefix/symref $E" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'incorrect old value blocks indirect delete' '
+	prefix=refs/incorrect-indirect-delete &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+	EOF
+	printf "%s\n" "delete $prefix/symref $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'missing old value blocks indirect no-deref update' '
+	prefix=refs/missing-noderef-update &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/symref$Q: can${Q}t resolve old value
+	EOF
+	printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'incorrect old value blocks indirect no-deref update' '
+	prefix=refs/incorrect-noderef-update &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+	EOF
+	printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_failure 'existing old value blocks indirect no-deref create' '
+	prefix=refs/existing-noderef-create &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
+	EOF
+	printf "%s\n" "option no-deref" "create $prefix/symref $E" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'incorrect old value blocks indirect no-deref delete' '
+	prefix=refs/incorrect-noderef-delete &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	git update-ref $prefix/foo $C &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
+	EOF
+	printf "%s\n" "option no-deref" "delete $prefix/symref $D" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'non-empty directory blocks create' '
+	prefix=refs/ne-create &&
+	mkdir -p .git/$prefix/foo/bar &&
+	: >.git/$prefix/foo/bar/baz.lock &&
+	test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
+	EOF
+	printf "%s\n" "update $prefix/foo $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+	EOF
+	printf "%s\n" "update $prefix/foo $D $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'broken reference blocks create' '
+	prefix=refs/broken-create &&
+	mkdir -p .git/$prefix &&
+	echo "gobbledigook" >.git/$prefix/foo &&
+	test_when_finished "rm -f .git/$prefix/foo" &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+	EOF
+	printf "%s\n" "update $prefix/foo $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+	EOF
+	printf "%s\n" "update $prefix/foo $D $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'non-empty directory blocks indirect create' '
+	prefix=refs/ne-indirect-create &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	mkdir -p .git/$prefix/foo/bar &&
+	: >.git/$prefix/foo/bar/baz.lock &&
+	test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
+	EOF
+	printf "%s\n" "update $prefix/symref $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+	EOF
+	printf "%s\n" "update $prefix/symref $D $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
+test_expect_success 'broken reference blocks indirect create' '
+	prefix=refs/broken-indirect-create &&
+	git symbolic-ref $prefix/symref $prefix/foo &&
+	echo "gobbledigook" >.git/$prefix/foo &&
+	test_when_finished "rm -f .git/$prefix/foo" &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+	EOF
+	printf "%s\n" "update $prefix/symref $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err &&
+	cat >expected <<-EOF &&
+	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+	EOF
+	printf "%s\n" "update $prefix/symref $D $C" |
+	test_must_fail git update-ref --stdin 2>output.err &&
+	test_cmp expected output.err
+'
+
 test_done
-- 
2.8.1

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

* [PATCH 4/5] lock_ref_for_update(): make error handling more uniform
  2016-06-07 11:50 [PATCH 0/5] Improve test coverage of update-ref error messages Michael Haggerty
                   ` (2 preceding siblings ...)
  2016-06-07 11:50 ` [PATCH 3/5] t1404: add more tests of update-ref error handling Michael Haggerty
@ 2016-06-07 11:50 ` Michael Haggerty
  2016-06-07 11:50 ` [PATCH 5/5] lock_ref_for_update(): avoid a symref resolution Michael Haggerty
  4 siblings, 0 replies; 11+ messages in thread
From: Michael Haggerty @ 2016-06-07 11:50 UTC (permalink / raw)
  To: Junio C Hamano, David Turner
  Cc: Jeff King, Nguyễn Thái Ngọc Duy, git,
	Michael Haggerty

To aid the effort, extract a new function, check_old_oid(), and use it
in the two places where the read value of the reference has to be
checked against update->old_sha1.

Update tests to reflect the improvements.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs/files-backend.c         | 77 ++++++++++++++++++++++++++------------------
 t/t1404-update-ref-errors.sh | 14 ++++----
 2 files changed, 52 insertions(+), 39 deletions(-)

diff --git a/refs/files-backend.c b/refs/files-backend.c
index 1230dfb..98c8b95 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3389,6 +3389,41 @@ static const char *original_update_refname(struct ref_update *update)
 }
 
 /*
+ * Check whether the REF_HAVE_OLD and old_oid values stored in update
+ * are consistent with the result read for the reference. error is
+ * true iff there was an error reading the reference; otherwise, oid
+ * is the value read for the reference.
+ *
+ * If there was a problem, write an error message to err and return
+ * -1.
+ */
+static int check_old_oid(struct ref_update *update, struct object_id *oid,
+			 struct strbuf *err)
+{
+	if (!(update->flags & REF_HAVE_OLD) ||
+		   !hashcmp(oid->hash, update->old_sha1))
+		return 0;
+
+	if (is_null_sha1(update->old_sha1))
+		strbuf_addf(err, "cannot lock ref '%s': "
+			    "reference already exists",
+			    original_update_refname(update));
+	else if (is_null_oid(oid))
+		strbuf_addf(err, "cannot lock ref '%s': "
+			    "reference is missing but expected %s",
+			    original_update_refname(update),
+			    sha1_to_hex(update->old_sha1));
+	else
+		strbuf_addf(err, "cannot lock ref '%s': "
+			    "is at %s but expected %s",
+			    original_update_refname(update),
+			    oid_to_hex(oid),
+			    sha1_to_hex(update->old_sha1));
+
+	return -1;
+}
+
+/*
  * Prepare for carrying out update:
  * - Lock the reference referred to by update.
  * - Read the reference under lock.
@@ -3432,7 +3467,7 @@ static int lock_ref_for_update(struct ref_update *update,
 
 		reason = strbuf_detach(err, NULL);
 		strbuf_addf(err, "cannot lock ref '%s': %s",
-			    update->refname, reason);
+			    original_update_refname(update), reason);
 		free(reason);
 		return ret;
 	}
@@ -3446,28 +3481,17 @@ static int lock_ref_for_update(struct ref_update *update,
 			 * the transaction, so we have to read it here
 			 * to record and possibly check old_sha1:
 			 */
-			if (read_ref_full(update->refname,
-					  mustexist ? RESOLVE_REF_READING : 0,
+			if (read_ref_full(update->refname, 0,
 					  lock->old_oid.hash, NULL)) {
 				if (update->flags & REF_HAVE_OLD) {
 					strbuf_addf(err, "cannot lock ref '%s': "
-						    "can't resolve old value",
-						    update->refname);
-					return TRANSACTION_GENERIC_ERROR;
-				} else {
-					hashclr(lock->old_oid.hash);
+						    "error reading reference",
+						    original_update_refname(update));
+					return -1;
 				}
-			}
-			if ((update->flags & REF_HAVE_OLD) &&
-			    hashcmp(lock->old_oid.hash, update->old_sha1)) {
-				strbuf_addf(err, "cannot lock ref '%s': "
-					    "is at %s but expected %s",
-					    update->refname,
-					    sha1_to_hex(lock->old_oid.hash),
-					    sha1_to_hex(update->old_sha1));
+			} else if (check_old_oid(update, &lock->old_oid, err)) {
 				return TRANSACTION_GENERIC_ERROR;
 			}
-
 		} else {
 			/*
 			 * Create a new update for the reference this
@@ -3484,6 +3508,9 @@ static int lock_ref_for_update(struct ref_update *update,
 	} else {
 		struct ref_update *parent_update;
 
+		if (check_old_oid(update, &lock->old_oid, err))
+			return TRANSACTION_GENERIC_ERROR;
+
 		/*
 		 * If this update is happening indirectly because of a
 		 * symref update, record the old SHA-1 in the parent
@@ -3494,20 +3521,6 @@ static int lock_ref_for_update(struct ref_update *update,
 		     parent_update = parent_update->parent_update) {
 			oidcpy(&parent_update->lock->old_oid, &lock->old_oid);
 		}
-
-		if ((update->flags & REF_HAVE_OLD) &&
-		    hashcmp(lock->old_oid.hash, update->old_sha1)) {
-			if (is_null_sha1(update->old_sha1))
-				strbuf_addf(err, "cannot lock ref '%s': reference already exists",
-					    original_update_refname(update));
-			else
-				strbuf_addf(err, "cannot lock ref '%s': is at %s but expected %s",
-					    original_update_refname(update),
-					    sha1_to_hex(lock->old_oid.hash),
-					    sha1_to_hex(update->old_sha1));
-
-			return TRANSACTION_GENERIC_ERROR;
-		}
 	}
 
 	if ((update->flags & REF_HAVE_NEW) &&
@@ -3529,7 +3542,7 @@ static int lock_ref_for_update(struct ref_update *update,
 			 */
 			update->lock = NULL;
 			strbuf_addf(err,
-				    "cannot update the ref '%s': %s",
+				    "cannot update ref '%s': %s",
 				    update->refname, write_err);
 			free(write_err);
 			return TRANSACTION_GENERIC_ERROR;
diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh
index 0dcc16c..b4602df 100755
--- a/t/t1404-update-ref-errors.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -232,7 +232,7 @@ test_expect_success 'missing old value blocks indirect update' '
 	prefix=refs/missing-indirect-update &&
 	git symbolic-ref $prefix/symref $prefix/foo &&
 	cat >expected <<-EOF &&
-	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+	fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
 	EOF
 	printf "%s\n" "update $prefix/symref $E $D" |
 	test_must_fail git update-ref --stdin 2>output.err &&
@@ -279,7 +279,7 @@ test_expect_success 'missing old value blocks indirect no-deref update' '
 	prefix=refs/missing-noderef-update &&
 	git symbolic-ref $prefix/symref $prefix/foo &&
 	cat >expected <<-EOF &&
-	fatal: cannot lock ref $Q$prefix/symref$Q: can${Q}t resolve old value
+	fatal: cannot lock ref $Q$prefix/symref$Q: reference is missing but expected $D
 	EOF
 	printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
 	test_must_fail git update-ref --stdin 2>output.err &&
@@ -298,7 +298,7 @@ test_expect_success 'incorrect old value blocks indirect no-deref update' '
 	test_cmp expected output.err
 '
 
-test_expect_failure 'existing old value blocks indirect no-deref create' '
+test_expect_success 'existing old value blocks indirect no-deref create' '
 	prefix=refs/existing-noderef-create &&
 	git symbolic-ref $prefix/symref $prefix/foo &&
 	git update-ref $prefix/foo $C &&
@@ -367,13 +367,13 @@ test_expect_success 'non-empty directory blocks indirect create' '
 	: >.git/$prefix/foo/bar/baz.lock &&
 	test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
 	cat >expected <<-EOF &&
-	fatal: cannot lock ref $Q$prefix/foo$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
+	fatal: cannot lock ref $Q$prefix/symref$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
 	EOF
 	printf "%s\n" "update $prefix/symref $C" |
 	test_must_fail git update-ref --stdin 2>output.err &&
 	test_cmp expected output.err &&
 	cat >expected <<-EOF &&
-	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
+	fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
 	EOF
 	printf "%s\n" "update $prefix/symref $D $C" |
 	test_must_fail git update-ref --stdin 2>output.err &&
@@ -386,13 +386,13 @@ test_expect_success 'broken reference blocks indirect create' '
 	echo "gobbledigook" >.git/$prefix/foo &&
 	test_when_finished "rm -f .git/$prefix/foo" &&
 	cat >expected <<-EOF &&
-	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+	fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
 	EOF
 	printf "%s\n" "update $prefix/symref $C" |
 	test_must_fail git update-ref --stdin 2>output.err &&
 	test_cmp expected output.err &&
 	cat >expected <<-EOF &&
-	fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
+	fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
 	EOF
 	printf "%s\n" "update $prefix/symref $D $C" |
 	test_must_fail git update-ref --stdin 2>output.err &&
-- 
2.8.1

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

* [PATCH 5/5] lock_ref_for_update(): avoid a symref resolution
  2016-06-07 11:50 [PATCH 0/5] Improve test coverage of update-ref error messages Michael Haggerty
                   ` (3 preceding siblings ...)
  2016-06-07 11:50 ` [PATCH 4/5] lock_ref_for_update(): make error handling more uniform Michael Haggerty
@ 2016-06-07 11:50 ` Michael Haggerty
  4 siblings, 0 replies; 11+ messages in thread
From: Michael Haggerty @ 2016-06-07 11:50 UTC (permalink / raw)
  To: Junio C Hamano, David Turner
  Cc: Jeff King, Nguyễn Thái Ngọc Duy, git,
	Michael Haggerty

If we're overwriting a symref with a SHA-1, we need to resolve the value
of the symref (1) to check against update->old_sha1 and (2) to write to
its reflog. However, we've already read the symref itself and know its
referent. So there is no need to read the symref's value through the
symref; we can read the referent directly.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs/files-backend.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/refs/files-backend.c b/refs/files-backend.c
index 98c8b95..b8d7a9a 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3481,7 +3481,7 @@ static int lock_ref_for_update(struct ref_update *update,
 			 * the transaction, so we have to read it here
 			 * to record and possibly check old_sha1:
 			 */
-			if (read_ref_full(update->refname, 0,
+			if (read_ref_full(referent.buf, 0,
 					  lock->old_oid.hash, NULL)) {
 				if (update->flags & REF_HAVE_OLD) {
 					strbuf_addf(err, "cannot lock ref '%s': "
-- 
2.8.1

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

* Re: [PATCH 2/5] t1404: document function test_update_rejected
  2016-06-07 11:50 ` [PATCH 2/5] t1404: document function test_update_rejected Michael Haggerty
@ 2016-06-07 16:57   ` Johannes Sixt
  2016-06-07 19:25     ` Junio C Hamano
  2016-06-09 15:45     ` Michael Haggerty
  0 siblings, 2 replies; 11+ messages in thread
From: Johannes Sixt @ 2016-06-07 16:57 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Junio C Hamano, David Turner, Jeff King,
	Nguyễn Thái Ngọc Duy, git

Am 07.06.2016 um 13:50 schrieb Michael Haggerty:
>   test_update_rejected () {
> +	local prefix before pack create error &&

Do we want to add more of unportable 'local' declarations?

>   	prefix="$1" &&
>   	before="$2" &&
>   	pack="$3" &&

-- Hannes

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

* Re: [PATCH 2/5] t1404: document function test_update_rejected
  2016-06-07 16:57   ` Johannes Sixt
@ 2016-06-07 19:25     ` Junio C Hamano
  2016-06-09 15:45     ` Michael Haggerty
  1 sibling, 0 replies; 11+ messages in thread
From: Junio C Hamano @ 2016-06-07 19:25 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: Michael Haggerty, David Turner, Jeff King,
	Nguyễn Thái Ngọc Duy, git

Johannes Sixt <j6t@kdbg.org> writes:

> Am 07.06.2016 um 13:50 schrieb Michael Haggerty:
>>   test_update_rejected () {
>> +	local prefix before pack create error &&
>
> Do we want to add more of unportable 'local' declarations?

Not really ;-)  Thanks for catching.

>>   	prefix="$1" &&
>>   	before="$2" &&
>>   	pack="$3" &&
>
> -- Hannes

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

* Re: [PATCH 2/5] t1404: document function test_update_rejected
  2016-06-07 16:57   ` Johannes Sixt
  2016-06-07 19:25     ` Junio C Hamano
@ 2016-06-09 15:45     ` Michael Haggerty
  2016-06-09 16:05       ` Junio C Hamano
  1 sibling, 1 reply; 11+ messages in thread
From: Michael Haggerty @ 2016-06-09 15:45 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: Junio C Hamano, David Turner, Jeff King,
	Nguyễn Thái Ngọc Duy, git

On 06/07/2016 06:57 PM, Johannes Sixt wrote:
> Am 07.06.2016 um 13:50 schrieb Michael Haggerty:
>>   test_update_rejected () {
>> +    local prefix before pack create error &&
> 
> Do we want to add more of unportable 'local' declarations?

Sorry, I forgot that `local` is not in the POSIX standard.

According to [1] it's nevertheless very portable. Do you object to
`local` based only on its absence from POSIX, or because it's known to
cause problems in the real world? I ask because it is a convenient
feature (and its lack is a common cause of mysterious errors), so it
would be nice if we could allow its use.

Michael

[1] http://apenwarr.ca/log/?m=201102#28

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

* Re: [PATCH 2/5] t1404: document function test_update_rejected
  2016-06-09 15:45     ` Michael Haggerty
@ 2016-06-09 16:05       ` Junio C Hamano
  2016-06-10  6:30         ` Michael Haggerty
  0 siblings, 1 reply; 11+ messages in thread
From: Junio C Hamano @ 2016-06-09 16:05 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Johannes Sixt, David Turner, Jeff King,
	Nguyễn Thái Ngọc Duy, git

Michael Haggerty <mhagger@alum.mit.edu> writes:

> On 06/07/2016 06:57 PM, Johannes Sixt wrote:
>> Am 07.06.2016 um 13:50 schrieb Michael Haggerty:
>>>   test_update_rejected () {
>>> +    local prefix before pack create error &&
>> 
>> Do we want to add more of unportable 'local' declarations?
>
> Sorry, I forgot that `local` is not in the POSIX standard.

Regarding portability we say three things.

 * It is supported practically everywhere, and it is even in POSIX,
   so let's use it.

 * Even this is not in POSIX, it is supported practically
   everywhere, and it is too cumbersome to do things without using
   it, so let's use it.

 * It is not available in some platforms we (collectively) still
   care; it is not even in POSIX.  Don't use it.

I think "local" falls into the third one.

: bash; ksh
$ v=1
$ f () { local v; v=2; echo f; }
$ f
ksh: local: not found [No such file or directory]
f
$ echo $v
2
$ exit
: bash;

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

* Re: [PATCH 2/5] t1404: document function test_update_rejected
  2016-06-09 16:05       ` Junio C Hamano
@ 2016-06-10  6:30         ` Michael Haggerty
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Haggerty @ 2016-06-10  6:30 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Sixt, David Turner, Jeff King,
	Nguyễn Thái Ngọc Duy, git

On 06/09/2016 06:05 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> On 06/07/2016 06:57 PM, Johannes Sixt wrote:
>>> Am 07.06.2016 um 13:50 schrieb Michael Haggerty:
>>>>   test_update_rejected () {
>>>> +    local prefix before pack create error &&
>>>
>>> Do we want to add more of unportable 'local' declarations?
>>
>> Sorry, I forgot that `local` is not in the POSIX standard.
> 
> Regarding portability we say three things.
> 
>  * It is supported practically everywhere, and it is even in POSIX,
>    so let's use it.
> 
>  * Even this is not in POSIX, it is supported practically
>    everywhere, and it is too cumbersome to do things without using
>    it, so let's use it.
> 
>  * It is not available in some platforms we (collectively) still
>    care; it is not even in POSIX.  Don't use it.
> 
> I think "local" falls into the third one.
> 
> : bash; ksh
> $ v=1
> $ f () { local v; v=2; echo f; }
> $ f
> ksh: local: not found [No such file or directory]
> f
> $ echo $v
> 2
> $ exit
> : bash;

OK, I didn't realize that we still support ksh. I will make the change.

Michael

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

end of thread, other threads:[~2016-06-10  6:31 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-07 11:50 [PATCH 0/5] Improve test coverage of update-ref error messages Michael Haggerty
2016-06-07 11:50 ` [PATCH 1/5] t1404: rename file to t1404-update-ref-errors.sh Michael Haggerty
2016-06-07 11:50 ` [PATCH 2/5] t1404: document function test_update_rejected Michael Haggerty
2016-06-07 16:57   ` Johannes Sixt
2016-06-07 19:25     ` Junio C Hamano
2016-06-09 15:45     ` Michael Haggerty
2016-06-09 16:05       ` Junio C Hamano
2016-06-10  6:30         ` Michael Haggerty
2016-06-07 11:50 ` [PATCH 3/5] t1404: add more tests of update-ref error handling Michael Haggerty
2016-06-07 11:50 ` [PATCH 4/5] lock_ref_for_update(): make error handling more uniform Michael Haggerty
2016-06-07 11:50 ` [PATCH 5/5] lock_ref_for_update(): avoid a symref resolution Michael Haggerty

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).