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

[PATCH] refs: handle null-oid for pseudorefs

From
MÅMartin Ågren <martin.agren@gmail.com>
Date
May 6, 2018, 13:35 UTC
Message-ID
<20180506133549.8536-1-martin.agren@gmail.com>
In-Reply-To
<CACUQV5-9PagVhE5YY=Z3721YRiBwSZykT3ZjtzmD3o-c6O6ddQ@mail.gmail.com>

According to the documentation on `git update-ref`, it is possible to "specify 40 '0' or an empty string as <oldvalue> to make sure that the ref you are creating does not exist." But in the code for pseudorefs, we do not implement this. If we fail to read the old ref, we immediately die. A failure to read would actually be a good thing if we have been given the null-oid.

With the null-oid, allow -- and even require -- the ref-reading to fail. This implements the "make sure that the ref ... does not exist" part of the documentation.

Since we have a `strbuf err` for collecting errors, let's use it and signal an error to the caller instead of dying hard.

Reported-by: Rafael Ascensão <rafa.almas@gmail.com>
Helped-by: Rafael Ascensão <rafa.almas@gmail.com>
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
---
(David's twopensource-address bounced, so I'm trying instead the one he
most recently posted from.)
 t/t1400-update-ref.sh |  7 +++++++
 refs.c                | 19 +++++++++++++++----
 2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 664a3a4e4e..bd41f86f22 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -457,6 +457,13 @@ test_expect_success 'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER
 	test OTHER = $(git cat-file blob "master@{2005-05-26 23:42}:F")
 '
 
+test_expect_success 'create pseudoref with old oid null, but do not overwrite' '
+	git update-ref PSEUDOREF $A $Z &&
+	test_when_finished "git update-ref -d PSEUDOREF" &&
+	test $A = $(cat .git/PSEUDOREF) &&
+	test_must_fail git update-ref PSEUDOREF $A $Z
+'
+
 a=refs/heads/a
 b=refs/heads/b
 c=refs/heads/c
diff --git a/refs.c b/refs.c
index 8b7a77fe5e..3669190499 100644
--- a/refs.c
+++ b/refs.c
@@ -666,10 +666,21 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
 	if (old_oid) {
 		struct object_id actual_old_oid;
 
-		if (read_ref(pseudoref, &actual_old_oid))
-			die("could not read ref '%s'", pseudoref);
-		if (oidcmp(&actual_old_oid, old_oid)) {
-			strbuf_addf(err, "unexpected sha1 when writing '%s'", pseudoref);
+		if (read_ref(pseudoref, &actual_old_oid)) {
+			if (!is_null_oid(old_oid)) {
+				strbuf_addf(err, "could not read ref '%s'",
+					    pseudoref);
+				rollback_lock_file(&lock);
+				goto done;
+			}
+		} else if (is_null_oid(old_oid)) {
+			strbuf_addf(err, "ref '%s' already exists",
+				    pseudoref);
+			rollback_lock_file(&lock);
+			goto done;
+		} else if (oidcmp(&actual_old_oid, old_oid)) {
+			strbuf_addf(err, "unexpected sha1 when writing '%s'",
+				    pseudoref);
 			rollback_lock_file(&lock);
 			goto done;
 		}
-- 
2.17.0.411.g9fd64c8e46
Previous: Rafael AscensãoNext: David Turner
Message 4 of 11 in “git update-ref fails to create reference. (bug)”
  1. Rafael AscensãoMay 4, 2018
  2. Martin ÅgrenMay 4, 2018
  3. Rafael AscensãoMay 5, 2018
  4. refs: handle null-oid for pseudorefsMartin Ågren, May 6, 2018
  5. David TurnerMay 6, 2018
  6. Michael HaggertyMay 7, 2018
  7. Martin ÅgrenMay 7, 2018
  8. 0/3 refs: handle zero oid for pseudorefsMartin Ågren, May 10, 2018
  9. 1/3 refs.c: refer to "object ID", not "sha1", in error messagesMartin Ågren, May 10, 2018
  10. 2/3 t1400: add tests around adding/deleting pseudorefsMartin Ågren, May 10, 2018
  11. 3/3 refs: handle zero oid for pseudorefsMartin Ågren, May 10, 2018

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.