From: Ronnie Sahlberg <sahlberg@xxxxxxxxxx> Signed-off-by: Ronnie Sahlberg <sahlberg@xxxxxxxxxx> Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx> --- builtin/branch.c | 7 +++++-- builtin/checkout.c | 13 ++++++++++--- builtin/clone.c | 15 +++++++++++---- builtin/init-db.c | 8 ++++++-- builtin/notes.c | 7 ++++--- builtin/remote.c | 26 ++++++++++++++++++-------- builtin/symbolic-ref.c | 6 +++++- cache.h | 1 - refs.c | 30 ++++++++++++++++++------------ refs.h | 1 + 10 files changed, 78 insertions(+), 36 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 04f57d4..ab6d9f4 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -698,6 +698,7 @@ static void rename_branch(const char *oldname, const char *newname, int force) { struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT; struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT; + struct strbuf err = STRBUF_INIT; int recovery = 0; int clobber_head_ok; @@ -734,8 +735,10 @@ static void rename_branch(const char *oldname, const char *newname, int force) warning(_("Renamed a misnamed branch '%s' away"), oldref.buf + 11); /* no need to pass logmsg here as HEAD didn't really move */ - if (!strcmp(oldname, head) && create_symref("HEAD", newref.buf, NULL)) - die(_("Branch renamed to %s, but HEAD is not updated!"), newname); + if (!strcmp(oldname, head) && + create_symref("HEAD", newref.buf, NULL, &err)) + die(_("Branch renamed to %s, but HEAD is not updated!. %s"), + newname, err.buf); strbuf_addf(&oldsection, "branch.%s", oldref.buf + 11); strbuf_release(&oldref); diff --git a/builtin/checkout.c b/builtin/checkout.c index d9cb9c3..1efe353 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -634,7 +634,10 @@ static void update_refs_for_switch(const struct checkout_opts *opts, describe_detached_head(_("HEAD is now at"), new->commit); } } else if (new->path) { /* Switch branches. */ - create_symref("HEAD", new->path, msg.buf); + if (create_symref("HEAD", new->path, msg.buf, &err)) { + error("%s", err.buf); + strbuf_release(&err); + } if (!opts->quiet) { if (old->path && !strcmp(new->path, old->path)) { if (opts->new_branch_force) @@ -1020,12 +1023,16 @@ static int parse_branchname_arg(int argc, const char **argv, static int switch_unborn_to_new_branch(const struct checkout_opts *opts) { int status; - struct strbuf branch_ref = STRBUF_INIT; + struct strbuf branch_ref = STRBUF_INIT, err = STRBUF_INIT; if (!opts->new_branch) die(_("You are on a branch yet to be born")); strbuf_addf(&branch_ref, "refs/heads/%s", opts->new_branch); - status = create_symref("HEAD", branch_ref.buf, "checkout -b"); + status = create_symref("HEAD", branch_ref.buf, "checkout -b", &err); + if (status) { + error("%s", err.buf); + strbuf_release(&err); + } strbuf_release(&branch_ref); if (!opts->quiet) fprintf(stderr, _("Switched to a new branch '%s'\n"), diff --git a/builtin/clone.c b/builtin/clone.c index 49a72ac..465818a 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -562,6 +562,7 @@ static void update_remote_refs(const struct ref *refs, int check_connectivity) { const struct ref *rm = mapped_refs; + struct strbuf err = STRBUF_INIT; if (check_connectivity) { if (transport->progress) @@ -583,9 +584,12 @@ static void update_remote_refs(const struct ref *refs, struct strbuf head_ref = STRBUF_INIT; strbuf_addstr(&head_ref, branch_top); strbuf_addstr(&head_ref, "HEAD"); - create_symref(head_ref.buf, - remote_head_points_at->peer_ref->name, - msg); + if (create_symref(head_ref.buf, + remote_head_points_at->peer_ref->name, + msg, &err)) { + error("%s", err.buf); + strbuf_release(&err); + } } } @@ -596,7 +600,10 @@ static void update_head(const struct ref *our, const struct ref *remote, const char *head; if (our && skip_prefix(our->name, "refs/heads/", &head)) { /* Local default branch link */ - create_symref("HEAD", our->name, NULL); + if (create_symref("HEAD", our->name, NULL, &err)) { + error("%s", err.buf); + strbuf_release(&err); + } if (!option_bare) { update_ref(msg, "HEAD", our->old_sha1, NULL, 0, &err); install_branch_config(0, head, option_origin, our->name); diff --git a/builtin/init-db.c b/builtin/init-db.c index 587a505..d6cdee8 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "exec_cmd.h" #include "parse-options.h" +#include "refs.h" #ifndef DEFAULT_GIT_TEMPLATE_DIR #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates" @@ -187,6 +188,7 @@ static int create_default_files(const char *template_path) char junk[2]; int reinit; int filemode; + struct strbuf err = STRBUF_INIT; if (len > sizeof(path)-50) die(_("insane git directory %s"), git_dir); @@ -236,8 +238,10 @@ static int create_default_files(const char *template_path) strcpy(path + len, "HEAD"); reinit = (!access(path, R_OK) || readlink(path, junk, sizeof(junk)-1) != -1); - if (!reinit) { - if (create_symref("HEAD", "refs/heads/master", NULL) < 0) + if (!reinit && + create_symref("HEAD", "refs/heads/master", NULL, &err)) { + error("%s", err.buf); + strbuf_release(&err); exit(1); } diff --git a/builtin/notes.c b/builtin/notes.c index b9fec39..f6d4696 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -821,9 +821,10 @@ static int merge(int argc, const char **argv, const char *prefix) 0, &err)) die("%s", err.buf); /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */ - if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL)) - die("Failed to store link to current notes ref (%s)", - default_notes_ref()); + if (create_symref("NOTES_MERGE_REF", default_notes_ref(), + NULL, &err)) + die("Failed to store link to current notes ref (%s). " + "%s", default_notes_ref(), err.buf); printf("Automatic notes merge failed. Fix conflicts in %s and " "commit the result with 'git notes merge --commit', or " "abort the merge with 'git notes merge --abort'.\n", diff --git a/builtin/remote.c b/builtin/remote.c index 42702d7..d9632df 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -147,6 +147,7 @@ static int add(int argc, const char **argv) const char *master = NULL; struct remote *remote; struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT; + struct strbuf err = STRBUF_INIT; const char *name, *url; int i; @@ -230,8 +231,12 @@ static int add(int argc, const char **argv) strbuf_reset(&buf2); strbuf_addf(&buf2, "refs/remotes/%s/%s", name, master); - if (create_symref(buf.buf, buf2.buf, "remote add")) - return error(_("Could not setup master '%s'"), master); + if (create_symref(buf.buf, buf2.buf, "remote add", &err)) { + error(_("Could not setup master '%s'. %s"), + master, err.buf); + strbuf_release(&err); + return -1; + } } strbuf_release(&buf); @@ -617,8 +622,8 @@ static int mv(int argc, const char **argv) OPT_END() }; struct remote *oldremote, *newremote; - struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT, - old_remote_context = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT; + struct strbuf old_remote_context = STRBUF_INIT, err = STRBUF_INIT; struct string_list remote_branches = STRING_LIST_INIT_NODUP; struct rename_info rename; int i, refspec_updated = 0; @@ -742,8 +747,8 @@ static int mv(int argc, const char **argv) strbuf_reset(&buf3); strbuf_addf(&buf3, "remote: renamed %s to %s", item->string, buf.buf); - if (create_symref(buf.buf, buf2.buf, buf3.buf)) - die(_("creating '%s' failed"), buf.buf); + if (create_symref(buf.buf, buf2.buf, buf3.buf, &err)) + die(_("creating '%s' failed. %s"), buf.buf, err.buf); } return 0; } @@ -1260,6 +1265,7 @@ static int set_head(int argc, const char **argv) { int i, opt_a = 0, opt_d = 0, result = 0; struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT; + struct strbuf err = STRBUF_INIT; char *head_name = NULL; struct option options[] = { @@ -1302,8 +1308,12 @@ static int set_head(int argc, const char **argv) /* make sure it's valid */ if (!ref_exists(buf2.buf)) result |= error(_("Not a valid ref: %s"), buf2.buf); - else if (create_symref(buf.buf, buf2.buf, "remote set-head")) - result |= error(_("Could not setup %s"), buf.buf); + else if (create_symref(buf.buf, buf2.buf, "remote set-head", + &err)) { + error(_("Could not setup %s. %s"), buf.buf, err.buf); + strbuf_release(&err); + result = -1; + } if (opt_a) printf("%s/HEAD set to %s\n", argv[0], head_name); free(head_name); diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 29fb3f1..f9ca959 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -35,6 +35,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) { int quiet = 0, delete = 0, shorten = 0, ret = 0; const char *msg = NULL; + struct strbuf err = STRBUF_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("suppress error message for non-symbolic (detached) refs")), @@ -67,7 +68,10 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) if (!strcmp(argv[0], "HEAD") && !starts_with(argv[1], "refs/")) die("Refusing to point HEAD outside of refs/"); - create_symref(argv[0], argv[1], msg); + if (create_symref(argv[0], argv[1], msg, &err)) { + error("%s", err.buf); + strbuf_release(&err); + } break; default: usage_with_options(git_symbolic_ref_usage, options); diff --git a/cache.h b/cache.h index 61e61af..3443da7 100644 --- a/cache.h +++ b/cache.h @@ -1026,7 +1026,6 @@ extern int get_sha1_mb(const char *str, unsigned char *sha1); */ extern int refname_match(const char *abbrev_name, const char *full_name); -extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg); extern int validate_headref(const char *ref); extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2); diff --git a/refs.c b/refs.c index d2f7cea..da7f12b 100644 --- a/refs.c +++ b/refs.c @@ -3104,20 +3104,22 @@ static int write_ref_sha1(struct ref_lock *lock, } int create_symref(const char *ref_target, const char *refs_heads_master, - const char *logmsg) + const char *logmsg, struct strbuf *err) { const char *lockpath; char ref[1000]; int fd, len, written; char *git_HEAD = git_pathdup("%s", ref_target); unsigned char old_sha1[20], new_sha1[20]; - struct strbuf err = STRBUF_INIT; if (logmsg && read_ref(ref_target, old_sha1)) hashclr(old_sha1); - if (safe_create_leading_directories(git_HEAD) < 0) - return error("unable to create directory for %s", git_HEAD); + if (safe_create_leading_directories(git_HEAD) < 0) { + strbuf_addf(err, "unable to create directory for %s.", + git_HEAD); + return -1; + } #ifndef NO_SYMLINK_HEAD if (prefer_symlink_refs) { @@ -3130,26 +3132,29 @@ int create_symref(const char *ref_target, const char *refs_heads_master, len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master); if (sizeof(ref) <= len) { - error("refname too long: %s", refs_heads_master); + strbuf_addf(err, "refname too long: %s", refs_heads_master); goto error_free_return; } lockpath = mkpath("%s.lock", git_HEAD); fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); if (fd < 0) { - error("Unable to open %s for writing", lockpath); + strbuf_addf(err, "Unable to open %s for writing. %s", lockpath, + strerror(errno)); goto error_free_return; } written = write_in_full(fd, ref, len); if (close(fd) != 0 || written != len) { - error("Unable to write to %s", lockpath); + strbuf_addf(err, "Unable to write to %s. %s", lockpath, + strerror(errno)); goto error_unlink_return; } if (rename(lockpath, git_HEAD) < 0) { - error("Unable to create %s", git_HEAD); + strbuf_addf(err, "Unable to create %s. %s", git_HEAD, + strerror(errno)); goto error_unlink_return; } if (adjust_shared_perm(git_HEAD)) { - error("Unable to fix permissions on %s", lockpath); + strbuf_addf(err, "Unable to fix permissions on %s", lockpath); error_unlink_return: unlink_or_warn(lockpath); error_free_return: @@ -3161,10 +3166,11 @@ 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)) - error("%s", err.buf); + log_ref_write(ref_target, old_sha1, new_sha1, logmsg, err)) { + error("%s", err->buf); + strbuf_release(err); + } - strbuf_release(&err); free(git_HEAD); return 0; } diff --git a/refs.h b/refs.h index 930821e..6c99a57 100644 --- a/refs.h +++ b/refs.h @@ -116,6 +116,7 @@ static inline const char *has_glob_specials(const char *pattern) /* can be used to learn about broken ref and symref */ extern int for_each_rawref(each_ref_fn, void *); +extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg, struct strbuf *err); extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname); extern void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames); -- 2.2.0.rc2.5.gf7b9fb2 -- 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