From: Stefan Beller <sbeller@google.com>
To: git@vger.kernel.org, mhagger@alum.mit.edu, jrnieder@gmail.com,
ronniesahlberg@gmail.com, gitster@pobox.com
Cc: Ronnie Sahlberg <sahlberg@google.com>,
Stefan Beller <sbeller@google.com>
Subject: [PATCH 6/8] refs.c: use a reflog transaction when writing during expire
Date: Fri, 5 Dec 2014 18:46:33 -0800 [thread overview]
Message-ID: <1417833995-25687-7-git-send-email-sbeller@google.com> (raw)
In-Reply-To: <1417833995-25687-1-git-send-email-sbeller@google.com>
From: Ronnie Sahlberg <sahlberg@google.com>
Use a transaction for all updates during expire_reflog.
[sb: This was once a patch series on its own. I cherry-picked these
patches on top of Michaels series to cleanup the refs api. So any
anomalies and bugs may be introduced by me.]
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
Notes:
Maybe we can leave out the first patch of the series
as this one deletes the changes made in the first patch of the series.
Originally authored by Ronnie for the reflogs.c file,
cherrypicked over to the refs.c file by Stefan
refs.c | 85 +++++++++++++++++++++++++++---------------------------------------
1 file changed, 35 insertions(+), 50 deletions(-)
diff --git a/refs.c b/refs.c
index 57f4941..295ea09 100644
--- a/refs.c
+++ b/refs.c
@@ -4100,8 +4100,10 @@ struct expire_reflog_cb {
unsigned int flags;
reflog_expiry_select_fn *select_fn;
void *policy_cb;
- FILE *newlog;
+ struct transaction *t;
+ const char *refname;
unsigned char last_kept_sha1[20];
+ struct strbuf *err;
};
static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
@@ -4116,15 +4118,18 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
if ((*cb->select_fn)(osha1, nsha1, email, timestamp, tz,
message, policy_cb)) {
- if (!cb->newlog)
+ if (!cb->t)
printf("would prune %s", message);
else if (cb->flags & EXPIRE_REFLOGS_VERBOSE)
printf("prune %s", message);
} else {
- if (cb->newlog) {
- fprintf(cb->newlog, "%s %s %s %lu %+05d\t%s",
- sha1_to_hex(osha1), sha1_to_hex(nsha1),
- email, timestamp, tz, message);
+ if (cb->t) {
+ if (transaction_update_reflog(cb->t, cb->refname,
+ nsha1, osha1,
+ email, timestamp,
+ tz, message,
+ cb->err))
+ return -1;
hashcpy(cb->last_kept_sha1, nsha1);
}
if (cb->flags & EXPIRE_REFLOGS_VERBOSE)
@@ -4133,8 +4138,6 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
return 0;
}
-static struct lock_file reflog_lock;
-
extern int reflog_expire(const char *refname, const unsigned char *sha1,
unsigned int flags,
reflog_expiry_prepare_fn prepare_fn,
@@ -4143,66 +4146,48 @@ extern int reflog_expire(const char *refname, const unsigned char *sha1,
void *policy_cb_data)
{
struct expire_reflog_cb cb;
- struct ref_lock *lock;
- char *log_file;
int status = 0;
+ struct strbuf err = STRBUF_INIT;
memset(&cb, 0, sizeof(cb));
cb.flags = flags;
cb.policy_cb = policy_cb_data;
cb.select_fn = select_fn;
+ cb.err = &err;
+ cb.refname = refname;
/*
- * we take the lock for the ref itself to prevent it from
- * getting updated.
+ * todo: we need to take the lock for the ref itself to
+ * prevent it from getting updated.
*/
- lock = lock_ref_sha1_basic(refname, sha1, NULL, 0, NULL);
- if (!lock)
- return error("cannot lock ref '%s'", refname);
- if (!reflog_exists(refname)) {
- unlock_ref(lock);
- return 0;
+ cb.t = transaction_begin(&err);
+ if (!cb.t) {
+ status |= error("%s", err.buf);
+ goto cleanup;
}
-
- log_file = git_pathdup("logs/%s", refname);
- if (!(flags & EXPIRE_REFLOGS_DRY_RUN)) {
- if (hold_lock_file_for_update(&reflog_lock, log_file, 0) < 0)
- goto failure;
- cb.newlog = fdopen_lock_file(&reflog_lock, "w");
- if (!cb.newlog)
- goto failure;
+ if (transaction_delete_reflog(cb.t, cb.refname, &err)) {
+ status |= error("%s", err.buf);
+ goto cleanup;
}
(*prepare_fn)(refname, sha1, cb.policy_cb);
for_each_reflog_ent(refname, expire_reflog_ent, &cb);
(*cleanup_fn)(cb.policy_cb);
+
if (!(flags & EXPIRE_REFLOGS_DRY_RUN)) {
- if (close_lock_file(&reflog_lock)) {
- status |= error("Couldn't write %s: %s", log_file,
- strerror(errno));
- } else if ((flags & EXPIRE_REFLOGS_UPDATE_REF) &&
- (write_in_full(lock->lock_fd,
- sha1_to_hex(cb.last_kept_sha1), 40) != 40 ||
- write_str_in_full(lock->lock_fd, "\n") != 1 ||
- close_ref(lock) < 0)) {
- status |= error("Couldn't write %s",
- lock->lk->filename.buf);
- rollback_lock_file(&reflog_lock);
- } else if (commit_lock_file(&reflog_lock)) {
- status |= error("cannot rename %s.lock to %s",
- log_file, log_file);
- } else if ((flags & EXPIRE_REFLOGS_UPDATE_REF) && commit_ref(lock)) {
- status |= error("Couldn't set %s", lock->ref_name);
+ if ((flags & EXPIRE_REFLOGS_UPDATE_REF) &&
+ transaction_update_ref(cb.t, cb.refname,
+ cb.last_kept_sha1, sha1,
+ 0, 1, NULL, &err)) {
+ status |= error("%s", err.buf);
+ goto cleanup;
}
+ if (transaction_commit(cb.t, &err))
+ status |= error("%s", err.buf);
}
- free(log_file);
- unlock_ref(lock);
+cleanup:
+ transaction_free(cb.t);
+ strbuf_release(&err);
return status;
-
- failure:
- rollback_lock_file(&reflog_lock);
- free(log_file);
- unlock_ref(lock);
- return -1;
}
--
2.2.0
next prev parent reply other threads:[~2014-12-06 2:47 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-06 2:46 [PATCH 0/8] Making reflog modifications part of the transactions API Stefan Beller
2014-12-06 2:46 ` [PATCH 1/8] refs.c: let fprintf handle the formatting Stefan Beller
2014-12-06 2:46 ` [PATCH 2/8] refs.c: rename the transaction functions Stefan Beller
2014-12-11 21:42 ` Junio C Hamano
2014-12-11 21:48 ` Stefan Beller
2014-12-06 2:46 ` [PATCH 3/8] refs.c: rename transaction.updates to transaction.ref_updates Stefan Beller
2014-12-06 2:46 ` [PATCH 4/8] refs.c: add transaction function to append to the reflog Stefan Beller
2014-12-11 21:50 ` Junio C Hamano
2014-12-06 2:46 ` [PATCH 5/8] refs.c: add transaction function to delete " Stefan Beller
2014-12-06 2:46 ` Stefan Beller [this message]
2014-12-06 2:46 ` [PATCH 7/8] refs.c: rename log_ref_setup to create_reflog Stefan Beller
2014-12-06 2:46 ` [PATCH 8/8] refs.c: allow deleting refs with a broken sha1 Stefan Beller
2014-12-08 20:05 ` [PATCH 0/8] Making reflog modifications part of the transactions API Stefan Beller
2014-12-08 21:54 ` Jonathan Nieder
2014-12-12 16:17 ` Michael Haggerty
2014-12-12 20:51 ` Stefan Beller
2014-12-12 21:16 ` ronnie sahlberg
2014-12-14 23:17 ` Michael Haggerty
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1417833995-25687-7-git-send-email-sbeller@google.com \
--to=sbeller@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jrnieder@gmail.com \
--cc=mhagger@alum.mit.edu \
--cc=ronniesahlberg@gmail.com \
--cc=sahlberg@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).