The --full-history traversal keeps all merges in addition to non-merge
commits that touch paths in the given pathspec. This is useful to view
both sides of a merge in a topology like this:
A---M---o
/ /
---O---B
even when A and B makes identical change to the given paths. The revision
traversal without --full-history aims to come up with the simplest history
to explain the final state of the tree, and one of the side branches can
be pruned away.
The behaviour to keep all merges however is inconvenient if neither A nor
B touches the paths we are interested in. --full-history reduces the
topology to:
---O---M---o
in such a case, without removing M.
This adds a post processing phase on top of --full-history traversal to
remove needless merges from the resulting history.
The idea is to compute, for each commit in the "full history" result set,
the commit that should replace it in the simplified history. The commit
to replace it in the final history is determined as follows:
* In any case, we first figure out the replacement commits of parents of
the commit we are looking at. The commit we are looking at is
rewritten as if the replacement commits of its original parents are its
parents. While doing so, we reduce the redundant parents from the
rewritten parent list by not just removing the identical ones, but also
removing a parent that is an ancestor of another parent.
* After the above parent simplification, if the commit is a root commit,
an UNINTERESTING commit, a merge commit, or modifies the paths we are
interested in, then the replacement commit of the commit is itself. In
other words, such a commit is not dropped from the final result.
The first point above essentially means that the history is rewritten in
the bottom up direction. We can rewrite the parent list of a commit only
after we know how all of its parents are rewritten. This means that the
processing needs to happen on the full history (i.e. after limit_list()).
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We used to set the TOPOSORT flag of commits during the topological
sorting, but we can just as well use the member "indegree" for it:
indegree is now incremented by 1 in the cases where the commit used
to have the TOPOSORT flag.
This is the same behavior as before, since indegree could not be
non-zero when TOPOSORT was unset.
Incidentally, this fixes the bug in show-branch where the 8th column
was not shown: show-branch sorts the commits in topological order,
assuming that all the commit flags are available for show-branch's
private matters.
But this was not true: TOPOSORT was identical to the flag corresponding
to the 8th ref. So the flags for the 8th column were unset by the
topological sorting.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* ph/parseopt-step-blame:
revisions: refactor handle_revision_opt into parse_revision_opt.
git-shortlog: migrate to parse-options partially.
git-blame: fix lapsus
git-blame: migrate to incremental parse-option [2/2]
git-blame: migrate to incremental parse-option [1/2]
revisions: split handle_revision_opt() from setup_revisions()
parse-opt: add PARSE_OPT_KEEP_ARGV0 parser option.
parse-opt: fake short strings for callers to believe in.
parse-opt: do not print errors on unknown options, return -2 intead.
parse-opt: create parse_options_step.
parse-opt: Export a non NORETURN usage dumper.
parse-opt: have parse_options_{start,end}.
git-blame --reverse
builtin-blame.c: allow more than 16 parents
builtin-blame.c: move prepare_final() into a separate function.
rev-list --children
revision traversal: --children option
* jc/report-tracking:
branch -r -v: do not spit out garbage
stat_tracking_info(): clear object flags used during counting
git-branch -v: show the remote tracking statistics
git-status: show the remote tracking statistics
Refactor "tracking statistics" code used by "git checkout"
It seems we're using handle_revision_opt the same way each time, have a
wrapper around it that does the 9-liner we copy each time instead.
handle_revision_opt can be static in the module for now, it's always
possible to make it public again if needed.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Add two fields to struct rev_info:
- .def to store --default argument; and
- .show_merge 1-bit field.
handle_revision_opt() is able to deal with any revision option, and
consumes them, and leaves revision arguments or pseudo arguments
(like --all, --not, ...) in place.
For now setup_revisions() does a pass of handle_revision_opt() again
so that code not using it in a parse-opt parser still work the same.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Reading rev-list parameters from the command line can be reused by
commands other than rev-list. Move this function to more "library-ish"
place to promote code reuse.
Signed-off-by: Adam Brewster <asb@bu.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When left-right traversal counts the commits in a diverged history, it
leaves the flags in the commits smudged, and we need to clear them before
we return. Otherwise the caller cannot inspect other branches with this
function again.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This new option causes a text-based representation of the history to be
printed to the left of the normal output.
Signed-off-by: Adam Simpkins <adam@adamsimpkins.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This change allows parent rewriting to be performed without causing
the log and rev-list commands to print the parents.
Signed-off-by: Adam Simpkins <adam@adamsimpkins.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This adds a new --children option to the revision machinery. In addition
to the list of parents, child commits of each commit are computed and
stored as a decoration to each commit.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This attached patch introduces a single bit "use_terminator" in "struct
rev_info", which is normally false (i.e. most formats use separator
semantics) but by flipping it to true, you can ask for terminator
semantics just like oneline format does.
The function get_commit_format(), which is what parses "--pretty=" option,
now takes a pointer to "struct rev_info" and updates its commit_format and
use_terminator fields. It used to return the value of type "enum
cmit_fmt", but all the callers assigned it to rev->commit_format.
There are only two cases the code turns use_terminator on. Obviously, the
traditional oneline format (--pretty=oneline) is one of them, and the new
case is --pretty=tformat:... that acts like --pretty=format:... but flips
the bit on.
With this, "--pretty=tformat:%H %s" acts like --pretty=oneline.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* db/cover-letter:
Improve collection of information for format-patch --cover-letter
Add API access to shortlog
t4014: Replace sed's non-standard 'Q' by standard 'q'
Support a --cc=<email> option in format-patch
Combine To: and Cc: headers
Fix format.headers not ending with a newline
Add tests for extra headers in format-patch
Add a --cover-letter option to format-patch
Export some email and pretty-printing functions
Improve message-id generation flow control for format-patch
Add more tests for format-patch
Conflicts:
builtin-log.c
builtin-shortlog.c
pretty.c
It's really not very easy to visualize the commit walker, because - on
purpose - it obvously doesn't show the uninteresting commits!
This adds a "--show-all" flag to the revision walker, which will make
it show uninteresting commits too, and they'll have a '^' in front of
them (it also fixes a logic error for !verbose_header for boundary
commits - we should show the '-' even if left_right isn't shown).
A separate patch to gitk to teach it the new '^' was sent
to paulus. With the change in place, it actually is interesting
even for the cases that git doesn't have any problems with, ie
for the kernel you can do:
gitk -d --show-all v2.6.24..
and you see just how far down it has to parse things to see it all. The
use of "-d" is a good idea, since the date-ordered toposort is much better
at showing why it goes deep down (ie the date of some of those commits
after 2.6.24 is much older, because they were merged from trees that
weren't rebased).
So I think this is a useful feature even for non-debugging - just to
visualize what git does internally more.
When it actually breaks out due to the "everybody_uninteresting()"
case, it adds the uninteresting commits (both the one it's looking at
now, and the list of pending ones) to the list
This way, we really list *all* the commits we've looked at.
Because we now end up listing commits we may not even have been parsed
at all "show_log" and "show_commit" need to protect against commits
that don't have a commit buffer entry.
That second part is debatable just how it should work. Maybe we shouldn't
show such entries at all (with this patch those entries do get shown, they
just don't get any message shown with them). But I think this is a useful
case.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Instead of warning the user that it is expecting git log output from
the standard input (and waiting for the user to type the log from
the keyboard, which is a silly thing to do), default to traverse from
HEAD when there is no rev parameter given and the standard input is
a tty.
This factors out a useful helper "add_head()" from builtin-diff.c to a
more appropriate place revision.c while renaming it to more descriptive
name add_head_to_pending(), as that is what the function is about.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We cannot tell a node that has been checked and found not to be
interesting (which does not have the TREECHANGE flag) from a
node that hasn't been checked if it is interesting or not,
without relying on something else, such as object->parsed.
But an object can get the "parsed" flag for other reasons.
Which means that "TREECHANGE" has the wrong polarity.
This changes the way how the path pruning logic marks an
uninteresting commits. From now on, we consider a commit
interesting by default, and explicitly mark the ones we decided
to prune. The flag is renamed to "TREESAME".
Then, this fixes the logic to show the early output with
incomplete pruning. It basically says "a commit that has
TREESAME set is kind-of-UNINTERESTING", but obviously in a
different way than an outright UNINTERESTING commit. Until we
parse and examine enough parents to determine if a commit
becomes surely "kind-of-UNINTERESTING", we avoid rewriting
the ancestry so that later rounds can fix things up.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This removes the unnecessary indirection of "revs->prune_fn",
since that function is always the same one (or NULL), and there
is in fact not even an abstraction reason to make it a function
(i.e. its not called from some other file and doesn't allow us
to keep the function itself static or anything like that).
It then just replaces it with a bit that says "prune or not",
and if not pruning, every commit gets TREECHANGE.
That in turn means that
- if (!revs->prune_fn || (flags & TREECHANGE))
- if (revs->prune_fn && !(flags & TREECHANGE))
just become
- if (flags & TREECHANGE)
- if (!(flags & TREECHANGE))
respectively.
Together with adding the "single_parent()" helper function, the "complex"
conditional now becomes
if (!(flags & TREECHANGE) && rev->dense && single_parent(commit))
continue;
Also indirection of "revs->dense" checking is thrown away the
same way, because TREECHANGE bit is set appropriately now.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This makes --early-output a bit more advanced, and actually makes it
generate multiple "Final output:" headers as it updates things
asynchronously. I realize that the "Final output:" line is now illogical,
since it's not really final until it also says "done", but
It now _always_ generates a "Final output:" header in front of any commit
list, and that output header gives you a *guess* at the maximum number of
commits available. However, it should be noted that the guess can be
completely off: I do a reasonable job estimating it, but it is not meant
to be exact.
So what happens is that you may get output like this:
- at 0.1 seconds:
Final output: 2 incomplete
.. 2 commits listed ..
- half a second later:
Final output: 33 incomplete
.. 33 commits listed ..
- another half a second after that:
Final output: 71 incomplete
.. 71 commits listed ..
- another half second later:
Final output: 136 incomplete
.. 100 commits listed: we hit the --early-output limit, and
.. will only output 100 commits, and after this you'll not
.. see an "incomplete" report any more since you got as much
.. early output as you asked for!
- .. and then finally:
Final output: 73106 done
.. all the commits ..
The above is a real-life scenario on my current kernel tree after having
flushed all the caches.
Tested with the experimental gitk patch that Paul sent out, and by looking
at the actual log output (and verifying that my commit count guesses
actually match real life fairly well).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This adds support for "--early-output[=n]" as a flag to the "git log"
family of commands. This allows GUI programs to state that they want to
get some output early, in order to be able to show at least something
quickly, even if the full output may take longer to generate.
If no count is specified, a default count of a hundred commits will be
used, although the actual numbr of commits output may be smaller
depending on how many commits were actually found in the first tenth of
a second (or if *everything* was found before that, in which case no
early output will be provided, and only the final list is made
available).
When the full list is generated, there will be a "Final output:" string
prepended to it, regardless of whether any early commits were shown or
not, so that the consumer can always know the difference between early
output and the final list.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
.. by not using quite so much indirection.
This currently grows the "struct commit" a bit, which could be avoided by
using a union for "util" and "indegree" (the topo-sort used to use "util"
anyway, so you cannot use them together), but for now the goal of this was
to simplify, not optimize.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
With this option git-log prints log message size
just before the corresponding message.
Porcelain tools could use this to speedup parsing
of git-log output.
Note that size refers to log message only. If also
patch content is shown its size is not included.
In case it is not possible to know the size upfront
size value is set to zero.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This fixes a crash in broken repositories where random commits
suddenly disappear.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This adds --date={local,relative,default} option to log family of commands,
to allow displaying timestamps in user's local timezone, relative time, or
the default format.
Existing --relative-date option is a synonym of --date=relative; we could
probably deprecate it in the long run.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This is meant to be a saner replacement for "git-cherry".
When used with "A...B", this filters out commits whose patch
text has the same patch-id as a commit on the other side. It
would probably most useful to use with --left-right.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Add a new option to git-format-patch, entitled --subject-prefix that allows
control of the subject prefix '[PATCH]'. Using this option, the text 'PATCH' is
replaced with whatever input is provided to the option. This allows easily
generating patches like '[PATCH 2.6.21-rc3]' or properly numbered series like
'[-mm3 PATCH N/M]'. This patch provides the implementation and documentation.
Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
If your development history does not have fast-forward merges,
i.e. the "first parent" of commits in your history are special
than other parents, this option gives a better overview of the
evolution of a particular branch.
Signed-off-by: Junio C Hamano <junkio@cox.net>
* jc/boundary:
git-bundle: prevent overwriting existing bundles
git-bundle: die if a given ref is not included in bundle
git-bundle: handle thin packs in subcommand "unbundle"
git-bundle: Make thin packs
git-bundle: avoid packing objects which are in the prerequisites
bundle: fix wrong check of read_header()'s return value & add tests
revision --boundary: fix uncounted case.
revision --boundary: fix stupid typo
git-bundle: make verify a bit more chatty.
revision traversal: SHOWN means shown
git-bundle: various fixups
revision traversal: retire BOUNDARY_SHOW
revision walker: Fix --boundary when limited
This removes the flag internally used by revision traversal to
decide which commits are indeed boundaries and renames it to
CHILD_SHOWN. builtin-bundle uses the symbol for its
verification, but I think the logic it uses it is wrong. The
flag is still useful but it is local to the git-bundle, so it is
renamed to PREREQ_MARK.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This cleans up the boundary processing in the commit walker. It
- rips out the boundary logic from the commit walker. Placing
"negative" commits in the revs->commits list was Ok if all we
cared about "boundary" was the UNINTERESTING limiting case,
but conceptually it was wrong.
- makes get_revision_1() function to walk the commits and return
the results as if there is no funny postprocessing flags such
as --reverse, --skip nor --max-count.
- makes get_revision() function the postprocessing phase:
If reverse is given, wait for get_revision_1() to give
everything that it would normally give, and then reverse it
before consuming.
If skip is given, skip that many before going further.
If max is given, stop when we gave out that many.
Now that we are about to return one positive commit, mark
the parents of that commit to be potential boundaries
before returning, iff we are doing the boundary processing.
Return the commit.
- After get_revision() finishes giving out all the positive
commits, if we are doing the boundary processing, we look at
the parents that we marked as potential boundaries earlier,
see if they are really boundaries, and give them out.
It loses more code than it adds, even when the new gc_boundary()
function, which is purely for early optimization, is counted.
Note that this patch is purely for eyeballing and discussion
only. It breaks git-bundle's verify logic because the logic
does not use BOUNDARY_SHOW flag for its internal computation
anymore. After we correct it not to attempt to affect the
boundary processing by setting the BOUNDARY_SHOW flag, we can
remove BOUNDARY_SHOW from revision.h and use that bit assignment
for the new CHILD_SHOWN flag.
Signed-off-by: Junio C Hamano <junkio@cox.net>
The existing --attach option did not create a true "attachment"
but multipart/mixed with Content-Disposition: inline. It should
have been with Content-Disposition: attachment.
Introduce --inline to add multipart/mixed that is inlined, and
make --attach to create an attachement.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
The option --reverse reverses the order of the commits.
[jc: with comments on rev_info.reverse from Simon 'corecode' Schubert.]
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
When called with "--walk-reflogs", as long as there are reflogs
available, the walker will take this information into account, rather
than the parent information in the commit object.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Updated commit objects record the encoding used in their
encoding header. This updates the log family to reencode it
into the encoding specified in i18n.commitencoding (or the
default, which is "utf-8") upon output.
To force a specific encoding that is different, log family takes
command line flag --encoding=<encoding>; giving --encoding=none
entirely disables the reencoding and lets you view log messges
in their original encoding.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This adds --skip=<n> option to revision traversal machinery.
Documentation and test were added by Robert Fitzsimons.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This reverts commit 5761231975.
Feeding symmetric difference to gitk is so useful, and it is the
same for other graphical Porcelains. Rather than forcing them
to pass --no-left-right, making it optional.
Noticed and reported by Jeff King.
When using symmetric differences, I think the user almost always
would want to know which side of the symmetry each commit came
from. So this removes --left-right option from the command
line, and turns it on automatically when a symmetric difference
is used ("git log --merge" counts as a symmetric difference
between HEAD and MERGE_HEAD).
Just in case, a new option --no-left-right is provided to defeat
this, but I do not know if it would be useful.
Signed-off-by: Junio C Hamano <junkio@cox.net>
The output from "symmetric diff", i.e. A...B, does not
distinguish between commits that are reachable from A and the
ones that are reachable from B. In this picture, such a
symmetric diff includes commits marked with a and b.
x---b---b branch B
/ \ /
/ .
/ / \
o---x---a---a branch A
However, you cannot tell which ones are 'a' and which ones are
'b' from the output. Sometimes this is frustrating. This adds
an output option, --left-right, to rev-list.
rev-list --left-right A...B
would show ones reachable from A prefixed with '<' and the ones
reachable from B prefixed with '>'.
When combined with --boundary, boundary commits (the ones marked
with 'x' in the above picture) are shown with prefix '-', so you
would see list that looks like this:
git rev-list --left-right --boundary --pretty=oneline A...B
>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 3rd on b
>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2nd on b
<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 3rd on a
<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2nd on a
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 1st on b
-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 1st on a
Signed-off-by: Junio C Hamano <junkio@cox.net>
Now we can tell the built-in grep to grep only in head or in
body, use that to update --author, --committer, and --grep.
Unfortunately, to make --and, --not and other grep boolean
expressions useful, as in:
# Things written by Junio committed and by Linus and log
# does not talk about diff.
git log --author=Junio --and --committer=Linus \
--grep-not --grep=diff
we will need to do another round of built-in grep core
enhancement, because grep boolean expressions are designed to
work on one line at a time.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This is from a suggestion by Linus, just to mark the locations where we
need to modify to actually implement the filtering.
We do not have any actual filtering code yet.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Incremental repack without -a essentially boils down to:
rev-list --objects --unpacked --all |
pack-objects $new_pack
which picks up all loose objects that are still live and creates
a new pack.
This implements --unpacked=<existing pack> option to tell the
revision walking machinery to pretend as if objects in such a
pack are unpacked for the purpose of object listing. With this,
we could say:
rev-list --objects --unpacked=$active_pack --all |
pack-objects $new_pack
instead, to mean "all live loose objects but pretend as if
objects that are in this pack are also unpacked". The newly
created pack would be perfect for updating $active_pack by
replacing it.
Since pack-objects now knows how to do the rev-list's work
itself internally, you can also write the above example by:
pack-objects --unpacked=$active_pack --all $new_pack </dev/null
Signed-off-by: Junio C Hamano <junkio@cox.net>
setup_revisions() wants to get all the parameters at once and
then postprocesses the resulting revs structure after it is done
with them. This code structure is a bit cumbersome to deal with
efficiently when we want to inject revision parameters from the
side (e.g. read from standard input).
Fortunately, the nature of this postprocessing is not affected by
revision parameters; they are affected only by flags. So it is
Ok to do add_object() after the it returns.
This splits out the code that deals with the revision parameter
out of the main loop of setup_revisions(), so that we can later
call it from elsewhere after it returns.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Any git command that expects to work in a subdirectory of a project, and
that reads the git config files (which is just about all of them) needs to
make sure that it does the "setup_git_directory()" call before it tries to
read the config file.
This means, among other things, that we need to move the call out of
"init_revisions()", and into the caller.
This does the mostly trivial conversion to do that.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Add message_id and ref_message_id fields to struct rev_info, used in show_log
with CMIT_FMT_EMAIL to set Message-Id and In-Reply-To/References respectively.
Use these in git-format-patch to make the second and subsequent patch mails
replies to the first patch mail.
Signed-off-by: Josh Triplett <josh@freedesktop.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>