git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 01/18] t1404: new tests of ref D/F conflicts within transactions

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
May 11, 2015, 15:25 UTC
Message-ID
<1431357920-25090-2-git-send-email-mhagger@alum.mit.edu>
In-Reply-To
<1431357920-25090-1-git-send-email-mhagger@alum.mit.edu>

Add some tests of reference D/F conflicts (by which I mean the fact that references like "refs/foo" and "refs/foo/bar" are not allowed to coexist) in the context of reference transactions.

The test of creating two conflicting references in the same transaction fails, leaving the transaction half-completed. This will be fixed later in this patch series.

Please note that the error messages emitted in the case of conflicts are not very user-friendly. In particular, when the conflicts involve loose references, then the errors are reported as

    error: there are still refs under 'refs/foo'
    fatal: Cannot lock the ref 'refs/foo'.
or
    error: unable to resolve reference refs/foo/bar: Not a directory
    fatal: Cannot lock the ref 'refs/foo/bar'.

This is because lock_ref_sha1_basic() fails while trying to lock the new reference, before it even gets to the is_refname_available() check. This situation will also be improved later in this patch series.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/t1404-update-ref-df-conflicts.sh | 107 +++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100755 t/t1404-update-ref-df-conflicts.sh
diff --git a/t/t1404-update-ref-df-conflicts.sh b/t/t1404-update-ref-df-conflicts.sh
new file mode 100755
index 0000000..ed1b93e
--- /dev/null
+++ b/t/t1404-update-ref-df-conflicts.sh
@@ -0,1 +1,107 @@
+#!/bin/sh
+
+test_description='Test git update-ref with D/F conflicts'
+. ./test-lib.sh
+
+test_update_rejected () {
+	prefix="$1" &&
+	before="$2" &&
+	pack="$3" &&
+	create="$4" &&
+	error="$5" &&
+	printf "create $prefix/%s $C\n" $before |
+	git update-ref --stdin &&
+	git for-each-ref $prefix >unchanged &&
+	if $pack
+	then
+		git pack-refs --all
+	fi &&
+	printf "create $prefix/%s $C\n" $create >input &&
+	test_must_fail git update-ref --stdin <input 2>output.err &&
+	grep -F "$error" output.err &&
+	git for-each-ref $prefix >actual &&
+	test_cmp unchanged actual
+}
+
+Q="'"
+
+test_expect_success 'setup' '
+
+	git commit --allow-empty -m Initial &&
+	C=$(git rev-parse HEAD)
+
+'
+
+test_expect_success 'existing loose ref is a simple prefix of new' '
+
+	prefix=refs/1l &&
+	test_update_rejected $prefix "a c e" false "b c/x d" \
+		"unable to resolve reference $prefix/c/x: Not a directory"
+
+'
+
+test_expect_success 'existing packed ref is a simple prefix of new' '
+
+	prefix=refs/1p &&
+	test_update_rejected $prefix "a c e" true "b c/x d" \
+		"$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
+
+'
+
+test_expect_success 'existing loose ref is a deeper prefix of new' '
+
+	prefix=refs/2l &&
+	test_update_rejected $prefix "a c e" false "b c/x/y d" \
+		"unable to resolve reference $prefix/c/x/y: Not a directory"
+
+'
+
+test_expect_success 'existing packed ref is a deeper prefix of new' '
+
+	prefix=refs/2p &&
+	test_update_rejected $prefix "a c e" true "b c/x/y d" \
+		"$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
+
+'
+
+test_expect_success 'new ref is a simple prefix of existing loose' '
+
+	prefix=refs/3l &&
+	test_update_rejected $prefix "a c/x e" false "b c d" \
+		"there are still refs under $Q$prefix/c$Q"
+
+'
+
+test_expect_success 'new ref is a simple prefix of existing packed' '
+
+	prefix=refs/3p &&
+	test_update_rejected $prefix "a c/x e" true "b c d" \
+		"$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
+
+'
+
+test_expect_success 'new ref is a deeper prefix of existing loose' '
+
+	prefix=refs/4l &&
+	test_update_rejected $prefix "a c/x/y e" false "b c d" \
+		"there are still refs under $Q$prefix/c$Q"
+
+'
+
+test_expect_success 'new ref is a deeper prefix of existing packed' '
+
+	prefix=refs/4p &&
+	test_update_rejected $prefix "a c/x/y e" true "b c d" \
+		"$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
+
+'
+
+test_expect_failure 'one new ref is a simple prefix of another' '
+
+	prefix=refs/5 &&
+	test_update_rejected $prefix "a e" false "b c c/x d" \
+		"cannot process $Q$prefix/c$Q and $Q$prefix/c/x$Q at the same time"
+
+'
+
+test_done
-- 
2.1.4
Previous: Michael HaggertyNext: Junio C Hamano
Message 2 of 33 in “Improve handling of D/F conflicts”
  1. 00/18 Improve handling of D/F conflictsMichael Haggerty, May 11, 2015
  2. 01/18 t1404: new tests of ref D/F conflicts within transactionsMichael Haggerty, May 11, 2015
  3. Junio C HamanoMay 11, 2015
  4. Michael HaggertyMay 12, 2015
  5. Junio C HamanoMay 11, 2015
  6. Michael HaggertyMay 12, 2015
  7. Junio C HamanoMay 12, 2015
  8. Michael HaggertyMay 13, 2015
  9. Junio C HamanoMay 14, 2015
  10. Michael HaggertyMay 22, 2015
  11. Junio C HamanoMay 23, 2015
  12. 02/18 is_refname_available(): revamp the commentsMichael Haggerty, May 11, 2015
  13. Junio C HamanoMay 12, 2015
  14. 03/18 is_refname_available(): avoid shadowing "dir" variableMichael Haggerty, May 11, 2015
  15. Junio C HamanoMay 12, 2015
  16. 04/18 is_refname_available(): convert local variable "dirname" to strbufMichael Haggerty, May 11, 2015
  17. 05/18 entry_matches(): inline functionMichael Haggerty, May 11, 2015
  18. 06/18 report_refname_conflict(): inline functionMichael Haggerty, May 11, 2015
  19. Junio C HamanoMay 12, 2015
  20. 07/18 struct nonmatching_ref_data: store a refname instead of a ref_entryMichael Haggerty, May 11, 2015
  21. 08/18 is_refname_available(): use dirname in first loopMichael Haggerty, May 11, 2015
  22. 09/18 ref_transaction_commit(): use a string_list for detecting duplicatesMichael Haggerty, May 11, 2015
  23. 10/18 refs: check for D/F conflicts among refs created in a transactionMichael Haggerty, May 11, 2015
  24. 11/18 verify_refname_available(): rename functionMichael Haggerty, May 11, 2015
  25. 12/18 verify_refname_available(): report errors via a "struct strbuf *err"Michael Haggerty, May 11, 2015
  26. 13/18 lock_ref_sha1_basic(): report errors via a "struct strbuf *err"Michael Haggerty, May 11, 2015
  27. 14/18 lock_ref_sha1_basic(): improve diagnostics for ref D/F conflictsMichael Haggerty, May 11, 2015
  28. 15/18 rename_ref(): integrate lock_ref_sha1_basic() errors into oursMichael Haggerty, May 11, 2015
  29. 16/18 ref_transaction_commit(): provide better error messagesMichael Haggerty, May 11, 2015
  30. 17/18 ref_transaction_commit(): delete extra "the" from error messageMichael Haggerty, May 11, 2015
  31. 18/18 reflog_expire(): integrate lock_ref_sha1_basic() errors into oursMichael Haggerty, May 11, 2015
  32. Junio C HamanoMay 11, 2015
  33. Stefan BellerMay 11, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.