[PATCH v3 2/3] refs.c: split delete_ref_loose() into a separate flag-for-deletion and commit phase
From: Ronnie Sahlberg <hidden>
Date: 2016-06-15 23:00:41
Subsystem:
the rest · Maintainer:
Linus Torvalds
Change delete_ref_loose()) to just flag that a ref is to be deleted but do not actually unlink the files. Change commit_ref_lock() so that it will unlink refs that are flagged for deletion. Change all callers of delete_ref_loose() to explicitely call commit_ref_lock() to commit the deletion. The new pattern for deleting loose refs thus become: lock = lock_ref_sha1_basic() (or varient of) delete_ref_loose(lock) unlock_ref(lock) | commit_ref_lock(lock) Signed-off-by: Ronnie Sahlberg <redacted> --- refs.c | 31 ++++++++++++++++++++----------- refs.h | 2 ++ 2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/refs.c b/refs.c
index 815e328..ec104f2 100644
--- a/refs.c
+++ b/refs.c@@ -2484,16 +2484,9 @@ static int repack_without_ref(const char *refname) static int delete_ref_loose(struct ref_lock *lock, int flag) { - if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) { - /* loose */ - int err, i = strlen(lock->lk->filename) - 5; /* .lock */ - - lock->lk->filename[i] = 0; - err = unlink_or_warn(lock->lk->filename); - lock->lk->filename[i] = '.'; - if (err && errno != ENOENT) - return 1; - } + lock->delete_ref = 1; + lock->delete_flag = flag; + return 0; }
@@ -2515,7 +2508,7 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt) unlink_or_warn(git_path("logs/%s", lock->ref_name)); clear_loose_ref_cache(&ref_cache); - unlock_ref(lock); + ret |= commit_ref_lock(lock); return ret; }
@@ -2868,6 +2861,20 @@ int write_ref_sha1(struct ref_lock *lock, int commit_ref_lock(struct ref_lock *lock) { + if (lock->delete_ref) { + int flag = lock->delete_flag; + + if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) { + /* loose */ + int err, i = strlen(lock->lk->filename) - 5; /* .lock */ + + lock->lk->filename[i] = 0; + err = unlink_or_warn(lock->lk->filename); + lock->lk->filename[i] = '.'; + if (err && errno != ENOENT) + return 1; + } + } else if (!lock->skipped_write && commit_ref(lock)) { error("Couldn't set %s", lock->ref_name); unlock_ref(lock);
@@ -3487,6 +3494,8 @@ int ref_transaction_commit(struct ref_transaction *transaction, if (update->lock) { delnames[delnum++] = update->refname; ret |= delete_ref_loose(update->lock, update->type); + ret |= commit_ref_lock(update->lock); + update->lock = NULL; } }
diff --git a/refs.h b/refs.h
index f14a417..223be30 100644
--- a/refs.h
+++ b/refs.h@@ -9,6 +9,8 @@ struct ref_lock { int lock_fd; int force_write; int skipped_write; + int delete_ref; + int delete_flag; }; struct ref_transaction;
--
1.9.1.505.g4f1e74f