views:

1548

answers:

9

I have a git repository with few branches and dangling commits. I would like to search all such commits in repository for a specific string.

I know how to get a log of all commits in history, but these don't include branches or dangling blobs, just HEAD's history. I want to get them all, to find a specific commit that got misplaced.

I would also like to know how to do this in mercurial, as I'm considering the switch.

A: 

You may were looking for a way to do it from the commandline, but the mercurial web interface comes with a search function that can look in changeset comments affected paths and so on.

Git also has a web interface with it's own search function.

Hope this works for you!

azkotoki
+1  A: 

Any command that takes references as arguments will accept the --all option documented in the man page for git rev-list as follows:

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

So for instance git log -Sstring --all will display all commits that mention string and that are accessible from a branch or from a tag (I'm assuming that your dangling commits are at least named with a tag).

adl
+14  A: 

You can see dangling commits with git log -g.

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones.

So you could do this to find a particular string in a commit message that is dangling:

git log -g --grep=search_for_this

Alternatively, if you want to search the changes for a particular string, you could use the pickaxe search option, "-S":

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Finally, you could use gitk to visualise the dangling commits with:

gitk --all $(git log -g --pretty=format:%h)

And then use its search features to look for the misplaced file. All these work assuming the missing commit has not "expired" and been garbage collected, which may happen if it is dangling for 30 days and you expire reflogs or run a command that expires them.

rq
Perhaps instead of running "git grep" on a (possibly large) number of commits, which would find all commits that have 'search_for_this' somewhere in a project, use so called "pickaxe" search, i.e. '-S' option to git log, which finds commits that introduced or removed given string, or to be more exact where number of occurences of a given string changed.
Jakub Narębski
You can specify multiple branches, or use '--all' option, e.g. 'git log --grep="string in a commit message" --all'
Jakub Narębski
+1  A: 

Don't know about git, but in Mercurial I'd just pipe the output of hg log to some sed/perl/whatever script to search for whatever it is you're looking for. You can customize the output of hg log using a template or a style to make it easier to search on, if you wish.

This will include all named branches in the repo. Mercurial does not have something like dangling blobs afaik.

Kurt Schelfthout
+2  A: 

In addition to rq answer: take a look at the following blog posts by Junio C Hamano, current git maintainer

Jakub Narębski
+1  A: 

With Mercurial you do a

$ hg grep "search for this" [file...]

There are other options that narrow down the range of revisions that are searched.

Yawar
+2  A: 

In Mercurial you use hg log --keyword to search for keywords in the commit messages and hg log --user to search for a particular user. See hg help log for other ways to limit the log.

Martin Geisler
This question is about git, how is this going to help?
Sam Murray-Sutton
Josip wrote that he is considering to switch to Mercurial and that he would also like to hear how it's done there.
Martin Geisler
+1  A: 

Building on rq's answer, I found this line does what I want:

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

Which will report the commit ID, filename, and display the matching line, like this:

91ba969:testFile:this is a test

... Does anyone agree that this would be a nice option to be included in the standard git grep command?

Sam H
A: 

I like the answer form "Sam H"... Now for fun try to do this in Subversion. This seems like the common sort of task that shouldn't be too much to ask from a version control system, yet with SVN it's like pulling teeth.

Noah Spurrier