git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 08/13] refs.c: rename log_ref_setup to create_reflog

From
Stefan Beller <sbeller@google.com>
Date
Dec 4, 2014, 08:29 UTC
Message-ID
<1417681763-32334-9-git-send-email-sbeller@google.com>
In-Reply-To
<1417681763-32334-1-git-send-email-sbeller@google.com>
From: Ronnie Sahlberg <sahlberg@google.com>
log_ref_setup is used to do several semi-related things:
* Sometimes it will create a new reflog including missing parent
  directories and cleaning up any conflicting stale directories
  in the path.
* Fill in a filename buffer for the full path to the reflog.
* Unconditionally re-adjust the permissions for the file.

This function is only called from two places: In checkout.c, where it is always used to create a reflog and in refs.c log_ref_write, where it is used to create a reflog sometimes, and sometimes just to fill in the filename.

Rename log_ref_setup to create_reflog and change it to only take the refname as an argument to make its signature similar to delete_reflog and reflog_exists. Change create_reflog to ignore log_all_ref_updates and "unconditionally" create the reflog when called. Since checkout.c always wants to create a reflog we can call create_reflog directly and avoid the temp-and-log_all_ref_update dance.

In log_ref_write, only call create_reflog, iff we want to create a reflog and if the reflog does not yet exist. This means that for the common case where the log already exists we now only need to perform a single lstat() instead of a open(O_CREAT)+lstat()+close().

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/checkout.c |  8 +-------
 refs.c             | 22 +++++++++++++---------
 refs.h             |  8 +++-----
 3 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5410dac..8550b6d 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -587,19 +587,13 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
 	if (opts->new_branch) {
 		if (opts->new_orphan_branch) {
 			if (opts->new_branch_log && !log_all_ref_updates) {
-				int temp;
-				char log_file[PATH_MAX];
 				char *ref_name = mkpath("refs/heads/%s", opts->new_orphan_branch);
 
-				temp = log_all_ref_updates;
-				log_all_ref_updates = 1;
-				if (log_ref_setup(ref_name, log_file, sizeof(log_file))) {
+				if (create_reflog(ref_name)) {
 					fprintf(stderr, _("Can not do reflog for '%s'\n"),
 					    opts->new_orphan_branch);
-					log_all_ref_updates = temp;
 					return;
 				}
-				log_all_ref_updates = temp;
 			}
 		}
 		else
diff --git a/refs.c b/refs.c
index c411af9..bdd3f75 100644
--- a/refs.c
+++ b/refs.c
@@ -2941,16 +2941,16 @@ static int copy_msg(char *buf, const char *msg)
 }
 
 /* This function must set a meaningful errno on failure */
-int log_ref_setup(const char *refname, char *logfile, int bufsize)
+int create_reflog(const char *refname)
 {
 	int logfd, oflags = O_APPEND | O_WRONLY;
+	char logfile[PATH_MAX];
 
-	git_snpath(logfile, bufsize, "logs/%s", refname);
-	if (log_all_ref_updates &&
-	    (starts_with(refname, "refs/heads/") ||
-	     starts_with(refname, "refs/remotes/") ||
-	     starts_with(refname, "refs/notes/") ||
-	     !strcmp(refname, "HEAD"))) {
+	git_snpath(logfile, sizeof(logfile), "logs/%s", refname);
+	if (starts_with(refname, "refs/heads/") ||
+	    starts_with(refname, "refs/remotes/") ||
+	    starts_with(refname, "refs/notes/") ||
+	    !strcmp(refname, "HEAD")) {
 		if (safe_create_leading_directories(logfile) < 0) {
 			int save_errno = errno;
 			error("unable to create directory for %s", logfile);
@@ -3019,16 +3019,20 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
 static int log_ref_write(const char *refname, const unsigned char *old_sha1,
 			 const unsigned char *new_sha1, const char *msg)
 {
-	int logfd, result, oflags = O_APPEND | O_WRONLY;
+	int logfd, result = 0, oflags = O_APPEND | O_WRONLY;
 	char log_file[PATH_MAX];
 
 	if (log_all_ref_updates < 0)
 		log_all_ref_updates = !is_bare_repository();
 
-	result = log_ref_setup(refname, log_file, sizeof(log_file));
+	if (log_all_ref_updates && !reflog_exists(refname))
+		result = create_reflog(refname);
+
 	if (result)
 		return result;
 
+	git_snpath(log_file, sizeof(log_file), "logs/%s", refname);
+
 	logfd = open(log_file, oflags);
 	if (logfd < 0)
 		return 0;
diff --git a/refs.h b/refs.h
index 1afc72c..0c75217 100644
--- a/refs.h
+++ b/refs.h
@@ -207,11 +207,6 @@ extern int commit_ref(struct ref_lock *lock);
 /** Release any lock taken but not written. **/
 extern void unlock_ref(struct ref_lock *lock);
 
-/*
- * Setup reflog before using. Set errno to something meaningful on failure.
- */
-int log_ref_setup(const char *refname, char *logfile, int bufsize);
-
 /** Reads log for the value of ref during at_time. **/
 extern int read_ref_at(const char *refname, unsigned int flags,
 		       unsigned long at_time, int cnt,
@@ -221,6 +216,9 @@ extern int read_ref_at(const char *refname, unsigned int flags,
 /** Check if a particular reflog exists */
 extern int reflog_exists(const char *refname);
 
+/** Create reflog. Set errno to something meaningful on failure. */
+extern int create_reflog(const char *refname);
+
 /** Delete a reflog */
 extern int delete_reflog(const char *refname);
 
-- 
2.2.0
Previous: Stefan BellerNext: Stefan Beller
Message 9 of 25 in “[PATCHv3 00/13] the refs-transactions-reflog series”
  1. Stefan BellerDec 4, 2014
  2. 01/13 refs.c: make ref_transaction_create a wrapper for ref_transaction_updateStefan Beller, Dec 4, 2014
  3. 02/13 refs.c: make ref_transaction_delete a wrapper for ref_transaction_updateStefan Beller, Dec 4, 2014
  4. 03/13 refs.c: add a function to append a reflog entry to a fdStefan Beller, Dec 4, 2014
  5. 04/13 refs.c: rename the transaction functionsStefan Beller, Dec 4, 2014
  6. 05/13 refs.c: rename transaction.updates to transaction.ref_updatesStefan Beller, Dec 4, 2014
  7. 06/13 refs.c: add a transaction function to truncate or append a reflog entryStefan Beller, Dec 4, 2014
  8. 07/13 reflog.c: use a reflog transaction when writing during expireStefan Beller, Dec 4, 2014
  9. 08/13 refs.c: rename log_ref_setup to create_reflogStefan Beller, Dec 4, 2014
  10. 09/13 refs.c: remove unlock_ref/close_ref/commit_ref from the refs apiStefan Beller, Dec 4, 2014
  11. 10/13 refs.c: remove lock_any_ref_for_updateStefan Beller, Dec 4, 2014
  12. 11/13 refs.c: don't expose the internal struct ref_lock in the header fileStefan Beller, Dec 4, 2014
  13. 12/13 refs.c: use a bit for ref_update have_oldStefan Beller, Dec 4, 2014
  14. Torsten BögershausenDec 4, 2014
  15. Andreas SchwabDec 4, 2014
  16. 13/13 refs.c: allow deleting refs with a broken sha1Stefan Beller, Dec 4, 2014
  17. Michael HaggertyDec 4, 2014
  18. Jonathan NiederDec 4, 2014
  19. Jonathan NiederDec 4, 2014
  20. Stefan BellerDec 4, 2014
  21. Michael HaggertyDec 4, 2014
  22. Junio C HamanoDec 4, 2014
  23. Junio C HamanoDec 4, 2014
  24. Stefan BellerDec 4, 2014
  25. Jonathan NiederDec 4, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.