From: Stefan Beller <sbeller@google.com>
To: git@vger.kernel.org, gitster@pobox.com, mhagger@alum.mit.edu
Cc: Ronnie Sahlberg <sahlberg@google.com>,
Jonathan Nieder <jrnieder@gmail.com>,
Stefan Beller <sbeller@google.com>
Subject: [PATCH v3 14/14] refs.c: allow deleting refs with a broken sha1
Date: Mon, 17 Nov 2014 17:35:50 -0800 [thread overview]
Message-ID: <1416274550-2827-15-git-send-email-sbeller@google.com> (raw)
In-Reply-To: <1416274550-2827-1-git-send-email-sbeller@google.com>
From: Ronnie Sahlberg <sahlberg@google.com>
Add back support to make it possible to delete refs that have a broken
sha1.
Add new internal flags REF_ALLOW_BROKEN and RESOLVE_REF_ALLOW_BAD_SHA1
to pass intent from branch.c that we are willing to allow
resolve_ref_unsafe and lock_ref_sha1_basic to allow broken refs.
Since these refs can not actually be resolved to a sha1, they instead resolve
to null_sha1 when these flags are used.
For example, the ref:
echo "Broken ref" > .git/refs/heads/foo-broken-1
can now be deleted using git branch -d foo-broken-1
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
builtin/branch.c | 5 +++--
cache.h | 7 +++++++
refs.c | 6 ++++++
refs.h | 6 ++++--
t/t1402-check-ref-format.sh | 8 ++++++++
5 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 3b79c50..04f57d4 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -238,7 +238,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
target = resolve_ref_unsafe(name,
RESOLVE_REF_READING
| RESOLVE_REF_NO_RECURSE
- | RESOLVE_REF_ALLOW_BAD_NAME,
+ | RESOLVE_REF_ALLOW_BAD_NAME
+ | RESOLVE_REF_ALLOW_BAD_SHA1,
sha1, &flags);
if (!target) {
error(remote_branch
@@ -255,7 +256,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
continue;
}
- if (delete_ref(name, sha1, REF_NODEREF)) {
+ if (delete_ref(name, sha1, REF_NODEREF|REF_ALLOW_BROKEN)) {
error(remote_branch
? _("Error deleting remote branch '%s'")
: _("Error deleting branch '%s'"),
diff --git a/cache.h b/cache.h
index 99ed096..61e61af 100644
--- a/cache.h
+++ b/cache.h
@@ -1000,10 +1000,17 @@ extern int read_ref(const char *refname, unsigned char *sha1);
* resolved. The function returns NULL for such ref names.
* Caps and underscores refers to the special refs, such as HEAD,
* FETCH_HEAD and friends, that all live outside of the refs/ directory.
+ *
+ * RESOLVE_REF_ALLOW_BAD_SHA1 when this flag is set and the ref contains
+ * an invalid sha1, resolve_ref_unsafe will clear the sha1 argument,
+ * set the REF_ISBROKEN flag and return the refname.
+ * This allows using resolve_ref_unsafe to check for existence of such
+ * broken refs.
*/
#define RESOLVE_REF_READING 0x01
#define RESOLVE_REF_NO_RECURSE 0x02
#define RESOLVE_REF_ALLOW_BAD_NAME 0x04
+#define RESOLVE_REF_ALLOW_BAD_SHA1 0x08
extern const char *resolve_ref_unsafe(const char *ref, int resolve_flags, unsigned char *sha1, int *flags);
extern char *resolve_refdup(const char *ref, int resolve_flags, unsigned char *sha1, int *flags);
diff --git a/refs.c b/refs.c
index b318888..d75af6c 100644
--- a/refs.c
+++ b/refs.c
@@ -1584,6 +1584,10 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags, unsigned
(buffer[40] != '\0' && !isspace(buffer[40]))) {
if (flags)
*flags |= REF_ISBROKEN;
+ if (resolve_flags & RESOLVE_REF_ALLOW_BAD_SHA1) {
+ hashclr(sha1);
+ return refname;
+ }
errno = EINVAL;
return NULL;
}
@@ -2265,6 +2269,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
if (flags & REF_NODEREF)
resolve_flags |= RESOLVE_REF_NO_RECURSE;
}
+ if (flags & REF_ALLOW_BROKEN)
+ resolve_flags |= RESOLVE_REF_ALLOW_BAD_SHA1;
refname = resolve_ref_unsafe(refname, resolve_flags,
lock->old_sha1, &type);
diff --git a/refs.h b/refs.h
index 721e21f..2e97f4f 100644
--- a/refs.h
+++ b/refs.h
@@ -185,11 +185,13 @@ extern int peel_ref(const char *refname, unsigned char *sha1);
* REF_NODEREF: act on the ref directly, instead of dereferencing
* symbolic references.
* REF_DELETING: tolerate broken refs
+ * REF_ALLOW_BROKEN: allow locking refs that are broken.
*
* Flags >= 0x100 are reserved for internal use.
*/
-#define REF_NODEREF 0x01
-#define REF_DELETING 0x02
+#define REF_NODEREF 0x01
+#define REF_DELETING 0x02
+#define REF_ALLOW_BROKEN 0x04
/** Reads log for the value of ref during at_time. **/
extern int read_ref_at(const char *refname, unsigned int flags,
diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
index e5dc62e..a0aef69 100755
--- a/t/t1402-check-ref-format.sh
+++ b/t/t1402-check-ref-format.sh
@@ -197,4 +197,12 @@ invalid_ref_normalized 'heads///foo.lock'
invalid_ref_normalized 'foo.lock/bar'
invalid_ref_normalized 'foo.lock///bar'
+test_expect_success 'git branch -d can delete ref with broken sha1' '
+ echo "012brokensha1" > .git/refs/heads/brokensha1 &&
+ test_when_finished "rm -f .git/refs/heads/brokensha1" &&
+ git branch -d brokensha1 &&
+ git branch >output &&
+ ! grep -e "brokensha1" output
+'
+
test_done
--
2.2.0.rc2.5.gf7b9fb2
next prev parent reply other threads:[~2014-11-18 1:36 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-18 1:35 [PATCH v3 00/14] ref-transactions-reflog Stefan Beller
2014-11-18 1:35 ` [PATCH v3 01/14] refs.c: make ref_transaction_create a wrapper for ref_transaction_update Stefan Beller
2014-11-18 1:35 ` [PATCH v3 02/14] refs.c: make ref_transaction_delete " Stefan Beller
2014-11-18 1:35 ` [PATCH v3 03/14] refs.c: rename the transaction functions Stefan Beller
2014-11-18 1:35 ` [PATCH v3 04/14] refs.c: add a function to append a reflog entry to a fd Stefan Beller
2014-11-18 1:35 ` [PATCH v3 05/14] refs.c: add a new update_type field to ref_update Stefan Beller
2014-11-18 1:35 ` [PATCH v3 06/14] refs.c: add a transaction function to append a reflog entry Stefan Beller
2014-11-18 1:35 ` [PATCH v3 07/14] refs.c: add a flag to allow reflog updates to truncate the log Stefan Beller
2014-11-18 1:35 ` [PATCH v3 08/14] refs.c: only write reflog update if msg is non-NULL Stefan Beller
2014-11-18 1:35 ` [PATCH v3 09/14] refs.c: allow multiple reflog updates during a single transaction Stefan Beller
2014-11-18 1:35 ` [PATCH v3 10/14] reflog.c: use a reflog transaction when writing during expire Stefan Beller
2014-11-18 1:35 ` [PATCH v3 11/14] refs.c: rename log_ref_setup to create_reflog Stefan Beller
2014-11-18 1:35 ` [PATCH v3 12/14] refs.c: Remove unlock_ref/close_ref/commit_ref from the refs api Stefan Beller
2014-11-18 1:35 ` [PATCH v3 13/14] refs.c: remove lock_any_ref_for_update Stefan Beller
2014-11-18 1:35 ` Stefan Beller [this message]
2014-11-18 11:26 ` [PATCH v3 00/14] ref-transactions-reflog Michael Haggerty
2014-11-18 18:36 ` Ronnie Sahlberg
2014-11-18 19:46 ` Michael Haggerty
2014-11-18 20:30 ` Junio C Hamano
2014-11-18 21:16 ` Michael Haggerty
2014-11-18 21:28 ` Junio C Hamano
2014-11-19 23:22 ` Stefan Beller
2014-11-20 3:24 ` Jonathan Nieder
2014-11-20 17:34 ` Junio C Hamano
2014-11-20 10:56 ` Michael Haggerty
2014-11-20 18:17 ` Jonathan Nieder
2014-11-27 5:34 ` [PATCH 0/4] Using transactions for the reflog Stefan Beller
2014-11-27 5:34 ` [PATCH 1/4] refs.c: rename the transaction functions Stefan Beller
2014-11-27 5:34 ` [PATCH 2/4] refs.c: add a new update_type field to ref_update Stefan Beller
2014-11-27 5:34 ` [PATCH 3/4] refs.c: add a transaction function to append a reflog entry Stefan Beller
2014-11-27 5:34 ` [PATCH 4/4] reflog.c: use a reflog transaction when writing during expire Stefan Beller
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=1416274550-2827-15-git-send-email-sbeller@google.com \
--to=sbeller@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jrnieder@gmail.com \
--cc=mhagger@alum.mit.edu \
--cc=sahlberg@google.com \
/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).