From a4c653dfcd05c987028b847092a1ee7e5d86a596 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 21 Jul 2015 17:04:50 -0400 Subject: refs.c: add err arguments to reflog functions Add an err argument to log_ref_setup that can explain the reason for a failure. This then eliminates the need to manage errno through this function since we can just add strerror(errno) to the err string when meaningful. No callers relied on errno from this function for anything else than the error message. Also add err arguments to private functions write_ref_to_lockfile, log_ref_write_1, commit_ref_update. This again eliminates the need to manage errno in these functions. Some error messages are slightly reordered. Update of a patch by Ronnie Sahlberg. Signed-off-by: Ronnie Sahlberg Signed-off-by: David Turner Signed-off-by: Junio C Hamano --- refs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'refs.h') diff --git a/refs.h b/refs.h index 8c3d433a8a..7cfc2e080e 100644 --- a/refs.h +++ b/refs.h @@ -189,9 +189,9 @@ extern int peel_ref(const char *refname, unsigned char *sha1); #define REF_NODEREF 0x01 /* - * Setup reflog before using. Set errno to something meaningful on failure. + * Setup reflog before using. Fill in err and return -1 on failure. */ -int log_ref_setup(const char *refname, struct strbuf *logfile); +int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err); /** Reads log for the value of ref during at_time. **/ extern int read_ref_at(const char *refname, unsigned int flags, -- cgit v1.3-5-g9baa From abd0cd3a3018e1c4e9e4437fb3911d6658e99fec Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 21 Jul 2015 17:04:52 -0400 Subject: refs: new public ref function: safe_create_reflog The safe_create_reflog function creates a reflog, if it does not already exist. The log_ref_setup function becomes private and gains a force_create parameter to force the creation of a reflog even if log_all_ref_updates is false or the refname is not one of the special refnames. The new parameter also reduces the need to store, modify, and restore the log_all_ref_updates global before reflog creation. In a moment, we will use this to add reflog creation commands to git-reflog. Signed-off-by: David Turner Signed-off-by: Junio C Hamano --- builtin/checkout.c | 14 +++++--------- refs.c | 24 ++++++++++++++++++++---- refs.h | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) (limited to 'refs.h') diff --git a/builtin/checkout.c b/builtin/checkout.c index 8faa2d141d..3eaa73b983 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -619,24 +619,20 @@ 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; - struct strbuf log_file = STRBUF_INIT; int ret; - const char *ref_name; + char *refname; struct strbuf err = STRBUF_INIT; - ref_name = mkpath("refs/heads/%s", opts->new_orphan_branch); - temp = log_all_ref_updates; - log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, &log_file, &err); - log_all_ref_updates = temp; - strbuf_release(&log_file); + refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch); + ret = safe_create_reflog(refname, 1, &err); + free(refname); if (ret) { fprintf(stderr, _("Can not do reflog for '%s': %s\n"), opts->new_orphan_branch, err.buf); strbuf_release(&err); return; } + strbuf_release(&err); } } else diff --git a/refs.c b/refs.c index f5dbf01e1e..57074b555c 100644 --- a/refs.c +++ b/refs.c @@ -3063,8 +3063,13 @@ static int should_autocreate_reflog(const char *refname) !strcmp(refname, "HEAD"); } -/* This function will fill in *err and return -1 on failure */ -int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) +/* + * Create a reflog for a ref. If force_create = 0, the reflog will + * only be created for certain refs (those for which + * should_autocreate_reflog returns non-zero. Otherwise, create it + * regardless of the ref name. Fill in *err and return -1 on failure. + */ +static int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err, int force_create) { int logfd, oflags = O_APPEND | O_WRONLY; char *logfile; @@ -3073,7 +3078,7 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf logfile = sb_logfile->buf; /* make sure the rest of the function can't change "logfile" */ sb_logfile = NULL; - if (should_autocreate_reflog(refname)) { + if (force_create || should_autocreate_reflog(refname)) { if (safe_create_leading_directories(logfile) < 0) { strbuf_addf(err, "unable to create directory for %s: " "%s", logfile, strerror(errno)); @@ -3108,6 +3113,17 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf return 0; } + +int safe_create_reflog(const char *refname, int force_create, struct strbuf *err) +{ + int ret; + struct strbuf sb = STRBUF_INIT; + + ret = log_ref_setup(refname, &sb, err, force_create); + strbuf_release(&sb); + return ret; +} + static int log_ref_write_fd(int fd, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *committer, const char *msg) @@ -3144,7 +3160,7 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, if (log_all_ref_updates < 0) log_all_ref_updates = !is_bare_repository(); - result = log_ref_setup(refname, sb_log_file, err); + result = log_ref_setup(refname, sb_log_file, err, 0); if (result) return result; diff --git a/refs.h b/refs.h index 7cfc2e080e..de68a452b7 100644 --- a/refs.h +++ b/refs.h @@ -191,7 +191,7 @@ extern int peel_ref(const char *refname, unsigned char *sha1); /* * Setup reflog before using. Fill in err and return -1 on failure. */ -int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err); +int safe_create_reflog(const char *refname, int force_create, struct strbuf *err); /** Reads log for the value of ref during at_time. **/ extern int read_ref_at(const char *refname, unsigned int flags, -- cgit v1.3-5-g9baa From 0f2a71d9923b4cf010ad0801eb71ee3666798204 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 21 Jul 2015 17:04:54 -0400 Subject: refs: add REF_FORCE_CREATE_REFLOG flag Add a flag to allow forcing the creation of a reflog even if the ref name and core.logAllRefUpdates setting would not ordinarily cause ref creation. In a moment, we will use this to add options to git tag and git update-ref to force reflog creation. Signed-off-by: David Turner Signed-off-by: Junio C Hamano --- refs.c | 34 +++++++++++++++++++++------------- refs.h | 1 + 2 files changed, 22 insertions(+), 13 deletions(-) (limited to 'refs.h') diff --git a/refs.c b/refs.c index 57074b555c..97a75f3c31 100644 --- a/refs.c +++ b/refs.c @@ -62,6 +62,11 @@ static unsigned char refname_disposition[256] = { */ #define REF_NEEDS_COMMIT 0x20 +/* + * 0x40 is REF_FORCE_CREATE_REFLOG, so skip it if you're adding a + * value to ref_update::flags + */ + /* * Try to read one refname component from the front of refname. * Return the length of the component found, or -1 if the component is @@ -2914,7 +2919,7 @@ static int write_ref_to_lockfile(struct ref_lock *lock, const unsigned char *sha1, struct strbuf *err); static int commit_ref_update(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, - struct strbuf *err); + int flags, struct strbuf *err); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { @@ -2976,7 +2981,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms hashcpy(lock->old_oid.hash, orig_sha1); if (write_ref_to_lockfile(lock, orig_sha1, &err) || - commit_ref_update(lock, orig_sha1, logmsg, &err)) { + commit_ref_update(lock, orig_sha1, logmsg, 0, &err)) { error("unable to write current sha1 into %s: %s", newrefname, err.buf); strbuf_release(&err); goto rollback; @@ -2995,7 +3000,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms flag = log_all_ref_updates; log_all_ref_updates = 0; if (write_ref_to_lockfile(lock, orig_sha1, &err) || - commit_ref_update(lock, orig_sha1, NULL, &err)) { + commit_ref_update(lock, orig_sha1, NULL, 0, &err)) { error("unable to write current sha1 into %s: %s", oldrefname, err.buf); strbuf_release(&err); } @@ -3152,7 +3157,8 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1, static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *msg, - struct strbuf *sb_log_file, struct strbuf *err) + struct strbuf *sb_log_file, int flags, + struct strbuf *err) { int logfd, result, oflags = O_APPEND | O_WRONLY; char *log_file; @@ -3160,7 +3166,7 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, if (log_all_ref_updates < 0) log_all_ref_updates = !is_bare_repository(); - result = log_ref_setup(refname, sb_log_file, err, 0); + result = log_ref_setup(refname, sb_log_file, err, flags & REF_FORCE_CREATE_REFLOG); if (result) return result; @@ -3189,10 +3195,11 @@ static int log_ref_write_1(const char *refname, 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, - struct strbuf *err) + int flags, struct strbuf *err) { struct strbuf sb = STRBUF_INIT; - int ret = log_ref_write_1(refname, old_sha1, new_sha1, msg, &sb, err); + int ret = log_ref_write_1(refname, old_sha1, new_sha1, msg, &sb, flags, + err); strbuf_release(&sb); return ret; } @@ -3246,12 +3253,12 @@ static int write_ref_to_lockfile(struct ref_lock *lock, */ static int commit_ref_update(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, - struct strbuf *err) + int flags, struct strbuf *err) { clear_loose_ref_cache(&ref_cache); - if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, err) < 0 || + if (log_ref_write(lock->ref_name, lock->old_oid.hash, sha1, logmsg, flags, err) < 0 || (strcmp(lock->ref_name, lock->orig_ref_name) && - log_ref_write(lock->orig_ref_name, lock->old_oid.hash, sha1, logmsg, err) < 0)) { + log_ref_write(lock->orig_ref_name, lock->old_oid.hash, sha1, logmsg, flags, err) < 0)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, "Cannot update the ref '%s': %s", lock->ref_name, old_msg); @@ -3281,7 +3288,7 @@ static int commit_ref_update(struct ref_lock *lock, !strcmp(head_ref, lock->ref_name)) { struct strbuf log_err = STRBUF_INIT; if (log_ref_write("HEAD", lock->old_oid.hash, sha1, - logmsg, &log_err)) { + logmsg, 0, &log_err)) { error("%s", log_err.buf); strbuf_release(&log_err); } @@ -3355,7 +3362,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master, done: #endif if (logmsg && !read_ref(refs_heads_master, new_sha1) && - log_ref_write(ref_target, old_sha1, new_sha1, logmsg, &err)) { + log_ref_write(ref_target, old_sha1, new_sha1, logmsg, 0, &err)) { error("%s", err.buf); strbuf_release(&err); } @@ -4032,7 +4039,8 @@ int ref_transaction_commit(struct ref_transaction *transaction, if (update->flags & REF_NEEDS_COMMIT) { if (commit_ref_update(update->lock, - update->new_sha1, update->msg, err)) { + update->new_sha1, update->msg, + update->flags, err)) { /* freed by commit_ref_update(): */ update->lock = NULL; ret = TRANSACTION_GENERIC_ERROR; diff --git a/refs.h b/refs.h index de68a452b7..4f1b236568 100644 --- a/refs.h +++ b/refs.h @@ -187,6 +187,7 @@ extern int peel_ref(const char *refname, unsigned char *sha1); * Other flags are reserved for internal use. */ #define REF_NODEREF 0x01 +#define REF_FORCE_CREATE_REFLOG 0x40 /* * Setup reflog before using. Fill in err and return -1 on failure. -- cgit v1.3-5-g9baa