merge: split reduce_parents() out of collect_parents()
[gitweb.git] / builtin / merge.c
index 878f82a4109b90541c09e2fa2624b4cd918cf6b8..054f0521d898428aae0c477fb42a3f1e39e842be 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") &&
@@ -1044,12 +1044,44 @@ static int default_edit_option(void)
                st_stdin.st_mode == st_stdout.st_mode);
 }
 
+static struct commit_list *reduce_parents(struct commit *head_commit,
+                                         int *head_subsumed,
+                                         struct commit_list *remoteheads)
+{
+       struct commit_list *parents, *next, **remotes = &remoteheads;
+
+       /*
+        * 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);
+
+       for (remoteheads = NULL, remotes = &remoteheads;
+            parents;
+            parents = next) {
+               struct commit *commit = parents->item;
+               next = parents->next;
+               if (commit == head_commit)
+                       *head_subsumed = 0;
+               else
+                       remotes = &commit_list_insert(commit, remotes)->next;
+               free(parents);
+       }
+       return remoteheads;
+}
+
 static struct commit_list *collect_parents(struct commit *head_commit,
                                           int *head_subsumed,
                                           int argc, const char **argv)
 {
        int i;
-       struct commit_list *remoteheads = NULL, *parents, *next;
+       struct commit_list *remoteheads = NULL;
        struct commit_list **remotes = &remoteheads;
 
        if (head_commit)
@@ -1061,22 +1093,8 @@ static struct commit_list *collect_parents(struct commit *head_commit,
                                         "not something we can merge");
                remotes = &commit_list_insert(commit, remotes)->next;
        }
-       *remotes = NULL;
-
-       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) {
-               struct commit *commit = parents->item;
-               next = parents->next;
-               if (commit == head_commit)
-                       *head_subsumed = 0;
-               else
-                       remotes = &commit_list_insert(commit, remotes)->next;
-       }
-       return remoteheads;
+       return reduce_parents(head_commit, head_subsumed, remoteheads);
 }
 
 int cmd_merge(int argc, const char **argv, const char *prefix)
@@ -1185,9 +1203,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 +1212,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);