Skip to content

Commit

Permalink
Merge branch 'mg/rev-list-one-side-only'
Browse files Browse the repository at this point in the history
* mg/rev-list-one-side-only:
  git-log: put space after commit mark
  t6007: test rev-list --cherry
  log --cherry: a synonym
  rev-list: documentation and test for --cherry-mark
  revision.c: introduce --cherry-mark
  rev-list/log: factor out revision mark generation
  rev-list: --left/right-only are mutually exclusive
  rev-list: documentation and test for --left/right-only
  t6007: Make sure we test --cherry-pick
  revlist.c: introduce --left/right-only for unsymmetric picking
  • Loading branch information
gitster committed Mar 23, 2011
2 parents 281ee1d + b1b4755 commit aeb2aaa
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 69 deletions.
3 changes: 3 additions & 0 deletions Documentation/git-rev-list.txt
Expand Up @@ -31,6 +31,9 @@ SYNOPSIS
[ \--parents ]
[ \--timestamp ]
[ \--left-right ]
[ \--left-only ]
[ \--right-only ]
[ \--cherry-mark ]
[ \--cherry-pick ]
[ \--encoding[=<encoding>] ]
[ \--(author|committer|grep)=<pattern> ]
Expand Down
26 changes: 26 additions & 0 deletions Documentation/rev-list-options.txt
Expand Up @@ -151,6 +151,11 @@ ifdef::git-rev-list[]
to /dev/null as the output does not have to be formatted.
endif::git-rev-list[]

--cherry-mark::

Like `--cherry-pick` (see below) but mark equivalent commits
with `=` rather than omitting them, and inequivalent ones with `+`.

--cherry-pick::

Omit any commit that introduces the same change as
Expand All @@ -165,6 +170,27 @@ from the other branch (for example, "3rd on b" may be cherry-picked
from branch A). With this option, such pairs of commits are
excluded from the output.

--left-only::
--right-only::

List only commits on the respective side of a symmetric range,
i.e. only those which would be marked `<` resp. `>` by
`--left-right`.
+
For example, `--cherry-pick --right-only A...B` omits those
commits from `B` which are in `A` or are patch-equivalent to a commit in
`A`. In other words, this lists the `{plus}` commits from `git cherry A B`.
More precisely, `--cherry-pick --right-only --no-merges` gives the exact
list.

--cherry::

A synonym for `--right-only --cherry-mark --no-merges`; useful to
limit the output to the commits on our side and mark those that
have been applied to the other side of a forked history with
`git log --cherry upstream...mybranch`, similar to
`git cherry upstream mybranch`.

-g::
--walk-reflogs::

Expand Down
14 changes: 2 additions & 12 deletions builtin/rev-list.c
Expand Up @@ -64,18 +64,8 @@ static void show_commit(struct commit *commit, void *data)
if (info->header_prefix)
fputs(info->header_prefix, stdout);

if (!revs->graph) {
if (commit->object.flags & BOUNDARY)
putchar('-');
else if (commit->object.flags & UNINTERESTING)
putchar('^');
else if (revs->left_right) {
if (commit->object.flags & SYMMETRIC_LEFT)
putchar('<');
else
putchar('>');
}
}
if (!revs->graph)
fputs(get_revision_mark(revs, commit), stdout);
if (revs->abbrev_commit && revs->abbrev)
fputs(find_unique_abbrev(commit->object.sha1, revs->abbrev),
stdout);
Expand Down
2 changes: 1 addition & 1 deletion git-svn.perl
Expand Up @@ -5734,7 +5734,7 @@ sub cmd_show_log {
my (@k, $c, $d, $stat);
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
while (<$log>) {
if (/^${esc_color}commit -?($::sha1_short)/o) {
if (/^${esc_color}commit (- )?($::sha1_short)/o) {
my $cmt = $1;
if ($c && cmt_showable($c) && $c->{r} != $r_last) {
$r_last = $c->{r};
Expand Down
17 changes: 2 additions & 15 deletions graph.c
Expand Up @@ -798,22 +798,9 @@ static void graph_output_commit_char(struct git_graph *graph, struct strbuf *sb)
}

/*
* If revs->left_right is set, print '<' for commits that
* come from the left side, and '>' for commits from the right
* side.
* get_revision_mark() handles all other cases without assert()
*/
if (graph->revs && graph->revs->left_right) {
if (graph->commit->object.flags & SYMMETRIC_LEFT)
strbuf_addch(sb, '<');
else
strbuf_addch(sb, '>');
return;
}

/*
* Print '*' in all other cases
*/
strbuf_addch(sb, '*');
strbuf_addstr(sb, get_revision_mark(graph->revs, graph->commit));
}

/*
Expand Down
28 changes: 4 additions & 24 deletions log-tree.c
Expand Up @@ -380,18 +380,8 @@ void show_log(struct rev_info *opt)
if (!opt->verbose_header) {
graph_show_commit(opt->graph);

if (!opt->graph) {
if (commit->object.flags & BOUNDARY)
putchar('-');
else if (commit->object.flags & UNINTERESTING)
putchar('^');
else if (opt->left_right) {
if (commit->object.flags & SYMMETRIC_LEFT)
putchar('<');
else
putchar('>');
}
}
if (!opt->graph)
put_revision_mark(opt, commit);
fputs(find_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
if (opt->print_parents)
show_parents(commit, abbrev_commit);
Expand Down Expand Up @@ -448,18 +438,8 @@ void show_log(struct rev_info *opt)
if (opt->commit_format != CMIT_FMT_ONELINE)
fputs("commit ", stdout);

if (!opt->graph) {
if (commit->object.flags & BOUNDARY)
putchar('-');
else if (commit->object.flags & UNINTERESTING)
putchar('^');
else if (opt->left_right) {
if (commit->object.flags & SYMMETRIC_LEFT)
putchar('<');
else
putchar('>');
}
}
if (!opt->graph)
put_revision_mark(opt, commit);
fputs(find_unique_abbrev(commit->object.sha1, abbrev_commit),
stdout);
if (opt->print_parents)
Expand Down
6 changes: 1 addition & 5 deletions pretty.c
Expand Up @@ -876,11 +876,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
c->abbrev_parent_hashes.off;
return 1;
case 'm': /* left/right/bottom */
strbuf_addch(sb, (commit->object.flags & BOUNDARY)
? '-'
: (commit->object.flags & SYMMETRIC_LEFT)
? '<'
: '>');
strbuf_addstr(sb, get_revision_mark(NULL, commit));
return 1;
case 'd':
format_decoration(sb, commit);
Expand Down
82 changes: 79 additions & 3 deletions revision.c
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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 */
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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")) {
Expand Down Expand Up @@ -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(' ');
}
8 changes: 7 additions & 1 deletion revision.h
Expand Up @@ -14,7 +14,8 @@
#define CHILD_SHOWN (1u<<6)
#define ADDED (1u<<7) /* Parents already parsed and added? */
#define SYMMETRIC_LEFT (1u<<8)
#define ALL_REV_FLAGS ((1u<<9)-1)
#define PATCHSAME (1u<<9)
#define ALL_REV_FLAGS ((1u<<10)-1)

#define DECORATE_SHORT_REFS 1
#define DECORATE_FULL_REFS 2
Expand Down Expand Up @@ -59,13 +60,16 @@ struct rev_info {
boundary:2,
count:1,
left_right:1,
left_only:1,
right_only:1,
rewrite_parents:1,
print_parents:1,
show_source:1,
show_decorations:1,
reverse:1,
reverse_output_stage:1,
cherry_pick:1,
cherry_mark:1,
bisect:1,
ancestry_path:1,
first_parent_only:1;
Expand Down Expand Up @@ -163,6 +167,8 @@ extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,

extern int prepare_revision_walk(struct rev_info *revs);
extern struct commit *get_revision(struct rev_info *revs);
extern char *get_revision_mark(const struct rev_info *revs, const struct commit *commit);
extern void put_revision_mark(const struct rev_info *revs, const struct commit *commit);

extern void mark_parents_uninteresting(struct commit *commit);
extern void mark_tree_uninteresting(struct tree *tree);
Expand Down

0 comments on commit aeb2aaa

Please sign in to comment.