1197

I checked some source code into GIT with the commit message "Build 0051".

However, I can't seem to find that source code any more - how do I extract this source from the GIT repository, using the command line?

Update

  1. Checked in versions 0043, 0044, 0045 and 0046 using SmartGIT.
  2. Checked out 0043, and checked in versions up to 0051 on a different branch.
  3. Checked out 0043 again.
  4. Now, 0051 has disappeared.

Update

The source code is definitely there, now its a matter of checking it out:

C:\Source>git log -g --grep="0052"
commit 77b1f718d19e5cf46e2fab8405a9a0859c9c2889
Reflog: HEAD@{10} (unknown <Mike@.(none)>)
Reflog message: commit: 20110819 - 1724 - GL: Intermediate version. File version:  v0.5.0 build 0052.
Author: unknown <Mike@.(none)>
Date:   Fri Aug 19 17:24:51 2011 +0100

    20110819 - 1724 - GL: Intermediate version. File version: v0.5.0 build 0052.

C:\Source>
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Contango
  • 76,540
  • 58
  • 260
  • 305
  • 3
    See also: [How to search through all commits in the repository?](http://stackoverflow.com/questions/746684/how-to-search-through-all-commits-in-the-repository) – rsenna Jul 08 '13 at 14:55
  • 1
    See also http://stackoverflow.com/questions/18122628/how-to-search-for-a-commit-message-in-github – ripper234 Aug 08 '13 at 09:36
  • possible duplicate of [How to grep git commits for a certain word](http://stackoverflow.com/questions/1337320/how-to-grep-git-commits-for-a-certain-word) –  Sep 05 '13 at 22:02

13 Answers13

1799

To search the commit log (across all branches) for the given text:

git log --all --grep='Build 0051'

To do so while ignoring case in the grep search:

git log --all -i --grep='Build 0051'

To search the actual content of commits through a repo's history, use:

git grep 'Build 0051' $(git rev-list --all)

to show all instances of the given text, the containing file name, and the commit sha1.

And to do this while ignoring case, use:

git grep -i 'Build 0051' $(git rev-list --all)

Note that this searches the entire content of the commit at each stage, and not just the diff changes. To search just the diff changes, use one of the following:

git log -S[searchTerm]
git log -G[searchTerm]

Finally, as a last resort in case your commit is dangling and not connected to history at all, you can search the reflog itself with the -g flag (short for --walk-reflogs:

git log -g --grep='Build 0051'

EDIT: if you seem to have lost your history, check the reflog as your safety net. Look for Build 0051 in one of the commits listed by

git reflog

You may have simply set your HEAD to a part of history in which the 'Build 0051' commit is not visible, or you may have actually blown it away. The git-ready reflog article may be of help.

To recover your commit from the reflog: do a git checkout of the commit you found (and optionally make a new branch or tag of it for reference)

git checkout 77b1f718d19e5cf46e2fab8405a9a0859c9c2889
# alternative, using reflog (see git-ready link provided)
# git checkout HEAD@{10}
git checkout -b build_0051 # make a new branch with the build_0051 as the tip
Jez
  • 27,951
  • 32
  • 136
  • 233
shelhamer
  • 29,752
  • 2
  • 30
  • 33
  • 3
    with git grep 'Build 0051' $(git rev-list --all) I get sh.exe": /bin/git: Bad file number has the way to do this changed maybe? – Jens Schauder Jul 03 '15 at 09:35
  • 9
    git log -i -grep – jhvaras Jul 18 '17 at 15:59
  • @JensSchauder If you run into an error with `git grep 'search' $(git rev-list --all)`, try `git rev-list --all | xargs git grep 'search'` – afilina Sep 23 '19 at 14:15
  • 3
    On Windows I had to use double-quotes instead of single-quotes to get this to work. – esteuart Jul 20 '20 at 17:19
  • @shelhamer What's the difference between `git log --all --grep='Build 0051'` and `git grep 'Build 0051' $(git rev-list --all)`? – John Apr 30 '22 at 14:48
111

I put this in my ~/.gitconfig:

[alias]
    find = log --pretty=\"format:%Cgreen%H %Cblue%s\" --name-status --grep

Then I can type "git find string" and I get a list of all the commits containing that string in the message. For example, to find all commits referencing ticket #33:

029a641667d6d92e16deccae7ebdeef792d8336b Added isAttachmentEditable() and isAttachmentViewable() methods. (references #33)
M       library/Dbs/Db/Row/Login.php

a1bccdcd29ed29573d2fb799e2a564b5419af2e2 Add permissions checks for attachments of custom strategies. (references #33).
M       application/controllers/AttachmentController.php

38c8db557e5ec0963a7292aef0220ad1088f518d Fix permissions. (references #33)
M       application/views/scripts/attachment/_row.phtml

041db110859e7259caeffd3fed7a3d7b18a3d564 Fix permissions. (references #33)
M       application/views/scripts/attachment/index.phtml

388df3b4faae50f8a8d8beb85750dd0aa67736ed Added getStrategy() method. (references #33)
M       library/Dbs/Db/Row/Attachment.php
BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
Alex Howansky
  • 50,515
  • 8
  • 78
  • 98
  • 3
    Nice, but perhaps missing a colour reset? `--pretty=\"format:%Cgreen%H %Cblue%s%Creset\"` – Ashley Coolman Oct 13 '15 at 12:29
  • 12
    I prefer to print the full git message (grep may be happened there, not in the title), so I ended up with: `find = log --all --pretty=\"format:%Cgreen%H %Cblue%s\n%b%Creset\" --name-status --grep`. Note the `--all` and `%b` chars. Thx @AshleyCoolman for the `reset` tip. – arcol Feb 22 '16 at 14:27
  • 12
    Thanks. I found the alias very useful. I didn't like the coloring and found the oneline format perfect for this. Also adding -i to make it case-insensitive was helpful. e.g. `find = log --oneline --name-status -i --grep` – robbp Jul 18 '18 at 15:53
69

Though a bit late, there is :/ which is the dedicated notation to specify a commit (or revision) based on the commit message, just prefix the search string with :/, e.g.:

git show :/keyword(s)

Here <keywords> can be a single word, or a complex regex pattern consisting of whitespaces, so please make sure to quote/escape when necessary, e.g.:

git log -1 -p ":/a few words"

Alternatively, a start point can be specified, to find the closest commit reachable from a specific point, e.g.:

git show 'HEAD^{/fix nasty bug}'

See: git revisions manual.

ryenus
  • 15,711
  • 5
  • 56
  • 63
  • Cool, didn't know that! Now how can I get the parent commit using this notation? The usual `^` doesn't seem to work. – LoneCodeRanger Oct 24 '22 at 22:13
  • Easy :-) you just do it with two git commands, like `git rev-parse $(git rev-parse :/keyword)~` @AndreiToroplean – ryenus Nov 02 '22 at 02:32
36
git log --grep="Build 0051"

should do the trick

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
31
git log --grep=<pattern>
            Limit the commits output to ones with log message that matches the
            specified pattern (regular expression).
Josh Lee
  • 171,072
  • 38
  • 269
  • 275
18

Try this!

git log | grep -b3 "Build 0051"
Nic
  • 13,287
  • 7
  • 40
  • 42
  • Thanks - but its not finding it. How do I search across all possible branches? – Contango Aug 19 '11 at 17:02
  • 7
    You want to use `git grep` instead of normal grep, and provide the `--all` flag to search multiple branches. – shelhamer Aug 19 '11 at 17:03
  • 1
    Hmm - are the other answers finding it either? If not, you might have a bigger problem. I'd try `git log --all --grep='Build 0051'` (@shelhamer's answer) – Nic Aug 19 '11 at 17:04
  • I tried "git log --all", and it only lists versions to 0046. Version 0051 was on a different branch. I rolled back to 0043, and 0051 disappeared. – Contango Aug 19 '11 at 17:07
  • Sounds like you may have lost your history when you rolled back? – Nic Aug 19 '11 at 17:08
  • Version 0051 was branched off 0043. Is it possible for GIT to just randomly delete source code? – Contango Aug 19 '11 at 17:11
  • 3
    @Gravitas, try my example that uses the reflog: the one with `git log -g`. You may have lost history in a reset, but you can still check the reflog if it hasn't been garbage collected. – shelhamer Aug 19 '11 at 17:13
10

Just a small addition to the git log --all --grep command: In my case I had to escape the brackets inside the message:

git log --all --grep="\[C\] Ticket-1001: Fix nasty things"
thedoctar
  • 8,943
  • 3
  • 20
  • 31
ratfury
  • 203
  • 2
  • 9
  • 2
    After finding the commit, you may want to find it's branch: `git branch -a --contains ` (Credit to https://stackoverflow.com/a/2707110/557406) – Charles L. Sep 28 '22 at 19:01
8

first to list the commits use

git log --oneline

then find the SHA of the commit (Message), then I used

 git log --stat 8zad24d

(8zad24d) is the SHA assosiated with the commit you are intrested in (the first couples sha example (8zad24d) you can select 4 char or 6 or 8 or the entire sha) to find the right info

Ridha Rezzag
  • 3,672
  • 1
  • 34
  • 39
8

To search across all the branches

git log --all --grep='Build 0051'

Once you know which commit you want to get to

git checkout <the commit hash>
Samarth S
  • 313
  • 4
  • 5
6

For anyone who wants to pass in arbitrary strings which are exact matches (And not worry about escaping regex special characters), git log takes a --fixed-strings option

git log --fixed-strings --grep "$SEARCH_TERM" 
Marvin Irwin
  • 938
  • 7
  • 17
3

If the change is not too old, you can do,

git reflog

and then checkout the commit id

joseph
  • 940
  • 10
  • 19
2

This:

git log --oneline --grep='Searched phrase'

or this:

git log --oneline --name-status --grep='Searched phrase'

commands work best for me.

simhumileco
  • 31,877
  • 16
  • 137
  • 115
0

in gitk you can search by commit message:

enter image description here

You can install gitk by command sudo apt install gitk

suhailvs
  • 20,182
  • 14
  • 100
  • 98