Reputation: 7275
I'd like to understand the difference between git log --all --grep=<>
and git log --grep=<>
. My goal is to traverse the whole repo when searching. If I don't add --all
, does it mean that I will miss all the commit messages in branches? Looks like a non-intuitive default to me.
Upvotes: 2
Views: 266
Reputation: 164809
git log
is a tool for traversing the commit graph and printing out commit information. --grep
is a filter on this traverse.
git log
starts from your current commit (ie. HEAD
) and works its way back through history from there.
git log --all
visits all commits. This is pretty rare, occasionally needed by an integrator.
--grep
is a filter. It filters the stream of commits visited by git log
. Filters only remove entries, never add. For each commit git log
visits --grep
decides whether that should be included. It might make more sense if you think of it like a normal Unix pipe.
git log | grep foo
Defaults should work best with the most common case. Commands like diff
and log
are most used in development. Integration happens far more rarely. So the defaults are targeted at developers.
The common use of git log
for developers is looking for changes which contributed to this commit. They're looking for answers to the question "why is this written like this?" or "where did this bug come from?". That's why the default is to walk the graph from your current commit. It's rare that you want to search commits which haven't been merged into your code, that's more the task of an integration manager.
--grep
doesn't change what commits git log
visits. If it implied --all
, that would be surprising and inflexible. Surprising because it would muddle the meaning of "filter" and it's pretty rare you want to search unrelated branches. Inflexible because how do you search only certain commits? I suppose you could require a --no-all
to turn it off, and then maybe more switches, probably --branches
, to get what you mean.
There are rare instances where having multiple default behaviors works out, but it's usually a nightmare. It's better to have a firm common use case in mind (development) and not guess about rarer cases (integration). Let rare cases be explicit about what they want.
Upvotes: 1
Reputation: 488183
You're correct that you need --all
here (or perhaps you might want --branches
instead).
"Intuitive" in git is a bit tricky, and the behavior of git log
is intuitive to me, but only because I've studied git and its peculiar notions of how to work with commit graphs.
The log
command is not very different from all the other commit-graph-traversing commands. They all work like—in fact, many of then simply run, or run and then use the output of—git rev-list
. You give it some starting point commit IDs, or some names or any of the syntax described in gitrevisions
, and it finds the SHA-1 IDs of every commit reachable from those IDs.
Every commit inside the repo—including commits that have been "abandoned" (but are still findable via reflogs) because of a rebase copy operation, commits that are on the stash stack, and even git notes
commits—works this way, so it would be bad for git log
to find all commits. Even the --all
flag doesn't actually find all commits.
If you peruse the git rev-list
documentation, you'll see that --all
means "every reference in the refs/
namespace" (hence all branches, all tags, and notes, but not special references like ORIG_HEAD
left behind after a rebase, nor any reflog entries, for instance). The same wording appears in the git log
documentation, but I like to refer people to git rev-list
since I think it is ultimately more revealing.
Upvotes: 1