summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-09-27 01:58:57 -0700
committerJunio C Hamano <junkio@cox.net>2006-09-27 02:01:42 -0700
commitac5409e420e5fdd7c4a381f873ffcedfb83d7117 (patch)
treeeae6bec434639c43b324005b5c0b88bfe5889834 /refs.c
parent4431fcc4b134ae501e3e57dc568ae4f031e57898 (diff)
downloadgit-ac5409e420e5fdd7c4a381f873ffcedfb83d7117.tar.gz
update-ref: -d flag and ref creation safety.
This adds -d flag to update-ref to allow safe deletion of ref. Before deleting it, the command checks if the given <oldvalue> still matches the value the caller thought the ref contained. Similarly, it also accepts 0{40} or an empty string as <oldvalue> to allow safe creation of a new ref. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/refs.c b/refs.c
index 9a1bc0db59..3d4cdd1eb9 100644
--- a/refs.c
+++ b/refs.c
@@ -378,6 +378,32 @@ int get_ref_sha1(const char *ref, unsigned char *sha1)
return read_ref(mkpath("refs/%s", ref), sha1);
}
+int delete_ref(const char *refname, unsigned char *sha1)
+{
+ struct ref_lock *lock;
+ int err, i, ret = 0;
+
+ lock = lock_any_ref_for_update(refname, sha1);
+ if (!lock)
+ return 1;
+ i = strlen(lock->lk->filename) - 5; /* .lock */
+ lock->lk->filename[i] = 0;
+ err = unlink(lock->lk->filename);
+ if (err) {
+ ret = 1;
+ error("unlink(%s) failed: %s",
+ lock->lk->filename, strerror(errno));
+ }
+ lock->lk->filename[i] = '.';
+
+ err = unlink(lock->log_file);
+ if (err && errno != ENOENT)
+ fprintf(stderr, "warning: unlink(%s) failed: %s",
+ lock->log_file, strerror(errno));
+
+ return ret;
+}
+
/*
* Make sure "ref" is something reasonable to have under ".git/refs/";
* We do not like it if: