From: Junio C Hamano Date: Sun, 9 Nov 2008 00:07:37 +0000 (-0800) Subject: Merge branch 'mv/maint-branch-m-symref' into maint X-Git-Tag: v1.6.0.4~5 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/3b8572a4297d8720b359c82e1dd9afeb45cda3cd?ds=inline;hp=-c Merge branch 'mv/maint-branch-m-symref' into maint * mv/maint-branch-m-symref: update-ref --no-deref -d: handle the case when the pointed ref is packed git branch -m: forbid renaming of a symref Fix git update-ref --no-deref -d. rename_ref(): handle the case when the reflog of a ref does not exist Fix git branch -m for symrefs. --- 3b8572a4297d8720b359c82e1dd9afeb45cda3cd diff --combined builtin-send-pack.c index 301f230432,ea1ad6e35f..ed94f9a460 --- a/builtin-send-pack.c +++ b/builtin-send-pack.c @@@ -132,13 -132,7 +132,13 @@@ static struct ref *remote_refs, **remot static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data) { struct ref *ref; - int len = strlen(refname) + 1; + int len; + + /* we already know it starts with refs/ to get here */ + if (check_ref_format(refname + 5)) + return 0; + + len = strlen(refname) + 1; ref = xcalloc(1, sizeof(*ref) + len); hashcpy(ref->new_sha1, sha1); memcpy(ref->name, refname, len); @@@ -232,7 -226,7 +232,7 @@@ static void update_tracking_ref(struct if (args.verbose) fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst); if (ref->deletion) { - delete_ref(rs.dst, NULL); + delete_ref(rs.dst, NULL, 0); } else update_ref("update by push", rs.dst, ref->new_sha1, NULL, 0, 0); diff --combined cache.h index 74339edaaa,715348a066..39f24ad827 --- a/cache.h +++ b/cache.h @@@ -270,7 -270,6 +270,7 @@@ static inline void remove_name_hash(str #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options)) #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) #define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase)) +#define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen)) #endif enum object_type { @@@ -383,7 -382,6 +383,7 @@@ extern int add_to_index(struct index_st extern int add_file_to_index(struct index_state *, const char *path, int flags); extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); +extern int index_name_is_other(const struct index_state *, const char *, int); /* do stat comparison even if CE_VALID is true */ #define CE_MATCH_IGNORE_VALID 01 @@@ -413,8 -411,6 +413,8 @@@ struct lock_file char on_list; char filename[PATH_MAX]; }; +#define LOCK_DIE_ON_ERROR 1 +#define LOCK_NODEREF 2 extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int hold_lock_file_for_append(struct lock_file *, const char *path, int); extern int commit_lock_file(struct lock_file *); @@@ -424,7 -420,7 +424,7 @@@ extern int commit_locked_index(struct l extern void set_alternate_index_output(const char *); extern int close_lock_file(struct lock_file *); extern void rollback_lock_file(struct lock_file *); - extern int delete_ref(const char *, const unsigned char *sha1); + extern int delete_ref(const char *, const unsigned char *sha1, int delopt); /* Environment bits from configuration mechanism */ extern int trust_executable_bit; diff --combined refs.c index 9e422dcccb,0d239e15b0..156714e54e --- a/refs.c +++ b/refs.c @@@ -790,7 -790,7 +790,7 @@@ static struct ref_lock *lock_ref_sha1_b struct ref_lock *lock; struct stat st; int last_errno = 0; - int type; + int type, lflags; int mustexist = (old_sha1 && !is_null_sha1(old_sha1)); lock = xcalloc(1, sizeof(struct ref_lock)); @@@ -830,11 -830,8 +830,11 @@@ lock->lk = xcalloc(1, sizeof(struct lock_file)); - if (flags & REF_NODEREF) + lflags = LOCK_DIE_ON_ERROR; + if (flags & REF_NODEREF) { ref = orig_ref; + lflags |= LOCK_NODEREF; + } lock->ref_name = xstrdup(ref); lock->orig_ref_name = xstrdup(orig_ref); ref_file = git_path("%s", ref); @@@ -848,8 -845,8 +848,8 @@@ error("unable to create directory for %s", ref_file); goto error_return; } - lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, 1); + lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags); return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock; error_return: @@@ -915,25 -912,33 +915,33 @@@ static int repack_without_ref(const cha 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)) { + if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) { /* 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 @@@ -958,11 -963,16 +966,16 @@@ int rename_ref(const char *oldref, cons struct ref_lock *lock; struct stat 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)) @@@ -982,12 -992,12 +995,12 @@@ 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); @@@ -1030,7 -1040,6 +1043,6 @@@ 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)) {