git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Beller <sbeller@google.com>
To: git@vger.kernel.org, gitster@pobox.com, mhagger@alum.mit.edu
Cc: Ronnie Sahlberg <sahlberg@google.com>,
	Jonathan Nieder <jrnieder@gmail.com>,
	Stefan Beller <sbeller@google.com>
Subject: [PATCH v3 11/14] refs.c: rename log_ref_setup to create_reflog
Date: Mon, 17 Nov 2014 17:35:47 -0800	[thread overview]
Message-ID: <1416274550-2827-12-git-send-email-sbeller@google.com> (raw)
In-Reply-To: <1416274550-2827-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: Jonathan Nieder <jrnieder@gmail.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 1571fa5..11cf26b 100644
--- a/refs.c
+++ b/refs.c
@@ -2947,16 +2947,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);
@@ -3025,16 +3025,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 9f70b89..17e3a3c 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.rc2.5.gf7b9fb2

  parent reply	other threads:[~2014-11-18  1:36 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-18  1:35 [PATCH v3 00/14] ref-transactions-reflog Stefan Beller
2014-11-18  1:35 ` [PATCH v3 01/14] refs.c: make ref_transaction_create a wrapper for ref_transaction_update Stefan Beller
2014-11-18  1:35 ` [PATCH v3 02/14] refs.c: make ref_transaction_delete " Stefan Beller
2014-11-18  1:35 ` [PATCH v3 03/14] refs.c: rename the transaction functions Stefan Beller
2014-11-18  1:35 ` [PATCH v3 04/14] refs.c: add a function to append a reflog entry to a fd Stefan Beller
2014-11-18  1:35 ` [PATCH v3 05/14] refs.c: add a new update_type field to ref_update Stefan Beller
2014-11-18  1:35 ` [PATCH v3 06/14] refs.c: add a transaction function to append a reflog entry Stefan Beller
2014-11-18  1:35 ` [PATCH v3 07/14] refs.c: add a flag to allow reflog updates to truncate the log Stefan Beller
2014-11-18  1:35 ` [PATCH v3 08/14] refs.c: only write reflog update if msg is non-NULL Stefan Beller
2014-11-18  1:35 ` [PATCH v3 09/14] refs.c: allow multiple reflog updates during a single transaction Stefan Beller
2014-11-18  1:35 ` [PATCH v3 10/14] reflog.c: use a reflog transaction when writing during expire Stefan Beller
2014-11-18  1:35 ` Stefan Beller [this message]
2014-11-18  1:35 ` [PATCH v3 12/14] refs.c: Remove unlock_ref/close_ref/commit_ref from the refs api Stefan Beller
2014-11-18  1:35 ` [PATCH v3 13/14] refs.c: remove lock_any_ref_for_update Stefan Beller
2014-11-18  1:35 ` [PATCH v3 14/14] refs.c: allow deleting refs with a broken sha1 Stefan Beller
2014-11-18 11:26 ` [PATCH v3 00/14] ref-transactions-reflog Michael Haggerty
2014-11-18 18:36   ` Ronnie Sahlberg
2014-11-18 19:46     ` Michael Haggerty
2014-11-18 20:30       ` Junio C Hamano
2014-11-18 21:16         ` Michael Haggerty
2014-11-18 21:28           ` Junio C Hamano
2014-11-19 23:22             ` Stefan Beller
2014-11-20  3:24               ` Jonathan Nieder
2014-11-20 17:34                 ` Junio C Hamano
2014-11-20 10:56               ` Michael Haggerty
2014-11-20 18:17                 ` Jonathan Nieder
2014-11-27  5:34                   ` [PATCH 0/4] Using transactions for the reflog Stefan Beller
2014-11-27  5:34                     ` [PATCH 1/4] refs.c: rename the transaction functions Stefan Beller
2014-11-27  5:34                     ` [PATCH 2/4] refs.c: add a new update_type field to ref_update Stefan Beller
2014-11-27  5:34                     ` [PATCH 3/4] refs.c: add a transaction function to append a reflog entry 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=1416274550-2827-12-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=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).