[PATCH 10/31] reflog.c: use a reflog transaction when writing during expire

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use a transaction when doing the updates of the reflog during expire_reflog.

Signed-off-by: Ronnie Sahlberg <sahlberg@xxxxxxxxxx>
---
 builtin/reflog.c | 54 ++++++++++++++++++++++--------------------------------
 refs.c           |  4 ++--
 2 files changed, 24 insertions(+), 34 deletions(-)

diff --git a/builtin/reflog.c b/builtin/reflog.c
index e8a8fb1..5f07647 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 ref_transaction *t;
+	const char *refname;
 	enum {
 		UE_NORMAL,
 		UE_ALWAYS,
@@ -316,20 +317,16 @@ 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) {
+		transaction_update_reflog(cb->t, cb->refname, nsha1, osha1,
+					  email, timestamp, tz, message, 0);
 		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);
@@ -354,12 +351,12 @@ 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;
 	int status = 0;
 
 	memset(&cb, 0, sizeof(cb));
+	cb.refname = ref;
 
 	/*
 	 * we take the lock for the ref itself to prevent it from
@@ -368,12 +365,14 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
 	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();
+		transaction_update_reflog(cb.t, cb.refname,
+					  null_sha1, null_sha1, NULL,
+					  0, 0, NULL,
+					  REFLOG_TRUNCATE);
 	}
 
 	cb.cmd = cmd;
@@ -420,31 +419,22 @@ 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)) {
+	if (cb.t) {
+		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);
-			unlink(newlog_path);
-		} else if (rename(newlog_path, log_file)) {
-			status |= error("cannot rename %s to %s",
-					newlog_path, log_file);
-			unlink(newlog_path);
+			transaction_rollback(cb.t);
+		} else if (transaction_commit(cb.t, NULL)) {
+			status |= error("cannot commit reflog for %s", ref);
 		} else if (cmd->updateref && commit_ref(lock)) {
 			status |= error("Couldn't set %s", lock->ref_name);
-		} else {
-			adjust_shared_perm(log_file);
 		}
+		transaction_free(cb.t);
 	}
-	free(newlog_path);
-	free(log_file);
 	unlock_ref(lock);
 	return status;
 }
diff --git a/refs.c b/refs.c
index e7ede03..5a5f9df 100644
--- a/refs.c
+++ b/refs.c
@@ -2766,8 +2766,8 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
 		      committer);
 	if (msglen)
 		len += copy_msg(logrec + len - 1, msg) - 1;
-	written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
 
+	written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
 	free(logrec);
 	if (written != len)
 		return -1;
@@ -3634,7 +3634,7 @@ int transaction_commit(struct ref_transaction *transaction,
 		}
 	}
 
-	/* Update all reflog files
+	/* Update all reflog files.
 	   We have already done all ref updates and deletes.
 	   There is not much we can do here if there are any reflog
 	   update errors, other than complain.
-- 
2.0.0.rc3.506.g3739a35

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]