2019-01-24 16:29:12 +08:00
|
|
|
#define USE_THE_INDEX_COMPATIBILITY_MACROS
|
2005-04-10 04:00:54 +08:00
|
|
|
#include "cache.h"
|
2017-06-15 02:07:36 +08:00
|
|
|
#include "config.h"
|
2005-04-28 00:21:00 +08:00
|
|
|
#include "diff.h"
|
2005-06-01 23:34:23 +08:00
|
|
|
#include "commit.h"
|
2006-04-09 16:11:11 +08:00
|
|
|
#include "log-tree.h"
|
2006-05-23 20:15:36 +08:00
|
|
|
#include "builtin.h"
|
2010-08-06 06:40:48 +08:00
|
|
|
#include "submodule.h"
|
2018-06-29 09:21:51 +08:00
|
|
|
#include "repository.h"
|
2005-04-10 04:00:54 +08:00
|
|
|
|
Common option parsing for "git log --diff" and friends
This basically does a few things that are sadly somewhat interdependent,
and nontrivial to split out
- get rid of "struct log_tree_opt"
The fields in "log_tree_opt" are moved into "struct rev_info", and all
users of log_tree_opt are changed to use the rev_info struct instead.
- add the parsing for the log_tree_opt arguments to "setup_revision()"
- make setup_revision set a flag (revs->diff) if the diff-related
arguments were used. This allows "git log" to decide whether it wants
to show diffs or not.
- make setup_revision() also initialize the diffopt part of rev_info
(which we had from before, but we just didn't initialize it)
- make setup_revision() do all the "finishing touches" on it all (it will
do the proper flag combination logic, and call "diff_setup_done()")
Now, that was the easy and straightforward part.
The slightly more involved part is that some of the programs that want to
use the new-and-improved rev_info parsing don't actually want _commits_,
they may want tree'ish arguments instead. That meant that I had to change
setup_revision() to parse the arguments not into the "revs->commits" list,
but into the "revs->pending_objects" list.
Then, when we do "prepare_revision_walk()", we walk that list, and create
the sorted commit list from there.
This actually cleaned some stuff up, but it's the less obvious part of the
patch, and re-organized the "revision.c" logic somewhat. It actually paves
the way for splitting argument parsing _entirely_ out of "revision.c",
since now the argument parsing really is totally independent of the commit
walking: that didn't use to be true, since there was lots of overlap with
get_commit_reference() handling etc, now the _only_ overlap is the shared
(and trivial) "add_pending_object()" thing.
However, I didn't do that file split, just because I wanted the diff
itself to be smaller, and show the actual changes more clearly. If this
gets accepted, I'll do further cleanups then - that includes the file
split, but also using the new infrastructure to do a nicer "git diff" etc.
Even in this form, it actually ends up removing more lines than it adds.
It's nice to note how simple and straightforward this makes the built-in
"git log" command, even though it continues to support all the diff flags
too. It doesn't get much simpler that this.
I think this is worth merging soonish, because it does allow for future
cleanup and even more sharing of code. However, it obviously touches
"revision.c", which is subtle. I've tested that it passes all the tests we
have, and it passes my "looks sane" detector, but somebody else should
also give it a good look-over.
[jc: squashed the original and three "oops this too" updates, with
another fix-up.]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-15 07:52:13 +08:00
|
|
|
static struct rev_info log_tree_opt;
|
2005-05-19 04:06:47 +08:00
|
|
|
|
2017-05-31 01:31:04 +08:00
|
|
|
static int diff_tree_commit_oid(const struct object_id *oid)
|
2006-02-06 15:00:41 +08:00
|
|
|
{
|
2018-06-29 09:21:58 +08:00
|
|
|
struct commit *commit = lookup_commit_reference(the_repository, oid);
|
2006-02-06 15:00:41 +08:00
|
|
|
if (!commit)
|
|
|
|
return -1;
|
2006-04-09 16:11:11 +08:00
|
|
|
return log_tree_commit(&log_tree_opt, commit);
|
2006-02-06 15:00:41 +08:00
|
|
|
}
|
|
|
|
|
2008-08-09 04:48:23 +08:00
|
|
|
/* Diff one or more commits. */
|
2017-02-22 07:47:21 +08:00
|
|
|
static int stdin_diff_commit(struct commit *commit, const char *p)
|
2005-05-19 04:06:47 +08:00
|
|
|
{
|
2017-02-22 07:47:21 +08:00
|
|
|
struct object_id oid;
|
|
|
|
struct commit_list **pptr = NULL;
|
|
|
|
|
|
|
|
/* Graft the fake parents locally to the commit */
|
|
|
|
while (isspace(*p++) && !parse_oid_hex(p, &oid, &p)) {
|
2018-06-29 09:21:59 +08:00
|
|
|
struct commit *parent = lookup_commit(the_repository, &oid);
|
2017-02-22 07:47:21 +08:00
|
|
|
if (!pptr) {
|
|
|
|
/* Free the real parent list */
|
|
|
|
free_commit_list(commit->parents);
|
|
|
|
commit->parents = NULL;
|
|
|
|
pptr = &(commit->parents);
|
|
|
|
}
|
|
|
|
if (parent) {
|
|
|
|
pptr = &commit_list_insert(parent, pptr)->next;
|
2006-02-06 15:00:41 +08:00
|
|
|
}
|
2005-05-19 04:06:47 +08:00
|
|
|
}
|
2006-04-09 16:11:11 +08:00
|
|
|
return log_tree_commit(&log_tree_opt, commit);
|
2005-05-07 01:03:17 +08:00
|
|
|
}
|
|
|
|
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
/* Diff two trees. */
|
2017-02-22 07:47:21 +08:00
|
|
|
static int stdin_diff_trees(struct tree *tree1, const char *p)
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
{
|
2017-02-22 07:47:21 +08:00
|
|
|
struct object_id oid;
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
struct tree *tree2;
|
2017-02-22 07:47:21 +08:00
|
|
|
if (!isspace(*p++) || parse_oid_hex(p, &oid, &p) || *p)
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
return error("Need exactly two trees, separated by a space");
|
2018-06-29 09:21:56 +08:00
|
|
|
tree2 = lookup_tree(the_repository, &oid);
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
if (!tree2 || parse_tree(tree2))
|
|
|
|
return -1;
|
2015-11-10 10:22:28 +08:00
|
|
|
printf("%s %s\n", oid_to_hex(&tree1->object.oid),
|
|
|
|
oid_to_hex(&tree2->object.oid));
|
2017-05-31 01:31:03 +08:00
|
|
|
diff_tree_oid(&tree1->object.oid, &tree2->object.oid,
|
|
|
|
"", &log_tree_opt.diffopt);
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
log_tree_diff_flush(&log_tree_opt);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-09 04:48:23 +08:00
|
|
|
static int diff_tree_stdin(char *line)
|
|
|
|
{
|
|
|
|
int len = strlen(line);
|
2017-02-22 07:47:21 +08:00
|
|
|
struct object_id oid;
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
struct object *obj;
|
2017-02-22 07:47:21 +08:00
|
|
|
const char *p;
|
2008-08-09 04:48:23 +08:00
|
|
|
|
|
|
|
if (!len || line[len-1] != '\n')
|
|
|
|
return -1;
|
|
|
|
line[len-1] = 0;
|
2017-02-22 07:47:21 +08:00
|
|
|
if (parse_oid_hex(line, &oid, &p))
|
2008-08-09 04:48:23 +08:00
|
|
|
return -1;
|
2018-06-29 09:21:51 +08:00
|
|
|
obj = parse_object(the_repository, &oid);
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
if (!obj)
|
2008-08-09 04:48:23 +08:00
|
|
|
return -1;
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
if (obj->type == OBJ_COMMIT)
|
2017-02-22 07:47:21 +08:00
|
|
|
return stdin_diff_commit((struct commit *)obj, p);
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
if (obj->type == OBJ_TREE)
|
2017-02-22 07:47:21 +08:00
|
|
|
return stdin_diff_trees((struct tree *)obj, p);
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
error("Object %s is a %s, not a commit or tree",
|
2018-02-15 02:59:24 +08:00
|
|
|
oid_to_hex(&oid), type_name(obj->type));
|
Teach git diff-tree --stdin to diff trees
When feeding trees on the command line, you can give exactly two
trees, not three nor one; --stdin now supports this "two tree" form on
its input, in addition to accepting lines with one or more commits.
When diffing trees (either specified on the command line or from the
standard input), the -s, -v, --pretty, --abbrev-commit, --encoding,
--no-commit-id, and --always options are ignored, since they do not
apply to trees; and the -m, -c, and --cc options are ignored since
they would be meaningful only with three or more trees, which is not
supported (yet).
Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-08-11 00:12:58 +08:00
|
|
|
return -1;
|
2008-08-09 04:48:23 +08:00
|
|
|
}
|
|
|
|
|
2005-07-29 17:01:26 +08:00
|
|
|
static const char diff_tree_usage[] =
|
log,diff-tree: add --combined-all-paths option
The combined diff format for merges will only list one filename, even if
rename or copy detection is active. For example, with raw format one
might see:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM describe.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR phooey.c
This doesn't let us know what the original name of bar.sh was in the
first parent, and doesn't let us know what either of the original names
of phooey.c were in either of the parents. In contrast, for non-merge
commits, raw format does provide original filenames (and a rename score
to boot). In order to also provide original filenames for merge
commits, add a --combined-all-paths option (which must be used with
either -c or --cc, and is likely only useful with rename or copy
detection active) so that we can print tab-separated filenames when
renames are involved. This transforms the above output to:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c desc.c desc.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM foo.sh bar.sh bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR fooey.c fuey.c phooey.c
Further, in patch format, this changes the from/to headers so that
instead of just having one "from" header, we get one for each parent.
For example, instead of having
--- a/phooey.c
+++ b/phooey.c
we would see
--- a/fooey.c
--- a/fuey.c
+++ b/phooey.c
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-08 09:12:46 +08:00
|
|
|
"git diff-tree [--stdin] [-m] [-c | --cc] [-s] [-v] [--pretty] [-t] [-r] [--root] "
|
2015-01-13 15:44:47 +08:00
|
|
|
"[<common-diff-options>] <tree-ish> [<tree-ish>] [<path>...]\n"
|
2005-10-29 01:04:49 +08:00
|
|
|
" -r diff recursively\n"
|
log,diff-tree: add --combined-all-paths option
The combined diff format for merges will only list one filename, even if
rename or copy detection is active. For example, with raw format one
might see:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM describe.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR phooey.c
This doesn't let us know what the original name of bar.sh was in the
first parent, and doesn't let us know what either of the original names
of phooey.c were in either of the parents. In contrast, for non-merge
commits, raw format does provide original filenames (and a rename score
to boot). In order to also provide original filenames for merge
commits, add a --combined-all-paths option (which must be used with
either -c or --cc, and is likely only useful with rename or copy
detection active) so that we can print tab-separated filenames when
renames are involved. This transforms the above output to:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c desc.c desc.c
::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM foo.sh bar.sh bar.sh
::100644 100644 100644 e07d6c5 9042e82 ee91881 RR fooey.c fuey.c phooey.c
Further, in patch format, this changes the from/to headers so that
instead of just having one "from" header, we get one for each parent.
For example, instead of having
--- a/phooey.c
+++ b/phooey.c
we would see
--- a/fooey.c
--- a/fuey.c
+++ b/phooey.c
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-08 09:12:46 +08:00
|
|
|
" -c show combined diff for merge commits\n"
|
|
|
|
" --cc show combined diff for merge commits removing uninteresting hunks\n"
|
|
|
|
" --combined-all-paths\n"
|
|
|
|
" show name of file in all parents for combined diffs\n"
|
2005-10-29 01:04:49 +08:00
|
|
|
" --root include the initial commit as diff against /dev/null\n"
|
2005-07-14 03:52:35 +08:00
|
|
|
COMMON_DIFF_OPTIONS_HELP;
|
2005-06-13 08:44:21 +08:00
|
|
|
|
2010-03-09 15:27:25 +08:00
|
|
|
static void diff_tree_tweak_rev(struct rev_info *rev, struct setup_revision_opt *opt)
|
|
|
|
{
|
|
|
|
if (!rev->diffopt.output_format) {
|
|
|
|
if (rev->dense_combined_merges)
|
|
|
|
rev->diffopt.output_format = DIFF_FORMAT_PATCH;
|
|
|
|
else
|
|
|
|
rev->diffopt.output_format = DIFF_FORMAT_RAW;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-29 13:44:25 +08:00
|
|
|
int cmd_diff_tree(int argc, const char **argv, const char *prefix)
|
2005-04-11 05:03:58 +08:00
|
|
|
{
|
2005-05-07 01:03:17 +08:00
|
|
|
char line[1000];
|
Common option parsing for "git log --diff" and friends
This basically does a few things that are sadly somewhat interdependent,
and nontrivial to split out
- get rid of "struct log_tree_opt"
The fields in "log_tree_opt" are moved into "struct rev_info", and all
users of log_tree_opt are changed to use the rev_info struct instead.
- add the parsing for the log_tree_opt arguments to "setup_revision()"
- make setup_revision set a flag (revs->diff) if the diff-related
arguments were used. This allows "git log" to decide whether it wants
to show diffs or not.
- make setup_revision() also initialize the diffopt part of rev_info
(which we had from before, but we just didn't initialize it)
- make setup_revision() do all the "finishing touches" on it all (it will
do the proper flag combination logic, and call "diff_setup_done()")
Now, that was the easy and straightforward part.
The slightly more involved part is that some of the programs that want to
use the new-and-improved rev_info parsing don't actually want _commits_,
they may want tree'ish arguments instead. That meant that I had to change
setup_revision() to parse the arguments not into the "revs->commits" list,
but into the "revs->pending_objects" list.
Then, when we do "prepare_revision_walk()", we walk that list, and create
the sorted commit list from there.
This actually cleaned some stuff up, but it's the less obvious part of the
patch, and re-organized the "revision.c" logic somewhat. It actually paves
the way for splitting argument parsing _entirely_ out of "revision.c",
since now the argument parsing really is totally independent of the commit
walking: that didn't use to be true, since there was lots of overlap with
get_commit_reference() handling etc, now the _only_ overlap is the shared
(and trivial) "add_pending_object()" thing.
However, I didn't do that file split, just because I wanted the diff
itself to be smaller, and show the actual changes more clearly. If this
gets accepted, I'll do further cleanups then - that includes the file
split, but also using the new infrastructure to do a nicer "git diff" etc.
Even in this form, it actually ends up removing more lines than it adds.
It's nice to note how simple and straightforward this makes the built-in
"git log" command, even though it continues to support all the diff flags
too. It doesn't get much simpler that this.
I think this is worth merging soonish, because it does allow for future
cleanup and even more sharing of code. However, it obviously touches
"revision.c", which is subtle. I've tested that it passes all the tests we
have, and it passes my "looks sane" detector, but somebody else should
also give it a good look-over.
[jc: squashed the original and three "oops this too" updates, with
another fix-up.]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-15 07:52:13 +08:00
|
|
|
struct object *tree1, *tree2;
|
|
|
|
static struct rev_info *opt = &log_tree_opt;
|
2010-03-09 15:27:25 +08:00
|
|
|
struct setup_revision_opt s_r_opt;
|
diff-tree.c: load notes machinery when required
Since its introduction in 7249e91 (revision.c: support --notes
command-line option, 2011-03-29), combining '--notes' with any option
that causes us to format notes (e.g., '--pretty', '--format="%N"', etc)
results in a failed assertion at runtime.
$ git rev-list HEAD | git diff-tree --stdin --pretty=medium --notes
commit 8f3d9f354286745c751374f5f1fcafee6b3f3136
git: notes.c:1308: format_display_notes: Assertion `display_notes_trees' failed.
Aborted
This failure is due to diff-tree not calling 'load_display_notes' to
initialize the notes machinery.
Ordinarily, this failure isn't triggered, because it requires passing
both '--notes' and another of the above mentioned options. In the case
of '--pretty', for example, we set 'opt->verbose_header', causing
'show_log()' to eventually call 'format_display_notes()', which expects
a non-NULL 'display_note_trees'.
Without initializing the notes machinery, 'display_note_trees' remains
NULL, and thus triggers an assertion failure.
Fix this by initializing the notes machinery after parsing our options,
and harden this behavior against regression with a test in t4013. (Note
that the added ref in this test requires updating two unrelated tests
which use 'log --all', and thus need to learn about the new refs).
Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-21 08:13:15 +08:00
|
|
|
struct userformat_want w;
|
2006-04-09 16:11:11 +08:00
|
|
|
int read_stdin = 0;
|
2005-04-11 05:03:58 +08:00
|
|
|
|
2017-06-01 12:38:16 +08:00
|
|
|
if (argc == 2 && !strcmp(argv[1], "-h"))
|
|
|
|
usage(diff_tree_usage);
|
|
|
|
|
2017-05-09 00:03:37 +08:00
|
|
|
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
|
2018-09-21 23:57:38 +08:00
|
|
|
repo_init_revisions(the_repository, opt, prefix);
|
2017-12-07 06:02:56 +08:00
|
|
|
if (read_cache() < 0)
|
|
|
|
die(_("index file corrupt"));
|
2006-04-15 13:19:38 +08:00
|
|
|
opt->abbrev = 0;
|
Log message printout cleanups
On Sun, 16 Apr 2006, Junio C Hamano wrote:
>
> In the mid-term, I am hoping we can drop the generate_header()
> callchain _and_ the custom code that formats commit log in-core,
> found in cmd_log_wc().
Ok, this was nastier than expected, just because the dependencies between
the different log-printing stuff were absolutely _everywhere_, but here's
a patch that does exactly that.
The patch is not very easy to read, and the "--patch-with-stat" thing is
still broken (it does not call the "show_log()" thing properly for
merges). That's not a new bug. In the new world order it _should_ do
something like
if (rev->logopt)
show_log(rev, rev->logopt, "---\n");
but it doesn't. I haven't looked at the --with-stat logic, so I left it
alone.
That said, this patch removes more lines than it adds, and in particular,
the "cmd_log_wc()" loop is now a very clean:
while ((commit = get_revision(rev)) != NULL) {
log_tree_commit(rev, commit);
free(commit->buffer);
commit->buffer = NULL;
}
so it doesn't get much prettier than this. All the complexity is entirely
hidden in log-tree.c, and any code that needs to flush the log literally
just needs to do the "if (rev->logopt) show_log(...)" incantation.
I had to make the combined_diff() logic take a "struct rev_info" instead
of just a "struct diff_options", but that part is pretty clean.
This does change "git whatchanged" from using "diff-tree" as the commit
descriptor to "commit", and I changed one of the tests to reflect that new
reality. Otherwise everything still passes, and my other tests look fine
too.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-18 02:59:32 +08:00
|
|
|
opt->diff = 1;
|
2009-11-03 22:59:18 +08:00
|
|
|
opt->disable_stdin = 1;
|
2010-03-09 15:27:25 +08:00
|
|
|
memset(&s_r_opt, 0, sizeof(s_r_opt));
|
|
|
|
s_r_opt.tweak = diff_tree_tweak_rev;
|
2016-05-14 04:41:02 +08:00
|
|
|
|
|
|
|
precompose_argv(argc, argv);
|
2010-03-09 15:27:25 +08:00
|
|
|
argc = setup_revisions(argc, argv, opt, &s_r_opt);
|
2005-09-21 15:00:47 +08:00
|
|
|
|
diff-tree.c: load notes machinery when required
Since its introduction in 7249e91 (revision.c: support --notes
command-line option, 2011-03-29), combining '--notes' with any option
that causes us to format notes (e.g., '--pretty', '--format="%N"', etc)
results in a failed assertion at runtime.
$ git rev-list HEAD | git diff-tree --stdin --pretty=medium --notes
commit 8f3d9f354286745c751374f5f1fcafee6b3f3136
git: notes.c:1308: format_display_notes: Assertion `display_notes_trees' failed.
Aborted
This failure is due to diff-tree not calling 'load_display_notes' to
initialize the notes machinery.
Ordinarily, this failure isn't triggered, because it requires passing
both '--notes' and another of the above mentioned options. In the case
of '--pretty', for example, we set 'opt->verbose_header', causing
'show_log()' to eventually call 'format_display_notes()', which expects
a non-NULL 'display_note_trees'.
Without initializing the notes machinery, 'display_note_trees' remains
NULL, and thus triggers an assertion failure.
Fix this by initializing the notes machinery after parsing our options,
and harden this behavior against regression with a test in t4013. (Note
that the added ref in this test requires updating two unrelated tests
which use 'log --all', and thus need to learn about the new refs).
Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-21 08:13:15 +08:00
|
|
|
memset(&w, 0, sizeof(w));
|
|
|
|
userformat_find_requirements(NULL, &w);
|
|
|
|
|
|
|
|
if (!opt->show_notes_given && w.notes)
|
|
|
|
opt->show_notes = 1;
|
|
|
|
if (opt->show_notes)
|
|
|
|
load_display_notes(&opt->notes_opt);
|
|
|
|
|
Common option parsing for "git log --diff" and friends
This basically does a few things that are sadly somewhat interdependent,
and nontrivial to split out
- get rid of "struct log_tree_opt"
The fields in "log_tree_opt" are moved into "struct rev_info", and all
users of log_tree_opt are changed to use the rev_info struct instead.
- add the parsing for the log_tree_opt arguments to "setup_revision()"
- make setup_revision set a flag (revs->diff) if the diff-related
arguments were used. This allows "git log" to decide whether it wants
to show diffs or not.
- make setup_revision() also initialize the diffopt part of rev_info
(which we had from before, but we just didn't initialize it)
- make setup_revision() do all the "finishing touches" on it all (it will
do the proper flag combination logic, and call "diff_setup_done()")
Now, that was the easy and straightforward part.
The slightly more involved part is that some of the programs that want to
use the new-and-improved rev_info parsing don't actually want _commits_,
they may want tree'ish arguments instead. That meant that I had to change
setup_revision() to parse the arguments not into the "revs->commits" list,
but into the "revs->pending_objects" list.
Then, when we do "prepare_revision_walk()", we walk that list, and create
the sorted commit list from there.
This actually cleaned some stuff up, but it's the less obvious part of the
patch, and re-organized the "revision.c" logic somewhat. It actually paves
the way for splitting argument parsing _entirely_ out of "revision.c",
since now the argument parsing really is totally independent of the commit
walking: that didn't use to be true, since there was lots of overlap with
get_commit_reference() handling etc, now the _only_ overlap is the shared
(and trivial) "add_pending_object()" thing.
However, I didn't do that file split, just because I wanted the diff
itself to be smaller, and show the actual changes more clearly. If this
gets accepted, I'll do further cleanups then - that includes the file
split, but also using the new infrastructure to do a nicer "git diff" etc.
Even in this form, it actually ends up removing more lines than it adds.
It's nice to note how simple and straightforward this makes the built-in
"git log" command, even though it continues to support all the diff flags
too. It doesn't get much simpler that this.
I think this is worth merging soonish, because it does allow for future
cleanup and even more sharing of code. However, it obviously touches
"revision.c", which is subtle. I've tested that it passes all the tests we
have, and it passes my "looks sane" detector, but somebody else should
also give it a good look-over.
[jc: squashed the original and three "oops this too" updates, with
another fix-up.]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-15 07:52:13 +08:00
|
|
|
while (--argc > 0) {
|
|
|
|
const char *arg = *++argv;
|
2005-04-24 13:08:00 +08:00
|
|
|
|
2005-05-07 01:03:17 +08:00
|
|
|
if (!strcmp(arg, "--stdin")) {
|
|
|
|
read_stdin = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2005-04-21 10:49:16 +08:00
|
|
|
usage(diff_tree_usage);
|
2005-04-11 05:03:58 +08:00
|
|
|
}
|
|
|
|
|
Common option parsing for "git log --diff" and friends
This basically does a few things that are sadly somewhat interdependent,
and nontrivial to split out
- get rid of "struct log_tree_opt"
The fields in "log_tree_opt" are moved into "struct rev_info", and all
users of log_tree_opt are changed to use the rev_info struct instead.
- add the parsing for the log_tree_opt arguments to "setup_revision()"
- make setup_revision set a flag (revs->diff) if the diff-related
arguments were used. This allows "git log" to decide whether it wants
to show diffs or not.
- make setup_revision() also initialize the diffopt part of rev_info
(which we had from before, but we just didn't initialize it)
- make setup_revision() do all the "finishing touches" on it all (it will
do the proper flag combination logic, and call "diff_setup_done()")
Now, that was the easy and straightforward part.
The slightly more involved part is that some of the programs that want to
use the new-and-improved rev_info parsing don't actually want _commits_,
they may want tree'ish arguments instead. That meant that I had to change
setup_revision() to parse the arguments not into the "revs->commits" list,
but into the "revs->pending_objects" list.
Then, when we do "prepare_revision_walk()", we walk that list, and create
the sorted commit list from there.
This actually cleaned some stuff up, but it's the less obvious part of the
patch, and re-organized the "revision.c" logic somewhat. It actually paves
the way for splitting argument parsing _entirely_ out of "revision.c",
since now the argument parsing really is totally independent of the commit
walking: that didn't use to be true, since there was lots of overlap with
get_commit_reference() handling etc, now the _only_ overlap is the shared
(and trivial) "add_pending_object()" thing.
However, I didn't do that file split, just because I wanted the diff
itself to be smaller, and show the actual changes more clearly. If this
gets accepted, I'll do further cleanups then - that includes the file
split, but also using the new infrastructure to do a nicer "git diff" etc.
Even in this form, it actually ends up removing more lines than it adds.
It's nice to note how simple and straightforward this makes the built-in
"git log" command, even though it continues to support all the diff flags
too. It doesn't get much simpler that this.
I think this is worth merging soonish, because it does allow for future
cleanup and even more sharing of code. However, it obviously touches
"revision.c", which is subtle. I've tested that it passes all the tests we
have, and it passes my "looks sane" detector, but somebody else should
also give it a good look-over.
[jc: squashed the original and three "oops this too" updates, with
another fix-up.]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-15 07:52:13 +08:00
|
|
|
/*
|
2017-06-02 10:34:15 +08:00
|
|
|
* NOTE! We expect "a..b" to expand to "^a b" but it is
|
|
|
|
* perfectly valid for revision range parser to yield "b ^a",
|
|
|
|
* which means the same thing. If we get the latter, i.e. the
|
|
|
|
* second one is marked UNINTERESTING, we recover the original
|
|
|
|
* order the user gave, i.e. "a..b", by swapping the trees.
|
Common option parsing for "git log --diff" and friends
This basically does a few things that are sadly somewhat interdependent,
and nontrivial to split out
- get rid of "struct log_tree_opt"
The fields in "log_tree_opt" are moved into "struct rev_info", and all
users of log_tree_opt are changed to use the rev_info struct instead.
- add the parsing for the log_tree_opt arguments to "setup_revision()"
- make setup_revision set a flag (revs->diff) if the diff-related
arguments were used. This allows "git log" to decide whether it wants
to show diffs or not.
- make setup_revision() also initialize the diffopt part of rev_info
(which we had from before, but we just didn't initialize it)
- make setup_revision() do all the "finishing touches" on it all (it will
do the proper flag combination logic, and call "diff_setup_done()")
Now, that was the easy and straightforward part.
The slightly more involved part is that some of the programs that want to
use the new-and-improved rev_info parsing don't actually want _commits_,
they may want tree'ish arguments instead. That meant that I had to change
setup_revision() to parse the arguments not into the "revs->commits" list,
but into the "revs->pending_objects" list.
Then, when we do "prepare_revision_walk()", we walk that list, and create
the sorted commit list from there.
This actually cleaned some stuff up, but it's the less obvious part of the
patch, and re-organized the "revision.c" logic somewhat. It actually paves
the way for splitting argument parsing _entirely_ out of "revision.c",
since now the argument parsing really is totally independent of the commit
walking: that didn't use to be true, since there was lots of overlap with
get_commit_reference() handling etc, now the _only_ overlap is the shared
(and trivial) "add_pending_object()" thing.
However, I didn't do that file split, just because I wanted the diff
itself to be smaller, and show the actual changes more clearly. If this
gets accepted, I'll do further cleanups then - that includes the file
split, but also using the new infrastructure to do a nicer "git diff" etc.
Even in this form, it actually ends up removing more lines than it adds.
It's nice to note how simple and straightforward this makes the built-in
"git log" command, even though it continues to support all the diff flags
too. It doesn't get much simpler that this.
I think this is worth merging soonish, because it does allow for future
cleanup and even more sharing of code. However, it obviously touches
"revision.c", which is subtle. I've tested that it passes all the tests we
have, and it passes my "looks sane" detector, but somebody else should
also give it a good look-over.
[jc: squashed the original and three "oops this too" updates, with
another fix-up.]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-15 07:52:13 +08:00
|
|
|
*/
|
2017-05-31 01:31:04 +08:00
|
|
|
switch (opt->pending.nr) {
|
2005-05-19 04:10:17 +08:00
|
|
|
case 0:
|
|
|
|
if (!read_stdin)
|
|
|
|
usage(diff_tree_usage);
|
|
|
|
break;
|
|
|
|
case 1:
|
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 08:42:35 +08:00
|
|
|
tree1 = opt->pending.objects[0].item;
|
2017-05-31 01:31:04 +08:00
|
|
|
diff_tree_commit_oid(&tree1->oid);
|
2005-05-19 04:10:17 +08:00
|
|
|
break;
|
|
|
|
case 2:
|
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 08:42:35 +08:00
|
|
|
tree1 = opt->pending.objects[0].item;
|
|
|
|
tree2 = opt->pending.objects[1].item;
|
|
|
|
if (tree2->flags & UNINTERESTING) {
|
2017-01-29 05:40:58 +08:00
|
|
|
SWAP(tree2, tree1);
|
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 08:42:35 +08:00
|
|
|
}
|
2017-05-31 01:31:03 +08:00
|
|
|
diff_tree_oid(&tree1->oid, &tree2->oid, "", &opt->diffopt);
|
2006-04-09 16:11:11 +08:00
|
|
|
log_tree_diff_flush(opt);
|
2005-05-19 04:10:17 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-12-14 04:24:52 +08:00
|
|
|
if (read_stdin) {
|
2011-01-07 05:50:06 +08:00
|
|
|
int saved_nrl = 0;
|
|
|
|
int saved_dcctc = 0;
|
|
|
|
|
2018-08-14 00:14:18 +08:00
|
|
|
if (opt->diffopt.detect_rename) {
|
|
|
|
if (!the_index.cache)
|
2019-01-12 10:13:26 +08:00
|
|
|
repo_read_index(the_repository);
|
2018-08-14 00:14:18 +08:00
|
|
|
opt->diffopt.setup |= DIFF_SETUP_USE_SIZE_CACHE;
|
|
|
|
}
|
2007-12-14 04:24:52 +08:00
|
|
|
while (fgets(line, sizeof(line), stdin)) {
|
2017-02-22 07:47:21 +08:00
|
|
|
struct object_id oid;
|
2005-05-07 01:03:17 +08:00
|
|
|
|
2017-02-22 07:47:21 +08:00
|
|
|
if (get_oid_hex(line, &oid)) {
|
2007-12-14 04:24:52 +08:00
|
|
|
fputs(line, stdout);
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
2011-01-07 05:50:06 +08:00
|
|
|
else {
|
2007-12-14 04:24:52 +08:00
|
|
|
diff_tree_stdin(line);
|
2011-01-07 05:50:06 +08:00
|
|
|
if (saved_nrl < opt->diffopt.needed_rename_limit)
|
|
|
|
saved_nrl = opt->diffopt.needed_rename_limit;
|
|
|
|
if (opt->diffopt.degraded_cc_to_c)
|
|
|
|
saved_dcctc = 1;
|
|
|
|
}
|
2006-05-30 10:01:38 +08:00
|
|
|
}
|
2011-01-07 05:50:06 +08:00
|
|
|
opt->diffopt.degraded_cc_to_c = saved_dcctc;
|
|
|
|
opt->diffopt.needed_rename_limit = saved_nrl;
|
2006-05-30 10:01:38 +08:00
|
|
|
}
|
2007-12-14 15:40:27 +08:00
|
|
|
|
|
|
|
return diff_result_code(&opt->diffopt, 0);
|
2005-04-10 04:00:54 +08:00
|
|
|
}
|