From: Stefan Beller <sbeller@google.com>
To: gitster@pobox.com, git@vger.kernel.org, ronniesahlberg@gmail.com,
mhagger@alum.mit.edu, jrnieder@gmail.com
Cc: Ronnie Sahlberg <sahlberg@google.com>,
Stefan Beller <sbeller@google.com>
Subject: [PATCH 4/4] reflog.c: use a reflog transaction when writing during expire
Date: Mon, 1 Dec 2014 23:46:42 -0800 [thread overview]
Message-ID: <1417506402-24257-5-git-send-email-sbeller@google.com> (raw)
In-Reply-To: <1417506402-24257-1-git-send-email-sbeller@google.com>
From: Ronnie Sahlberg <sahlberg@google.com>
Use a transaction for all updates during expire_reflog.
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
no changes since sending it 5 days ago.
builtin/reflog.c | 86 ++++++++++++++++++++++++--------------------------------
1 file changed, 37 insertions(+), 49 deletions(-)
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 2d85d26..55f3023 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -33,7 +33,8 @@ struct cmd_reflog_expire_cb {
};
struct expire_reflog_cb {
- FILE *newlog;
+ struct transaction *t;
+ const char *refname;
enum {
UE_NORMAL,
UE_ALWAYS,
@@ -290,7 +291,7 @@ static int unreachable(struct expire_reflog_cb *cb, struct commit *commit, unsig
static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
const char *email, unsigned long timestamp, int tz,
- const char *message, void *cb_data)
+ const char *message, void *cb_data, struct strbuf *err)
{
struct expire_reflog_cb *cb = cb_data;
struct commit *old, *new;
@@ -316,20 +317,18 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
if (cb->cmd->recno && --(cb->cmd->recno) == 0)
goto prune;
- if (cb->newlog) {
- char sign = (tz < 0) ? '-' : '+';
- int zone = (tz < 0) ? (-tz) : tz;
- fprintf(cb->newlog, "%s %s %s %lu %c%04d\t%s",
- sha1_to_hex(osha1), sha1_to_hex(nsha1),
- email, timestamp, sign, zone,
- message);
+ if (cb->t) {
+ if (transaction_update_reflog(cb->t, cb->refname, nsha1, osha1,
+ email, timestamp, tz, message, 0,
+ err))
+ return -1;
hashcpy(cb->last_kept_sha1, nsha1);
}
if (cb->cmd->verbose)
printf("keep %s", message);
return 0;
prune:
- if (!cb->newlog)
+ if (!cb->t)
printf("would prune %s", message);
else if (cb->cmd->verbose)
printf("prune %s", message);
@@ -353,29 +352,27 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
{
struct cmd_reflog_expire_cb *cmd = cb_data;
struct expire_reflog_cb cb;
- struct ref_lock *lock;
- char *log_file, *newlog_path = NULL;
struct commit *tip_commit;
struct commit_list *tips;
+ struct strbuf err = STRBUF_INIT;
int status = 0;
memset(&cb, 0, sizeof(cb));
+ cb.refname = ref;
- /*
- * we take the lock for the ref itself to prevent it from
- * getting updated.
- */
- lock = lock_any_ref_for_update(ref, sha1, 0, NULL);
- if (!lock)
- return error("cannot lock ref '%s'", ref);
- log_file = git_pathdup("logs/%s", ref);
if (!reflog_exists(ref))
goto finish;
- if (!cmd->dry_run) {
- newlog_path = git_pathdup("logs/%s.lock", ref);
- cb.newlog = fopen(newlog_path, "w");
+ cb.t = transaction_begin(&err);
+ if (!cb.t) {
+ status |= error("%s", err.buf);
+ goto cleanup;
+ }
+ if (transaction_update_reflog(cb.t, cb.refname, null_sha1, null_sha1,
+ NULL, 0, 0, NULL, REFLOG_TRUNCATE,
+ &err)) {
+ status |= error("%s", err.buf);
+ goto cleanup;
}
-
cb.cmd = cmd;
if (!cmd->expire_unreachable || !strcmp(ref, "HEAD")) {
@@ -407,7 +404,10 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
mark_reachable(&cb);
}
- for_each_reflog_ent(ref, expire_reflog_ent, &cb);
+ if (for_each_reflog_ent(ref, expire_reflog_ent, &cb)) {
+ status |= error("%s", err.buf);
+ goto cleanup;
+ }
if (cb.unreachable_expire_kind != UE_ALWAYS) {
if (cb.unreachable_expire_kind == UE_HEAD) {
@@ -420,32 +420,20 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
}
}
finish:
- if (cb.newlog) {
- if (fclose(cb.newlog)) {
- status |= error("%s: %s", strerror(errno),
- newlog_path);
- unlink(newlog_path);
- } else if (cmd->updateref &&
- (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);
- unlink(newlog_path);
- } else if (rename(newlog_path, log_file)) {
- status |= error("cannot rename %s to %s",
- newlog_path, log_file);
- unlink(newlog_path);
- } else if (cmd->updateref && commit_ref(lock)) {
- status |= error("Couldn't set %s", lock->ref_name);
- } else {
- adjust_shared_perm(log_file);
+ if (!cmd->dry_run) {
+ if (cmd->updateref &&
+ 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(newlog_path);
- free(log_file);
- unlock_ref(lock);
+ cleanup:
+ transaction_free(cb.t);
+ strbuf_release(&err);
return status;
}
--
2.2.0
next prev parent reply other threads:[~2014-12-02 7:47 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-02 7:46 [PATCHv2 0/4] refs.c: use transactions for the reflog Stefan Beller
2014-12-02 7:46 ` [PATCH 1/4] refs.c: rename the transaction functions Stefan Beller
2014-12-03 2:24 ` Jonathan Nieder
2014-12-02 7:46 ` [PATCH 2/4] refs.c: rename transaction.updates to transaction.ref_updates Stefan Beller
2014-12-03 2:43 ` Jonathan Nieder
2014-12-02 7:46 ` [PATCH 3/4] refs.c: add a transaction function to append a reflog entry Stefan Beller
2014-12-03 3:15 ` Jonathan Nieder
2014-12-03 22:28 ` Stefan Beller
2014-12-03 22:52 ` Jonathan Nieder
2014-12-02 7:46 ` Stefan Beller [this message]
2014-12-03 3:18 ` [PATCH 4/4] reflog.c: use a reflog transaction when writing during expire Jonathan Nieder
2014-12-03 18:05 ` [PATCHv2 0/4] refs.c: use transactions for the reflog Junio C Hamano
-- strict thread matches above, loose matches on Subject: below --
2014-12-02 2:02 [PATCH 1/4] refs.c: rename the transaction functions Stefan Beller
2014-12-02 2:02 ` [PATCH 4/4] reflog.c: use a reflog transaction when writing during expire Stefan Beller
2014-11-20 18:17 [PATCH v3 00/14] ref-transactions-reflog Jonathan Nieder
2014-11-27 5:34 ` [PATCH 0/4] Using transactions for the reflog Stefan Beller
2014-11-27 5:34 ` [PATCH 4/4] reflog.c: use a reflog transaction when writing during expire Stefan Beller
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=1417506402-24257-5-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).