mirror of
https://github.com/git/git
synced 2024-08-27 11:39:22 +00:00
Merge branch 'lt/decorate'
* lt/decorate: rev-list documentation: clarify the two parts of history simplification Document "git log --simplify-by-decoration" Document "git log --source" revision traversal: '--simplify-by-decoration' Make '--decorate' set an explicit 'show_decorations' flag revision: make tree comparison functions take commits rather than trees Add a 'source' decorator for commits Conflicts: Documentation/rev-list-options.txt
This commit is contained in:
commit
b2b80c107f
|
@ -40,6 +40,10 @@ include::diff-options.txt[]
|
||||||
--decorate::
|
--decorate::
|
||||||
Print out the ref names of any commits that are shown.
|
Print out the ref names of any commits that are shown.
|
||||||
|
|
||||||
|
--source::
|
||||||
|
Print out the ref name given on the command line by which each
|
||||||
|
commit was reached.
|
||||||
|
|
||||||
--full-diff::
|
--full-diff::
|
||||||
Without this flag, "git log -p <path>..." shows commits that
|
Without this flag, "git log -p <path>..." shows commits that
|
||||||
touch the specified paths, and diffs about the same specified
|
touch the specified paths, and diffs about the same specified
|
||||||
|
|
|
@ -285,8 +285,52 @@ See also linkgit:git-reflog[1].
|
||||||
History Simplification
|
History Simplification
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
When optional paths are given, 'git rev-list' simplifies commits with
|
Sometimes you are only interested in parts of the history, for example the
|
||||||
various strategies, according to the options you have selected.
|
commits modifying a particular <path>. But there are two parts of
|
||||||
|
'History Simplification', one part is selecting the commits and the other
|
||||||
|
is how to do it, as there are various strategies to simplify the history.
|
||||||
|
|
||||||
|
The following options select the commits to be shown:
|
||||||
|
|
||||||
|
<paths>::
|
||||||
|
|
||||||
|
Commits modifying the given <paths> are selected.
|
||||||
|
|
||||||
|
--simplify-by-decoration::
|
||||||
|
|
||||||
|
Commits that are referred by some branch or tag are selected.
|
||||||
|
|
||||||
|
Note that extra commits can be shown to give a meaningful history.
|
||||||
|
|
||||||
|
The following options affect the way the simplification is performed:
|
||||||
|
|
||||||
|
Default mode::
|
||||||
|
|
||||||
|
Simplifies the history to the simplest history explaining the
|
||||||
|
final state of the tree. Simplest because it prunes some side
|
||||||
|
branches if the end result is the same (i.e. merging branches
|
||||||
|
with the same content)
|
||||||
|
|
||||||
|
--full-history::
|
||||||
|
|
||||||
|
As the default mode but does not prune some history.
|
||||||
|
|
||||||
|
--dense::
|
||||||
|
|
||||||
|
Only the selected commits are shown, plus some to have a
|
||||||
|
meaningful history.
|
||||||
|
|
||||||
|
--sparse::
|
||||||
|
|
||||||
|
All commits in the simplified history are shown.
|
||||||
|
|
||||||
|
--simplify-merges::
|
||||||
|
|
||||||
|
Additional option to '--full-history' to remove some needless
|
||||||
|
merges from the resulting history, as there are no selected
|
||||||
|
commits contributing to this merge.
|
||||||
|
|
||||||
|
A more detailed explanation follows.
|
||||||
|
|
||||||
Suppose you specified `foo` as the <paths>. We shall call commits
|
Suppose you specified `foo` as the <paths>. We shall call commits
|
||||||
that modify `foo` !TREESAME, and the rest TREESAME. (In a diff
|
that modify `foo` !TREESAME, and the rest TREESAME. (In a diff
|
||||||
|
@ -456,6 +500,14 @@ Note the major differences in `N` and `P` over '\--full-history':
|
||||||
removed completely, because it had one parent and is TREESAME.
|
removed completely, because it had one parent and is TREESAME.
|
||||||
--
|
--
|
||||||
|
|
||||||
|
The '\--simplify-by-decoration' option allows you to view only the
|
||||||
|
big picture of the topology of the history, by omitting commits
|
||||||
|
that are not referenced by tags. Commits are marked as !TREESAME
|
||||||
|
(in other words, kept after history simplification rules described
|
||||||
|
above) if (1) they are referenced by tags, or (2) they change the
|
||||||
|
contents of the paths given on the command line. All other
|
||||||
|
commits are marked as TREESAME (subject to be simplified away).
|
||||||
|
|
||||||
ifdef::git-rev-list[]
|
ifdef::git-rev-list[]
|
||||||
Bisection Helpers
|
Bisection Helpers
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -28,7 +28,6 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||||
struct rev_info *rev)
|
struct rev_info *rev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int decorate = 0;
|
|
||||||
|
|
||||||
rev->abbrev = DEFAULT_ABBREV;
|
rev->abbrev = DEFAULT_ABBREV;
|
||||||
rev->commit_format = CMIT_FMT_DEFAULT;
|
rev->commit_format = CMIT_FMT_DEFAULT;
|
||||||
|
@ -55,7 +54,9 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||||
const char *arg = argv[i];
|
const char *arg = argv[i];
|
||||||
if (!strcmp(arg, "--decorate")) {
|
if (!strcmp(arg, "--decorate")) {
|
||||||
load_ref_decorations();
|
load_ref_decorations();
|
||||||
decorate = 1;
|
rev->show_decorations = 1;
|
||||||
|
} else if (!strcmp(arg, "--source")) {
|
||||||
|
rev->show_source = 1;
|
||||||
} else
|
} else
|
||||||
die("unrecognized argument: %s", arg);
|
die("unrecognized argument: %s", arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ static void show_commit(struct commit *commit)
|
||||||
children = children->next;
|
children = children->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
show_decorations(commit);
|
show_decorations(&revs, commit);
|
||||||
if (revs.commit_format == CMIT_FMT_ONELINE)
|
if (revs.commit_format == CMIT_FMT_ONELINE)
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
else
|
else
|
||||||
|
|
10
log-tree.c
10
log-tree.c
|
@ -52,11 +52,15 @@ static void show_parents(struct commit *commit, int abbrev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_decorations(struct commit *commit)
|
void show_decorations(struct rev_info *opt, struct commit *commit)
|
||||||
{
|
{
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
struct name_decoration *decoration;
|
struct name_decoration *decoration;
|
||||||
|
|
||||||
|
if (opt->show_source && commit->util)
|
||||||
|
printf(" %s", (char *) commit->util);
|
||||||
|
if (!opt->show_decorations)
|
||||||
|
return;
|
||||||
decoration = lookup_decoration(&name_decoration, &commit->object);
|
decoration = lookup_decoration(&name_decoration, &commit->object);
|
||||||
if (!decoration)
|
if (!decoration)
|
||||||
return;
|
return;
|
||||||
|
@ -279,7 +283,7 @@ void show_log(struct rev_info *opt)
|
||||||
fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
|
fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
|
||||||
if (opt->print_parents)
|
if (opt->print_parents)
|
||||||
show_parents(commit, abbrev_commit);
|
show_parents(commit, abbrev_commit);
|
||||||
show_decorations(commit);
|
show_decorations(opt, commit);
|
||||||
if (opt->graph && !graph_is_commit_finished(opt->graph)) {
|
if (opt->graph && !graph_is_commit_finished(opt->graph)) {
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
graph_show_remainder(opt->graph);
|
graph_show_remainder(opt->graph);
|
||||||
|
@ -352,7 +356,7 @@ void show_log(struct rev_info *opt)
|
||||||
printf(" (from %s)",
|
printf(" (from %s)",
|
||||||
diff_unique_abbrev(parent->object.sha1,
|
diff_unique_abbrev(parent->object.sha1,
|
||||||
abbrev_commit));
|
abbrev_commit));
|
||||||
show_decorations(commit);
|
show_decorations(opt, commit);
|
||||||
printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
|
printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
|
||||||
if (opt->commit_format == CMIT_FMT_ONELINE) {
|
if (opt->commit_format == CMIT_FMT_ONELINE) {
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
|
|
|
@ -12,7 +12,7 @@ int log_tree_diff_flush(struct rev_info *);
|
||||||
int log_tree_commit(struct rev_info *, struct commit *);
|
int log_tree_commit(struct rev_info *, struct commit *);
|
||||||
int log_tree_opt_parse(struct rev_info *, const char **, int);
|
int log_tree_opt_parse(struct rev_info *, const char **, int);
|
||||||
void show_log(struct rev_info *opt);
|
void show_log(struct rev_info *opt);
|
||||||
void show_decorations(struct commit *commit);
|
void show_decorations(struct rev_info *opt, struct commit *commit);
|
||||||
void log_write_email_headers(struct rev_info *opt, const char *name,
|
void log_write_email_headers(struct rev_info *opt, const char *name,
|
||||||
const char **subject_p,
|
const char **subject_p,
|
||||||
const char **extra_headers_p,
|
const char **extra_headers_p,
|
||||||
|
|
45
revision.c
45
revision.c
|
@ -11,6 +11,7 @@
|
||||||
#include "reflog-walk.h"
|
#include "reflog-walk.h"
|
||||||
#include "patch-ids.h"
|
#include "patch-ids.h"
|
||||||
#include "decorate.h"
|
#include "decorate.h"
|
||||||
|
#include "log-tree.h"
|
||||||
|
|
||||||
volatile show_early_output_fn_t show_early_output;
|
volatile show_early_output_fn_t show_early_output;
|
||||||
|
|
||||||
|
@ -199,6 +200,8 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
|
||||||
mark_parents_uninteresting(commit);
|
mark_parents_uninteresting(commit);
|
||||||
revs->limited = 1;
|
revs->limited = 1;
|
||||||
}
|
}
|
||||||
|
if (revs->show_source && !commit->util)
|
||||||
|
commit->util = (void *) name;
|
||||||
return commit;
|
return commit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,10 +295,31 @@ static void file_change(struct diff_options *options,
|
||||||
DIFF_OPT_SET(options, HAS_CHANGES);
|
DIFF_OPT_SET(options, HAS_CHANGES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
|
static int rev_compare_tree(struct rev_info *revs, struct commit *parent, struct commit *commit)
|
||||||
{
|
{
|
||||||
|
struct tree *t1 = parent->tree;
|
||||||
|
struct tree *t2 = commit->tree;
|
||||||
|
|
||||||
if (!t1)
|
if (!t1)
|
||||||
return REV_TREE_NEW;
|
return REV_TREE_NEW;
|
||||||
|
|
||||||
|
if (revs->simplify_by_decoration) {
|
||||||
|
/*
|
||||||
|
* If we are simplifying by decoration, then the commit
|
||||||
|
* is worth showing if it has a tag pointing at it.
|
||||||
|
*/
|
||||||
|
if (lookup_decoration(&name_decoration, &commit->object))
|
||||||
|
return REV_TREE_DIFFERENT;
|
||||||
|
/*
|
||||||
|
* A commit that is not pointed by a tag is uninteresting
|
||||||
|
* if we are not limited by path. This means that you will
|
||||||
|
* see the usual "commits that touch the paths" plus any
|
||||||
|
* tagged commit by specifying both --simplify-by-decoration
|
||||||
|
* and pathspec.
|
||||||
|
*/
|
||||||
|
if (!revs->prune_data)
|
||||||
|
return REV_TREE_SAME;
|
||||||
|
}
|
||||||
if (!t2)
|
if (!t2)
|
||||||
return REV_TREE_DIFFERENT;
|
return REV_TREE_DIFFERENT;
|
||||||
tree_difference = REV_TREE_SAME;
|
tree_difference = REV_TREE_SAME;
|
||||||
|
@ -306,12 +330,13 @@ static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree
|
||||||
return tree_difference;
|
return tree_difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
|
static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
void *tree;
|
void *tree;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
struct tree_desc empty, real;
|
struct tree_desc empty, real;
|
||||||
|
struct tree *t1 = commit->tree;
|
||||||
|
|
||||||
if (!t1)
|
if (!t1)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -345,7 +370,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!commit->parents) {
|
if (!commit->parents) {
|
||||||
if (rev_same_tree_as_empty(revs, commit->tree))
|
if (rev_same_tree_as_empty(revs, commit))
|
||||||
commit->object.flags |= TREESAME;
|
commit->object.flags |= TREESAME;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +390,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||||
die("cannot simplify commit %s (because of %s)",
|
die("cannot simplify commit %s (because of %s)",
|
||||||
sha1_to_hex(commit->object.sha1),
|
sha1_to_hex(commit->object.sha1),
|
||||||
sha1_to_hex(p->object.sha1));
|
sha1_to_hex(p->object.sha1));
|
||||||
switch (rev_compare_tree(revs, p->tree, commit->tree)) {
|
switch (rev_compare_tree(revs, p, commit)) {
|
||||||
case REV_TREE_SAME:
|
case REV_TREE_SAME:
|
||||||
tree_same = 1;
|
tree_same = 1;
|
||||||
if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) {
|
if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) {
|
||||||
|
@ -385,7 +410,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||||
|
|
||||||
case REV_TREE_NEW:
|
case REV_TREE_NEW:
|
||||||
if (revs->remove_empty_trees &&
|
if (revs->remove_empty_trees &&
|
||||||
rev_same_tree_as_empty(revs, p->tree)) {
|
rev_same_tree_as_empty(revs, p)) {
|
||||||
/* We are adding all the specified
|
/* We are adding all the specified
|
||||||
* paths from this parent, so the
|
* paths from this parent, so the
|
||||||
* history beyond this parent is not
|
* history beyond this parent is not
|
||||||
|
@ -484,6 +509,8 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
|
||||||
|
|
||||||
if (parse_commit(p) < 0)
|
if (parse_commit(p) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (revs->show_source && !p->util)
|
||||||
|
p->util = commit->util;
|
||||||
p->object.flags |= left_flag;
|
p->object.flags |= left_flag;
|
||||||
if (!(p->object.flags & SEEN)) {
|
if (!(p->object.flags & SEEN)) {
|
||||||
p->object.flags |= SEEN;
|
p->object.flags |= SEEN;
|
||||||
|
@ -1033,6 +1060,14 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
||||||
revs->rewrite_parents = 1;
|
revs->rewrite_parents = 1;
|
||||||
revs->simplify_history = 0;
|
revs->simplify_history = 0;
|
||||||
revs->limited = 1;
|
revs->limited = 1;
|
||||||
|
} else if (!strcmp(arg, "--simplify-by-decoration")) {
|
||||||
|
revs->simplify_merges = 1;
|
||||||
|
revs->rewrite_parents = 1;
|
||||||
|
revs->simplify_history = 0;
|
||||||
|
revs->simplify_by_decoration = 1;
|
||||||
|
revs->limited = 1;
|
||||||
|
revs->prune = 1;
|
||||||
|
load_ref_decorations();
|
||||||
} else if (!strcmp(arg, "--date-order")) {
|
} else if (!strcmp(arg, "--date-order")) {
|
||||||
revs->lifo = 0;
|
revs->lifo = 0;
|
||||||
revs->topo_order = 1;
|
revs->topo_order = 1;
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct rev_info {
|
||||||
lifo:1,
|
lifo:1,
|
||||||
topo_order:1,
|
topo_order:1,
|
||||||
simplify_merges:1,
|
simplify_merges:1,
|
||||||
|
simplify_by_decoration:1,
|
||||||
tag_objects:1,
|
tag_objects:1,
|
||||||
tree_objects:1,
|
tree_objects:1,
|
||||||
blob_objects:1,
|
blob_objects:1,
|
||||||
|
@ -53,6 +54,8 @@ struct rev_info {
|
||||||
left_right:1,
|
left_right:1,
|
||||||
rewrite_parents:1,
|
rewrite_parents:1,
|
||||||
print_parents:1,
|
print_parents:1,
|
||||||
|
show_source:1,
|
||||||
|
show_decorations:1,
|
||||||
reverse:1,
|
reverse:1,
|
||||||
reverse_output_stage:1,
|
reverse_output_stage:1,
|
||||||
cherry_pick:1,
|
cherry_pick:1,
|
||||||
|
|
Loading…
Reference in a new issue