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>
This commit is contained in:
Junio C Hamano
2006-09-27 01:58:57 -07:00
parent 4431fcc4b1
commit ac5409e420
4 changed files with 50 additions and 5 deletions

26
refs.c
View File

@ -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: