We already support decorating commits by tags or branches that point to
them, but especially when we are looking at multiple branches together,
we sometimes want to see _how_ we reached a particular commit.
We can abuse the '->util' field in the commit to keep track of that as
we walk the commit lists, and get a reasonably useful view into which
branch or tag first reaches that commit.
Of course, if the commit is reachable through multiple sources (which is
common), our particular choice of "first" reachable is entirely random
and depends on the particular path we happened to follow.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Many call sites use strbuf_init(&foo, 0) to initialize local
strbuf variable "foo" which has not been accessed since its
declaration. These can be replaced with a static initialization
using the STRBUF_INIT macro which is just as readable, saves a
function call, and takes up fewer lines.
Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
User notifications are presented as 'git cmd', and code comments
are presented as '"cmd"' or 'git's cmd', rather than 'git-cmd'.
Signed-off-by: Heikki Orsila <heikki.orsila@iki.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This has been broken in v1.6.0 due to the reorganization of
the revision option parsing code. The "-i" is completely
ignored, but works fine in "git log --grep -i".
What happens is that the code for "-i" looks for
revs->grep_filter; if it is NULL, we do nothing, since there
are no grep filters. But that is obviously not correct,
since we want it to influence the later --grep option. Doing
it the other way around works, since "-i" just impacts the
existing grep_filter option.
Instead, we now always initialize the grep_filter member and
just fill in options and patterns as we get them. This means
that we can no longer check grep_filter for NULL, but
instead must check the pattern list to see if we have any
actual patterns.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nick Andrew noticed that rev-list lets --quiet option to be parsed by
underlying diff_options parser but did not pick up the result. This
resulted in --quiet option to become effectively a no-op.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When you misuse a git command, you are shown the usage string.
But this is currently shown in the dashed form. So if you just
copy what you see, it will not work, when the dashed form
is no longer supported.
This patch makes git commands show the dash-less version.
For shell scripts that do not specify OPTIONS_SPEC, git-sh-setup.sh
generates a dash-less usage string now.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
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>
With the --graph option, the graph already outputs 'o' instead of '*'
for boundary commits. Make it emit '<' or '>' when --left-right is
specified.
(This change also disables the '^' prefix for UNINTERESTING commits.
The graph code currently doesn't print anything special for these
commits, since it assumes no UNINTERESTING, non-BOUNDARY commits are
displayed. This is potentially a bug if UNINTERESTING non-BOUNDARY
commits can actually be displayed via some code path.)
[jc: squashed the left-right change from Dscho and Adam's fixup into one]
Signed-off-by: Adam Simpkins <adam@adamsimpkins.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git_config() only had a function parameter, but no callback data
parameter. This assumes that all callback functions only modify
global variables.
With this patch, every callback gets a void * parameter, and it is hoped
that this will help the libification effort.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
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>
git-rev-list accepts --reverse, as documented in
the manpage, but the usage string does not list it.
Signed-off-by: Kevin Ballard <kevin@sb.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
These flags are already known to rev-parse and have the same meaning.
This patch allows to run gitk as follows:
gitk --branches --not --remotes
to show only your local work.
Signed-off-by: Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
A failure in prepare_revision_walk can be caused by
a not parseable object.
Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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>
A NUL byte at beginning of file, or just after a newline
would provoke an invalid buf[-1] access in a few places.
* builtin-grep.c (cmd_grep): Don't access buf[-1].
* builtin-pack-objects.c (get_object_list): Likewise.
* builtin-rev-list.c (read_revisions_from_stdin): Likewise.
* bundle.c (read_bundle_header): Likewise.
* server-info.c (read_pack_info_file): Likewise.
* transport.c (insert_packed_refs): Likewise.
Signed-off-by: Jim Meyering <meyering@redhat.com>
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>
Some uses of git-rev-list are to run it with --objects to see if
a range of objects between two or more commits is fully connected
or not. In such a case the caller doesn't care about the actual
object names or hash hints so formatting this data only for it to
be dumped to /dev/null by a redirect is a waste of CPU time. If
all the caller needs is the exit status then --quiet can be used
to bypass the commit and object formatting.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When the body of the commit log message contains a non-ASCII character,
format-patch correctly emitted the encoding header to mark the resulting
message as such. However, if the original message was fully ASCII, the
command line switch "-s" was given to add a new sign-off, and
the signer's name was not ASCII only, the resulting message would have
contained non-ASCII character but was not marked as such.
This was cherry-picked from the fix in 'master'
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>
When the body of the commit log message contains a non-ASCII character,
format-patch correctly emitted the encoding header to mark the resulting
message as such. However, if the original message was fully ASCII, the
command line switch "-s" was given to add a new sign-off, and
the signer's name was not ASCII only, the resulting message would have
contained non-ASCII character but was not marked as such.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This is Junio's patch with some stuff to make --bisect-all
compatible with --bisect-vars.
This option makes it possible to see all the potential
bisection points. The best ones are displayed first.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This changes the interporate() to replace entries with NULL values
by the empty string, and uses it to interpolate missing fields in
custom format output used in git-log and friends. It is most useful
to avoid <unknown> output from %b format for a commit log message
that lack any body text.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Earlier commit ce0cbad77 broke rev-list --bisect to cause it
segfault when the resulting set is empty.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This factorises some code and make a big function smaller.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Also remove the "len" parameter, as:
(1) it was used as a max boundary, and every caller used ~0u
(2) we check for final NUL no matter what, so it doesn't help for speed.
As a result most of the pp_* function takes 3 arguments less, and we need
a lot less local variables, this makes the code way more readable, and
easier to extend if needed.
This patch also fixes some spacing and cosmetic issues.
This patch also fixes (as a side effect) a memory leak intoruced in
builtin-archive.c at commit df4a394f (fmt was xmalloc'ed and not free'd)
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This patch arose from a discussion started by Jim Meyering's patch
whose intention was to provide better diagnostics for failed writes.
Linus proposed a better way to do things, which also had the added
benefit that adding a fflush() to git-log-* operations and incremental
git-blame operations could improve interactive respose time feel, at
the cost of making things a bit slower when we aren't piping the
output to a downstream program.
This patch skips the fflush() calls when stdout is a regular file, or
if the environment variable GIT_FLUSH is set to "0". This latter can
speed up a command such as:
GIT_FLUSH=0 strace -c -f -e write time git-rev-list HEAD | wc -l
a tiny amount.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Traditionally we had 16kB limit when formatting log messages for
output, because it was easier to arrange for the caller to have
a reasonably big buffer and pass it down without ever worrying
about reallocating.
This changes the calling convention of pretty_print_commit() to
lift this limit. Instead of the buffer and remaining length, it
now takes a pointer to the pointer that points at the allocated
buffer, and another pointer to the location that stores the
allocated length, and reallocates the buffer as necessary.
To support the user format, the error return of interpolate()
needed to be changed. It used to return a bool telling "Ok the
result fits", or "Sorry, I had to truncate it". Now it returns
0 on success, and returns the size of the buffer it wants in
order to fit the whole result.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 updates git-rev-list --objects to be a bit more careful
when listing a blob object to make sure the blob actually
exists, and uses it to make sure the quick-fetch optimization we
introduced earlier is not fooled by a previous incomplete fetch.
The quick-fetch optimization works by running this command:
git rev-list --objects <<commit-list>> --not --all
where <<commit-list>> is a list of commits that we are going to
fetch from the other side. If there is any object missing to
complete the <<commit-list>>, the rev-list would fail and die
(say, the commit was in our repository, but its tree wasn't --
then it will barf while trying to list the blobs the tree
contains because it cannot read that tree).
Usually we do not have the objects (otherwise why would we
fetching?), but in one important special case we do: when the
remote repository is used as an alternate object store
(i.e. pointed by .git/objects/info/alternates). We could check
.git/objects/info/alternates to see if the remote we are
interacting with is one of them (or is used as an alternate,
recursively, by one of them), but that check is more cumbersome
than it is worth.
The above check however did not catch missing blob, because
object listing code did not read nor check blob objects, knowing
that blobs do not contain any further references to other
objects. This commit fixes it with practically unmeasurable
overhead.
I've benched this with
git rev-list --objects --all >/dev/null
in the kernel repository, with three different implementations
of the "check-blob".
- Checking with has_sha1_file() has negligible (unmeasurable)
performance penalty.
- Checking with sha1_object_info() makes it somewhat slower,
perhaps by 5%.
- Checking with read_sha1_file() to cause a fully re-validation
is prohibitively expensive (about 4 times as much runtime).
In my original patch, I had this as a command line option, but
the overhead is small enough that it is not really worth it.
Signed-off-by: Junio C Hamano <junkio@cox.net>
The trick is to give a child commit that is not tree-changing
the same depth as its parent, so that the depth is propagated
properly along strand of pearls.
Signed-off-by: Junio C Hamano <junkio@cox.net>
If you have 5 commits in the set, commits that reach 2 or 3
commits are at halfway. If you have 6 commits, only commits
that reach exactly 3 commits are at halfway. The earlier one is
completely botched the math.
Signed-off-by: Junio C Hamano <junkio@cox.net>
In a path-limited bisection, when the $bad commit is not
changing the limited path, and the number of suspects is 1, the
code miscounted and returned $bad from find_bisection(), which
is not marked with TREECHANGE. This is of course filtered by
the output routine, resulting in an empty output, in turn
causing git-bisect driver to say "$bad was both good and bad".
Illustration. Suppose you have these four commits, and only C
changes path P. You know D is bad and A is good.
A---B---C*--D
git-bisect driver runs this to find a bisection point:
$ git rev-list --bisect A..D -- P
which calls find_bisection() with B, C and D. The set of
commits that is given to this function is the same set of
commits as rev-list without --bisect option and pathspec
returns. Among them, only C is marked with TREECHANGE. Let's
call the set of commits given to find_bisection() that are
marked with TREECHANGE (or all of them if no path limiter is in
effect) "the bisect set". In the above example, the size of the
bisect set is 1 (contains only "C").
For each commit in its input, find_bisection() computes the
number of commits it can reach in the bisect set. For a commit
in the bisect set, this number includes itself, so the number is
1 or more. This number is called "depth", and computed by
count_distance() function.
When you have a bisect set of N commits, and a commit has depth
D, how good is your bisection if you returned that commit? How
good this bisection is can be measured by how many commits are
effectively tested "together" by testing one commit.
Currently you have (N-1) untested commits (the tip of the bisect
set, although it is included in the bisect set, is already known
to be bad). If the commit with depth D turns out to be bad,
then your next bisect set will have D commits and you will have
(D-1) untested commits left, which means you tested (N-1)-(D-1)
= (N-D) commits with this bisection. If it turns out to be good, then
your next bisect set will have (N-D) commits, and you will have
(N-D-1) untested commits left, which means you tested
(N-1)-(N-D-1) = D commits with this bisection.
Therefore, the goodness of this bisection is is min(N-D, D), and
find_bisection() function tries to find a commit that maximizes
this, by initializing "closest" variable to 0 and whenever a
commit with the goodness that is larger than the current
"closest" is found, that commit and its goodness are remembered
by updating "closest" variable. The "the commit with the best
goodness so far" is kept in "best" variable, and is initialized
to a commit that happens to be at the beginning of the list of
commits given to this function (which may or may not be in the
bisect set when path-limit is in use).
However, when N is 1, then the sole tree-changing commit has
depth of 1, and min(N-D, D) evaluates to 0. This is not larger
than the initial value of "closest", and the "so far the best
one" commit is never replaced in the loop.
When path-limit is not in use, this is not a problem, as any
commit in the input set is tree-changing. But when path-limit
is in use, and when the starting "bad" commit does not change
the specified path, it is not correct to return it.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This improves the performance of revision bisection.
The idea is to avoid rather expensive count_distance() function,
which counts the number of commits that are reachable from any
given commit (including itself) in the set. When a commit has
only one relevant parent commit, the number of commits the
commit can reach is exactly the number of commits that the
parent can reach plus one; instead of running count_distance()
on commits that are on straight single strand of pearls, we can
just add one to the parents' count.
On the other hand, for a merge commit, because the commits
reachable from one parent can be reachable from another parent,
you cannot just add the parents' counts up plus one for the
commit itself; that would overcount ancestors that are reachable
from more than one parents.
The algorithm used in the patch runs count_distance() on merge
commits, and uses the util field of commit objects to remember
them. After that, the number of commits reachable from each of
the remaining commits is counted by finding a commit whose count
is not yet known but the count for its (sole) parent is known,
and adding one to the parent's count, until we assign numbers to
everybody.
Another small optimization is whenever we find a half-way commit
(that is, a commit that can reach exactly half of the commits),
we stop giving counts to remaining commits, as we will not find
any better commit than we just found.
The performance to bisect between v1.0.0 and v1.5.0 in git.git
repository was improved by saying good and bad in turns from
3.68 seconds down to 1.26 seconds. Bisecting the kernel between
v2.6.18 and v2.6.20 was sped up from 21.84 seconds down to 4.22
seconds.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This adds --bisect-vars option to rev-list. The output is suitable
for `eval` in shell and defines five variables:
- bisect_rev is the next revision to test.
- bisect_nr is the expected number of commits to test after
bisect_rev is tested.
- bisect_good is the expected number of commits to test
if bisect_rev turns out to be good.
- bisect_bad is the expected number of commits to test
if bisect_rev turns out to be bad.
- bisect_all is the number of commits we are bisecting right now.
The documentation text was partly stolen from Johannes
Schindelin's patch.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Otherwise "git rev-list --header HEAD" will not do the right
thing if i18n.commitencoding is set.
Signed-off-by: Fredrik Kuivinen <frekui@gmail.com>
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>
We need to save the commit buffer if we're going to match against it.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This teaches the internal rev-list logic to understand options
that are needed for pack handling: --all, --unpacked, and --thin.
It also moves two functions from builtin-rev-list to list-objects
so that the two programs can share more code.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Create a separate file, list-objects.c, and move object listing
routines from rev-list to it. The next round will use it in
pack-objects directly.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When --stdin option is given, in addition to the <rev>s listed
on the command line, the command can read one rev parameter per
line from the standard input. The list of revs ends at the
first empty line or EOF.
Note that you still have to give all the flags from the command
line; only rev arguments (including A..B, A...B, and A^@ notations)
can be give from the standard input.
Signed-off-by: Junio C Hamano <junkio@cox.net>