From: Junio C Hamano Date: Wed, 9 Nov 2011 00:35:53 +0000 (-0800) Subject: Merge branch 'jc/maint-remove-renamed-ref' into maint X-Git-Tag: v1.7.7.3~1 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=916034b93ce45bdedfb1c5cef270e6eba2a26fea;p=git.git Merge branch 'jc/maint-remove-renamed-ref' into maint * jc/maint-remove-renamed-ref: branch -m/-M: remove undocumented RENAMED-REF Conflicts: refs.c --- 916034b93ce45bdedfb1c5cef270e6eba2a26fea diff --cc refs.c index a615043b3,ecfc22c36..fb258ea99 --- a/refs.c +++ b/refs.c @@@ -1200,53 -784,35 +1200,45 @@@ int delete_ref(const char *refname, con return ret; } -int rename_ref(const char *oldref, const char *newref) +/* + * People using contrib's git-new-workdir have .git/logs/refs -> + * /some/other/path/.git/logs/refs, and that may live on another device. + * + * IOW, to avoid cross device rename errors, the temporary renamed log must + * live into logs/refs. + */ +#define TMP_RENAMED_LOG "logs/refs/.tmp-renamed-log" + +int rename_ref(const char *oldref, const char *newref, const char *logmsg) { - static const char renamed_ref[] = "RENAMED-REF"; unsigned char sha1[20], orig_sha1[20]; int flag = 0, logmoved = 0; struct ref_lock *lock; - char msg[PATH_MAX*2 + 100]; struct stat loginfo; - int log = !stat(git_path("logs/%s", oldref), &loginfo); + int log = !lstat(git_path("logs/%s", oldref), &loginfo); + const char *symref = NULL; - if (S_ISLNK(loginfo.st_mode)) + if (log && 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) + return error("refname %s is a symbolic ref, renaming it is not supported", + oldref); + if (!symref) return error("refname %s not found", oldref); - if (!is_refname_available(newref, oldref, get_packed_refs(), 0)) + if (!is_refname_available(newref, oldref, get_packed_refs(NULL), 0)) return 1; - if (!is_refname_available(newref, oldref, get_loose_refs(), 0)) + if (!is_refname_available(newref, oldref, get_loose_refs(NULL), 0)) return 1; - lock = lock_ref_sha1_basic(renamed_ref, NULL, 0, NULL); - if (!lock) - return error("unable to lock %s", renamed_ref); - lock->force_write = 1; - if (write_ref_sha1(lock, orig_sha1, logmsg)) - return error("unable to save current sha1 in %s", renamed_ref); - if (snprintf(msg, sizeof(msg), "renamed %s to %s", oldref, newref) > sizeof(msg)) - return error("Refnames to long"); -- - if (log && rename(git_path("logs/%s", oldref), git_path("tmp-renamed-log"))) - return error("unable to move logfile logs/%s to tmp-renamed-log: %s", + if (log && rename(git_path("logs/%s", oldref), git_path(TMP_RENAMED_LOG))) + 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; }