The install_branch_config function may fail to write the
configuration file due to locking. To accomodate for this
scenario, introduce a return value which may be used to check if
the function did finish correctly and adjust callers to use this
error code.

Signed-off-by: Patrick Steinhardt <p...@pks.im>
---
 branch.c          | 31 +++++++++++++++++++++----------
 branch.h          |  3 ++-
 builtin/clone.c   |  9 ++++++---
 t/t3200-branch.sh |  9 ++++++++-
 transport.c       | 11 ++++++-----
 5 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/branch.c b/branch.c
index 7ff3f20..7f35bcf 100644
--- a/branch.c
+++ b/branch.c
@@ -49,33 +49,38 @@ static int should_setup_rebase(const char *origin)
        return 0;
 }
 
-void install_branch_config(int flag, const char *local, const char *origin, 
const char *remote)
+int install_branch_config(int flag, const char *local, const char *origin, 
const char *remote)
 {
        const char *shortname = NULL;
        struct strbuf key = STRBUF_INIT;
-       int rebasing = should_setup_rebase(origin);
+       int ret = 0, rebasing = should_setup_rebase(origin);
 
        if (skip_prefix(remote, "refs/heads/", &shortname)
            && !strcmp(local, shortname)
            && !origin) {
                warning(_("Not setting branch %s as its own upstream."),
                        local);
-               return;
+               return ret;
        }
 
        strbuf_addf(&key, "branch.%s.remote", local);
-       git_config_set(key.buf, origin ? origin : ".");
+       ret = git_config_set(key.buf, origin ? origin : ".");
+       if (ret)
+               goto out;
 
        strbuf_reset(&key);
        strbuf_addf(&key, "branch.%s.merge", local);
-       git_config_set(key.buf, remote);
+       ret = git_config_set(key.buf, remote);
+       if (ret)
+               goto out;
 
        if (rebasing) {
                strbuf_reset(&key);
                strbuf_addf(&key, "branch.%s.rebase", local);
-               git_config_set(key.buf, "true");
+               ret = git_config_set(key.buf, "true");
+               if (ret)
+                       goto out;
        }
-       strbuf_release(&key);
 
        if (flag & BRANCH_CONFIG_VERBOSE) {
                if (shortname) {
@@ -102,6 +107,10 @@ void install_branch_config(int flag, const char *local, 
const char *origin, cons
                                          local, remote);
                }
        }
+
+out:
+       strbuf_release(&key);
+       return ret;
 }
 
 /*
@@ -134,8 +143,9 @@ static int setup_tracking(const char *new_ref, const char 
*orig_ref,
                return error(_("Not tracking: ambiguous information for ref 
%s"),
                                orig_ref);
 
-       install_branch_config(config_flags, new_ref, tracking.remote,
-                             tracking.src ? tracking.src : orig_ref);
+       if (install_branch_config(config_flags, new_ref, tracking.remote,
+                                 tracking.src ? tracking.src : orig_ref))
+               return error(_("Could not install branch configuration"));
 
        free(tracking.src);
        return 0;
@@ -295,7 +305,8 @@ void create_branch(const char *head,
        }
 
        if (real_ref && track)
-               setup_tracking(ref.buf + 11, real_ref, track, quiet);
+               if (setup_tracking(ref.buf + 11, real_ref, track, quiet) < 0)
+                       die(_("Could not setup tracking branch"));
 
        strbuf_release(&ref);
        free(real_ref);
diff --git a/branch.h b/branch.h
index 58aa45f..78ad438 100644
--- a/branch.h
+++ b/branch.h
@@ -43,9 +43,10 @@ void remove_branch_state(void);
 /*
  * Configure local branch "local" as downstream to branch "remote"
  * from remote "origin".  Used by git branch --set-upstream.
+ * Returns 0 on success.
  */
 #define BRANCH_CONFIG_VERBOSE 01
-extern void install_branch_config(int flag, const char *local, const char 
*origin, const char *remote);
+extern int install_branch_config(int flag, const char *local, const char 
*origin, const char *remote);
 
 /*
  * Read branch description
diff --git a/builtin/clone.c b/builtin/clone.c
index a7c8def..8b11650 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -648,6 +648,7 @@ static void update_head(const struct ref *our, const struct 
ref *remote,
                        const char *msg)
 {
        const char *head;
+
        if (our && skip_prefix(our->name, "refs/heads/", &head)) {
                /* Local default branch link */
                if (create_symref("HEAD", our->name, NULL) < 0)
@@ -655,7 +656,8 @@ static void update_head(const struct ref *our, const struct 
ref *remote,
                if (!option_bare) {
                        update_ref(msg, "HEAD", our->old_oid.hash, NULL, 0,
                                   UPDATE_REFS_DIE_ON_ERR);
-                       install_branch_config(0, head, option_origin, 
our->name);
+                       if (install_branch_config(0, head, option_origin, 
our->name))
+                               die(_("Could not update '%s'"), head);
                }
        } else if (our) {
                struct commit *c = lookup_commit_reference(our->old_oid.hash);
@@ -1054,8 +1056,9 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
                remote_head = NULL;
                option_no_checkout = 1;
                if (!option_bare)
-                       install_branch_config(0, "master", option_origin,
-                                             "refs/heads/master");
+                       if (install_branch_config(0, "master", option_origin,
+                                                 "refs/heads/master"))
+                               die(_("Could not set up master branch"));
        }
 
        write_refspec_config(src_ref_prefix, our_head_points_at,
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cdaf6f6..dd776b3 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -446,6 +446,13 @@ test_expect_success '--set-upstream-to fails on a non-ref' 
'
        test_must_fail git branch --set-upstream-to HEAD^{}
 '
 
+test_expect_success '--set-upstream-to fails on locked config' '
+       test_when_finished "rm -f .git/config.lock" &&
+       >.git/config.lock &&
+       git branch locked &&
+       test_must_fail git branch --set-upstream-to locked
+'
+
 test_expect_success 'use --set-upstream-to modify HEAD' '
        test_config branch.master.remote foo &&
        test_config branch.master.merge foo &&
@@ -579,7 +586,7 @@ test_expect_success 'avoid ambiguous track' '
        git config remote.ambi1.fetch refs/heads/lalala:refs/heads/master &&
        git config remote.ambi2.url lilili &&
        git config remote.ambi2.fetch refs/heads/lilili:refs/heads/master &&
-       git branch all1 master &&
+       test_must_fail git branch all1 master &&
        test -z "$(git config branch.all1.merge)"
 '
 
diff --git a/transport.c b/transport.c
index 67f3666..f7ad752 100644
--- a/transport.c
+++ b/transport.c
@@ -181,11 +181,12 @@ static void set_upstreams(struct transport *transport, 
struct ref *refs,
                if (!remotename || !starts_with(remotename, "refs/heads/"))
                        continue;
 
-               if (!pretend)
-                       install_branch_config(BRANCH_CONFIG_VERBOSE,
-                               localname + 11, transport->remote->name,
-                               remotename);
-               else
+               if (!pretend) {
+                       if (install_branch_config(BRANCH_CONFIG_VERBOSE,
+                                   localname + 11, transport->remote->name,
+                                   remotename))
+                               die(_("Could not set upstream"));
+               } else
                        printf("Would set upstream of '%s' to '%s' of '%s'\n",
                                localname + 11, remotename + 11,
                                transport->remote->name);
-- 
2.7.0

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

Reply via email to