merge: clarify collect_parents() logic
[gitweb.git] / builtin / merge.c
index 878f82a4109b90541c09e2fa2624b4cd918cf6b8..d2e36e2051d11a97f5d93ee4833ef60a14544c76 100644 (file)
@@ -491,8 +491,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
        }
        if (len) {
                struct strbuf truname = STRBUF_INIT;
-               strbuf_addstr(&truname, "refs/heads/");
-               strbuf_addstr(&truname, remote);
+               strbuf_addf(&truname, "refs/heads/%s", remote);
                strbuf_setlen(&truname, truname.len - len);
                if (ref_exists(truname.buf)) {
                        strbuf_addf(msg,
@@ -503,6 +502,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
                        strbuf_release(&truname);
                        goto cleanup;
                }
+               strbuf_release(&truname);
        }
 
        if (!strcmp(remote, "FETCH_HEAD") &&
@@ -1061,11 +1061,19 @@ static struct commit_list *collect_parents(struct commit *head_commit,
                                         "not something we can merge");
                remotes = &commit_list_insert(commit, remotes)->next;
        }
-       *remotes = NULL;
 
+       /*
+        * Is the current HEAD reachable from another commit being
+        * merged?  If so we do not want to record it as a parent of
+        * the resulting merge, unless --no-ff is given.  We will flip
+        * this variable to 0 when we find HEAD among the independent
+        * tips being merged.
+        */
+       *head_subsumed = 1;
+
+       /* Find what parents to record by checking independent ones. */
        parents = reduce_heads(remoteheads);
 
-       *head_subsumed = 1; /* we will flip this to 0 when we find it */
        for (remoteheads = NULL, remotes = &remoteheads;
             parents;
             parents = next) {
@@ -1075,6 +1083,7 @@ static struct commit_list *collect_parents(struct commit *head_commit,
                        *head_subsumed = 0;
                else
                        remotes = &commit_list_insert(commit, remotes)->next;
+               free(parents);
        }
        return remoteheads;
 }
@@ -1185,9 +1194,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                 * to forbid "git merge" into a branch yet to be born.
                 * We do the same for "git pull".
                 */
-               if (argc != 1)
-                       die(_("Can merge only exactly one commit into "
-                               "empty head"));
                if (squash)
                        die(_("Squash commit into empty head not supported yet"));
                if (fast_forward == FF_NO)
@@ -1197,6 +1203,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                remote_head = remoteheads->item;
                if (!remote_head)
                        die(_("%s - not something we can merge"), argv[0]);
+               if (remoteheads->next)
+                       die(_("Can merge only exactly one commit into empty head"));
                read_empty(remote_head->object.sha1, 0);
                update_ref("initial pull", "HEAD", remote_head->object.sha1,
                           NULL, 0, UPDATE_REFS_DIE_ON_ERR);