lock_ref_sha1_basic(): only handle REF_NODEREF mode

Now lock_ref_sha1_basic() is only called with flags==REF_NODEREF. So we
don't have to handle other cases anymore.

This enables several simplifications, the most interesting of which come
from the fact that ref_lock::orig_ref_name is now always the same as
ref_lock::ref_name:

* Remove ref_lock::orig_ref_name
* Remove local variable orig_refname from lock_ref_sha1_basic()
* ref_name can be initialize once and its value reused
* commit_ref_update() never has to write to the reflog for
  lock->orig_ref_name

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
This commit is contained in:
Michael Haggerty 2016-04-22 15:25:25 +02:00
parent 5d9b2de4ef
commit 7a418f3a17

View File

@ -7,7 +7,6 @@
struct ref_lock { struct ref_lock {
char *ref_name; char *ref_name;
char *orig_ref_name;
struct lock_file *lk; struct lock_file *lk;
struct object_id old_oid; struct object_id old_oid;
}; };
@ -1522,7 +1521,6 @@ static void unlock_ref(struct ref_lock *lock)
if (lock->lk) if (lock->lk)
rollback_lock_file(lock->lk); rollback_lock_file(lock->lk);
free(lock->ref_name); free(lock->ref_name);
free(lock->orig_ref_name);
free(lock); free(lock);
} }
@ -1576,7 +1574,6 @@ static int lock_raw_ref(const char *refname, int mustexist,
*lock_p = lock = xcalloc(1, sizeof(*lock)); *lock_p = lock = xcalloc(1, sizeof(*lock));
lock->ref_name = xstrdup(refname); lock->ref_name = xstrdup(refname);
lock->orig_ref_name = xstrdup(refname);
strbuf_git_path(&ref_file, "%s", refname); strbuf_git_path(&ref_file, "%s", refname);
retry: retry:
@ -1969,14 +1966,13 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
struct strbuf *err) struct strbuf *err)
{ {
struct strbuf ref_file = STRBUF_INIT; struct strbuf ref_file = STRBUF_INIT;
struct strbuf orig_ref_file = STRBUF_INIT;
const char *orig_refname = refname;
struct ref_lock *lock; struct ref_lock *lock;
int last_errno = 0; int last_errno = 0;
int lflags = 0; int lflags = LOCK_NO_DEREF;
int mustexist = (old_sha1 && !is_null_sha1(old_sha1)); int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
int resolve_flags = 0; int resolve_flags = RESOLVE_REF_NO_RECURSE;
int attempts_remaining = 3; int attempts_remaining = 3;
int resolved;
assert(err); assert(err);
@ -1986,46 +1982,39 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
resolve_flags |= RESOLVE_REF_READING; resolve_flags |= RESOLVE_REF_READING;
if (flags & REF_DELETING) if (flags & REF_DELETING)
resolve_flags |= RESOLVE_REF_ALLOW_BAD_NAME; resolve_flags |= RESOLVE_REF_ALLOW_BAD_NAME;
if (flags & REF_NODEREF) {
resolve_flags |= RESOLVE_REF_NO_RECURSE;
lflags |= LOCK_NO_DEREF;
}
refname = resolve_ref_unsafe(refname, resolve_flags, strbuf_git_path(&ref_file, "%s", refname);
lock->old_oid.hash, type); resolved = !!resolve_ref_unsafe(refname, resolve_flags,
if (!refname && errno == EISDIR) { lock->old_oid.hash, type);
if (!resolved && errno == EISDIR) {
/* /*
* we are trying to lock foo but we used to * we are trying to lock foo but we used to
* have foo/bar which now does not exist; * have foo/bar which now does not exist;
* it is normal for the empty directory 'foo' * it is normal for the empty directory 'foo'
* to remain. * to remain.
*/ */
strbuf_git_path(&orig_ref_file, "%s", orig_refname); if (remove_empty_directories(&ref_file)) {
if (remove_empty_directories(&orig_ref_file)) {
last_errno = errno; last_errno = errno;
if (!verify_refname_available_dir(orig_refname, extras, skip, if (!verify_refname_available_dir(refname, extras, skip,
get_loose_refs(&ref_cache), err)) get_loose_refs(&ref_cache), err))
strbuf_addf(err, "there are still refs under '%s'", strbuf_addf(err, "there are still refs under '%s'",
orig_refname); refname);
goto error_return; goto error_return;
} }
refname = resolve_ref_unsafe(orig_refname, resolve_flags, resolved = !!resolve_ref_unsafe(refname, resolve_flags,
lock->old_oid.hash, type); lock->old_oid.hash, type);
} }
if (!refname) { if (!resolved) {
last_errno = errno; last_errno = errno;
if (last_errno != ENOTDIR || if (last_errno != ENOTDIR ||
!verify_refname_available_dir(orig_refname, extras, skip, !verify_refname_available_dir(refname, extras, skip,
get_loose_refs(&ref_cache), err)) get_loose_refs(&ref_cache), err))
strbuf_addf(err, "unable to resolve reference '%s': %s", strbuf_addf(err, "unable to resolve reference '%s': %s",
orig_refname, strerror(last_errno)); refname, strerror(last_errno));
goto error_return; goto error_return;
} }
if (flags & REF_NODEREF)
refname = orig_refname;
/* /*
* If the ref did not exist and we are creating it, make sure * If the ref did not exist and we are creating it, make sure
* there is no existing packed ref whose name begins with our * there is no existing packed ref whose name begins with our
@ -2042,8 +2031,6 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
lock->lk = xcalloc(1, sizeof(struct lock_file)); lock->lk = xcalloc(1, sizeof(struct lock_file));
lock->ref_name = xstrdup(refname); lock->ref_name = xstrdup(refname);
lock->orig_ref_name = xstrdup(orig_refname);
strbuf_git_path(&ref_file, "%s", refname);
retry: retry:
switch (safe_create_leading_directories_const(ref_file.buf)) { switch (safe_create_leading_directories_const(ref_file.buf)) {
@ -2086,7 +2073,6 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
out: out:
strbuf_release(&ref_file); strbuf_release(&ref_file);
strbuf_release(&orig_ref_file);
errno = last_errno; errno = last_errno;
return lock; return lock;
} }
@ -2883,9 +2869,7 @@ static int commit_ref_update(struct ref_lock *lock,
struct strbuf *err) struct strbuf *err)
{ {
clear_loose_ref_cache(&ref_cache); clear_loose_ref_cache(&ref_cache);
if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, 0, err) < 0 || if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, 0, err)) {
(strcmp(lock->ref_name, lock->orig_ref_name) &&
log_ref_write(lock->orig_ref_name, lock->old_oid.hash, sha1, logmsg, 0, err) < 0)) {
char *old_msg = strbuf_detach(err, NULL); char *old_msg = strbuf_detach(err, NULL);
strbuf_addf(err, "cannot update the ref '%s': %s", strbuf_addf(err, "cannot update the ref '%s': %s",
lock->ref_name, old_msg); lock->ref_name, old_msg);
@ -2893,7 +2877,8 @@ static int commit_ref_update(struct ref_lock *lock,
unlock_ref(lock); unlock_ref(lock);
return -1; return -1;
} }
if (strcmp(lock->orig_ref_name, "HEAD") != 0) {
if (strcmp(lock->ref_name, "HEAD") != 0) {
/* /*
* Special hack: If a branch is updated directly and HEAD * Special hack: If a branch is updated directly and HEAD
* points to it (may happen on the remote side of a push * points to it (may happen on the remote side of a push
@ -2909,6 +2894,7 @@ static int commit_ref_update(struct ref_lock *lock,
unsigned char head_sha1[20]; unsigned char head_sha1[20];
int head_flag; int head_flag;
const char *head_ref; const char *head_ref;
head_ref = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_ref = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
head_sha1, &head_flag); head_sha1, &head_flag);
if (head_ref && (head_flag & REF_ISSYMREF) && if (head_ref && (head_flag & REF_ISSYMREF) &&
@ -2921,6 +2907,7 @@ static int commit_ref_update(struct ref_lock *lock,
} }
} }
} }
if (commit_ref(lock)) { if (commit_ref(lock)) {
strbuf_addf(err, "couldn't set '%s'", lock->ref_name); strbuf_addf(err, "couldn't set '%s'", lock->ref_name);
unlock_ref(lock); unlock_ref(lock);
@ -3026,7 +3013,6 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
lock = xcalloc(1, sizeof(struct ref_lock)); lock = xcalloc(1, sizeof(struct ref_lock));
lock->lk = &head_lock; lock->lk = &head_lock;
lock->ref_name = xstrdup(head_rel); lock->ref_name = xstrdup(head_rel);
lock->orig_ref_name = xstrdup(head_rel);
ret = create_symref_locked(lock, head_rel, target, NULL); ret = create_symref_locked(lock, head_rel, target, NULL);