merge: merge unborn index before setting ref
[gitweb.git] / revision.c
index 86d24704896d71de7bb554a3925ea88e2be3417b..e96c281d1f04f37e519e9447e18e43b86cb2363a 100644 (file)
@@ -535,6 +535,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
        int left_count = 0, right_count = 0;
        int left_first;
        struct patch_ids ids;
+       unsigned cherry_flag;
 
        /* First count the commits on the left and on the right */
        for (p = list; p; p = p->next) {
@@ -572,6 +573,9 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
                commit->util = add_commit_patch_id(commit, &ids);
        }
 
+       /* either cherry_mark or cherry_pick are true */
+       cherry_flag = revs->cherry_mark ? PATCHSAME : SHOWN;
+
        /* Check the other side */
        for (p = list; p; p = p->next) {
                struct commit *commit = p->item;
@@ -594,7 +598,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
                if (!id)
                        continue;
                id->seen = 1;
-               commit->object.flags |= SHOWN;
+               commit->object.flags |= cherry_flag;
        }
 
        /* Now check the original side for seen ones */
@@ -606,7 +610,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
                if (!ent)
                        continue;
                if (ent->seen)
-                       commit->object.flags |= SHOWN;
+                       commit->object.flags |= cherry_flag;
                commit->util = NULL;
        }
 
@@ -729,6 +733,23 @@ static struct commit_list *collect_bottom_commits(struct commit_list *list)
        return bottom;
 }
 
+/* Assumes either left_only or right_only is set */
+static void limit_left_right(struct commit_list *list, struct rev_info *revs)
+{
+       struct commit_list *p;
+
+       for (p = list; p; p = p->next) {
+               struct commit *commit = p->item;
+
+               if (revs->right_only) {
+                       if (commit->object.flags & SYMMETRIC_LEFT)
+                               commit->object.flags |= SHOWN;
+               } else  /* revs->left_only is set */
+                       if (!(commit->object.flags & SYMMETRIC_LEFT))
+                               commit->object.flags |= SHOWN;
+       }
+}
+
 static int limit_list(struct rev_info *revs)
 {
        int slop = SLOP;
@@ -781,9 +802,12 @@ static int limit_list(struct rev_info *revs)
                show(revs, newlist);
                show_early_output = NULL;
        }
-       if (revs->cherry_pick)
+       if (revs->cherry_pick || revs->cherry_mark)
                cherry_pick_list(newlist, revs);
 
+       if (revs->left_only || revs->right_only)
+               limit_left_right(newlist, revs);
+
        if (bottom) {
                limit_to_ancestry(bottom, newlist);
                free_commit_list(bottom);
@@ -1260,9 +1284,32 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->boundary = 1;
        } else if (!strcmp(arg, "--left-right")) {
                revs->left_right = 1;
+       } else if (!strcmp(arg, "--left-only")) {
+               if (revs->right_only)
+                       die("--left-only is incompatible with --right-only"
+                           " or --cherry");
+               revs->left_only = 1;
+       } else if (!strcmp(arg, "--right-only")) {
+               if (revs->left_only)
+                       die("--right-only is incompatible with --left-only");
+               revs->right_only = 1;
+       } else if (!strcmp(arg, "--cherry")) {
+               if (revs->left_only)
+                       die("--cherry is incompatible with --left-only");
+               revs->cherry_mark = 1;
+               revs->right_only = 1;
+               revs->no_merges = 1;
+               revs->limited = 1;
        } else if (!strcmp(arg, "--count")) {
                revs->count = 1;
+       } else if (!strcmp(arg, "--cherry-mark")) {
+               if (revs->cherry_pick)
+                       die("--cherry-mark is incompatible with --cherry-pick");
+               revs->cherry_mark = 1;
+               revs->limited = 1; /* needs limit_list() */
        } else if (!strcmp(arg, "--cherry-pick")) {
+               if (revs->cherry_mark)
+                       die("--cherry-pick is incompatible with --cherry-mark");
                revs->cherry_pick = 1;
                revs->limited = 1;
        } else if (!strcmp(arg, "--objects")) {
@@ -2232,3 +2279,32 @@ struct commit *get_revision(struct rev_info *revs)
                graph_update(revs->graph, c);
        return c;
 }
+
+char *get_revision_mark(const struct rev_info *revs, const struct commit *commit)
+{
+       if (commit->object.flags & BOUNDARY)
+               return "-";
+       else if (commit->object.flags & UNINTERESTING)
+               return "^";
+       else if (commit->object.flags & PATCHSAME)
+               return "=";
+       else if (!revs || revs->left_right) {
+               if (commit->object.flags & SYMMETRIC_LEFT)
+                       return "<";
+               else
+                       return ">";
+       } else if (revs->graph)
+               return "*";
+       else if (revs->cherry_mark)
+               return "+";
+       return "";
+}
+
+void put_revision_mark(const struct rev_info *revs, const struct commit *commit)
+{
+       char *mark = get_revision_mark(revs, commit);
+       if (!strlen(mark))
+               return;
+       fputs(mark, stdout);
+       putchar(' ');
+}