diff options
author | Miklos Vajna <vmiklos@frugalware.org> | 2008-10-26 03:33:56 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-10-26 14:42:57 -0700 |
commit | eca35a25a92a1ad725af2a549fc9158488c4cc43 (patch) | |
tree | d598c2304f5c3f6d4bee5aa2cb4ce15fab117bf2 /refs.c | |
parent | 031e6c898f61db1ae0c0be641eac6532c1000d56 (diff) | |
download | git-eca35a25a92a1ad725af2a549fc9158488c4cc43.tar.gz git-eca35a25a92a1ad725af2a549fc9158488c4cc43.tar.xz |
Fix git branch -m for symrefs.
This had two problems with symrefs. First, it copied the actual sha1
instead of the "pointer", second it failed to remove the old ref after a
successful rename.
Given that till now delete_ref() always dereferenced symrefs, a new
parameters has been introduced to delete_ref() to allow deleting refs
without a dereference.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 59 |
1 files changed, 37 insertions, 22 deletions
@@ -912,25 +912,33 @@ static int repack_without_ref(const char *refname) return commit_lock_file(&packlock); } -int delete_ref(const char *refname, const unsigned char *sha1) +int delete_ref(const char *refname, const unsigned char *sha1, int delopt) { struct ref_lock *lock; - int err, i, ret = 0, flag = 0; + int err, i = 0, ret = 0, flag = 0; lock = lock_ref_sha1_basic(refname, sha1, 0, &flag); if (!lock) return 1; if (!(flag & REF_ISPACKED)) { /* loose */ - i = strlen(lock->lk->filename) - 5; /* .lock */ - lock->lk->filename[i] = 0; - err = unlink(lock->lk->filename); + const char *path; + + if (!(delopt & REF_NODEREF)) { + i = strlen(lock->lk->filename) - 5; /* .lock */ + lock->lk->filename[i] = 0; + path = lock->lk->filename; + } else { + path = git_path(refname); + } + err = unlink(path); if (err && errno != ENOENT) { ret = 1; error("unlink(%s) failed: %s", - lock->lk->filename, strerror(errno)); + path, strerror(errno)); } - lock->lk->filename[i] = '.'; + if (!(delopt & REF_NODEREF)) + lock->lk->filename[i] = '.'; } /* removing the loose one could have resurrected an earlier * packed one. Also, if it was not loose we need to repack @@ -955,11 +963,16 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg) struct ref_lock *lock; struct stat loginfo; int log = !lstat(git_path("logs/%s", oldref), &loginfo); + const char *symref = NULL; + int is_symref = 0; if (S_ISLNK(loginfo.st_mode)) return error("reflog for %s is a symlink", oldref); - if (!resolve_ref(oldref, orig_sha1, 1, &flag)) + symref = resolve_ref(oldref, orig_sha1, 1, &flag); + if (flag & REF_ISSYMREF) + is_symref = 1; + if (!symref) return error("refname %s not found", oldref); if (!is_refname_available(newref, oldref, get_packed_refs(), 0)) @@ -979,12 +992,12 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg) return error("unable to move logfile logs/%s to tmp-renamed-log: %s", oldref, strerror(errno)); - if (delete_ref(oldref, orig_sha1)) { + if (delete_ref(oldref, orig_sha1, REF_NODEREF)) { error("unable to delete old %s", oldref); goto rollback; } - if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1)) { + if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1, REF_NODEREF)) { if (errno==EISDIR) { if (remove_empty_directories(git_path("%s", newref))) { error("Directory not empty: %s", newref); @@ -1022,18 +1035,20 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg) } logmoved = log; - lock = lock_ref_sha1_basic(newref, NULL, 0, NULL); - if (!lock) { - error("unable to lock %s for update", newref); - goto rollback; - } - - lock->force_write = 1; - hashcpy(lock->old_sha1, orig_sha1); - if (write_ref_sha1(lock, orig_sha1, logmsg)) { - error("unable to write current sha1 into %s", newref); - goto rollback; - } + if (!is_symref) { + lock = lock_ref_sha1_basic(newref, NULL, 0, NULL); + if (!lock) { + error("unable to lock %s for update", newref); + goto rollback; + } + lock->force_write = 1; + hashcpy(lock->old_sha1, orig_sha1); + if (write_ref_sha1(lock, orig_sha1, logmsg)) { + error("unable to write current sha1 into %s", newref); + goto rollback; + } + } else + create_symref(newref, symref, logmsg); return 0; |