Skip to content
Eric Bouchut edited this page Dec 28, 2022 · 67 revisions

Git Log

List the permissions of a file

git ls-files HEAD -- README.md
  100644 3bf618a1066a1dd68affd16dc9a67e0dc8bc6b81 0       README.md

The first number contains the file mode (type + permissions...). It is a regular file (1) with the following permissions rw-r--r-- (644).

Compare (a File in) a Branch against the Working Directory

Here is how to compare the branch master against the current working directory.

git diff master .

Below I compare the file CHANGELOG.md on the tip of branch master against the one in the working directory.

git diff master -- CHANGELOG.md

Compare (a File in) a Branch against the Staging Area

Here is how to compare the branch master against the content of the staging area.

git diff --staged master 

Below I compare the file CHANGELOG.md on the tip of branch master against the one in the staging area.

git diff --staged master -- CHANGELOG.md

You can use either the option --staged or --cached, each one reflecting the naming variants for the same thing: staging area or cache.

Compare (a File in) 2 Branches

Here is how to compare the branches master and develop.

git diff master develop

Below I compare the file CHANGELOG.md on the tip of branch master with the one on develop.

git diff master develop -- CHANGELOG.md

List commits where a file has been modified

git log --source -- file

This only logs the commits/refs where file has been modified .

Revisions

Caret (^) and tilde (~}

A merge commit has (at least) 2 parents, the main branch and the branch(es) merged into the main branch.

Say for instance, you create a feature branch based on master. In this example, master is the main branch (the base branch you created a new branch from), feature-42 is the feature branch.

git checkout master
git checkout -b feature-42  # Create the branch feature-42 out of master and jump on it

# Edit some files
git commit -m "Feature #42: part 1"

# Edit some other files
git commit -m "Feature #42: part 2"

# Jump back to master, now that we are ready to merge in the feature branch 
git checkout master
git merge --no-ff feature-42  # Using --no-ff to require the creation of a merge commit even if fast forward is possible

# At this point, both HEAD and master reference the merge commit

Tilde is always relative to the main branch (master in this example). **Caret

TODO

Search for commits where a string has been added/removed

git log -Sstring

Log commits where the string (factories in the below example) has been added or removed from a file.

git log -Sfactories

Search for commits whose message matches a regex

Here is how to search in the current branch for commit whose message matches for instance the pattern flog.

git log --grep=flog
commit 7f499d9a74a6200d885c4028107b9f57912109db
Author: Eric Bouchut <ebouchut@gmail.com>
Date:   Mon May 30 14:53:21 2016 +0200

    Vim: Disable plugin vim-flog

    Vim-flog increases singnificantly vim's load time

commit 293a197f4903e432699c7befbcf57ccb9aaa090a
Author: Eric Bouchut <ebouchut@gmail.com>
Date:   Tue Apr 26 17:48:52 2016 +0200

    Vim: <Leader>f  toggle flog

    Display/Hide the cyclomatic complexity next to each Ruby method

commit b01b5c97bd78df2b0704014262c26dc96be35925
Author: Eric Bouchut <ebouchut@gmail.com>
Date:   Mon Apr 25 17:26:43 2016 +0200

    vim: plugin: Add vim-flog

    Compute the cyclomatic complexity of Ruby methods

    Require: gem install flog

    See: http://ruby.sadi.st/Flog.html

Search and show the most recent commit on a branch whose commit matches a regex

To see the changes of the most recent commit on the branch my_branch whose commit matches for instance flog.

git show my_branch:/flog   # You can omit my_branch if it is the current branch
commit 7f499d9a74a6200d885c4028107b9f57912109db
Author: Eric Bouchut <ebouchut@gmail.com>
Date:   Mon May 30 14:53:21 2016 +0200

    Vim: Disable plugin vim-flog

    Vim-flog increases singnificantly vim's load time

diff --git a/vimrc b/vimrc
index 40047f9..85d37b9 100644
--- a/vimrc
+++ b/vimrc
@@ -50,7 +50,7 @@ Plug         'xolox/vim-misc'          " required by vim-session
 Plug         'jistr/vim-nerdtree-tabs' " NERDTree and tabs together in Vim
 Plug     'powerman/vim-plugin-AnsiEsc' " for colorful charts in taskwiki
 Plug   'christoomey/vim-quicklink'   " Look up a topic in google and insert the markdwn link
-Plug 'sentientmonkey/vim-flog' " Compute Ruby cyclomatic complexity with flog
+" Plug 'sentientmonkey/vim-flog' " Compute Ruby cyclomatic complexity with flog
 Plug        'tpope/vim-repeat'
 Plug         'tpope/vim-projectionist'
 Plug       'blindFS/vim-taskwarrior' " interface to task-warrior (required)

RealTime Log

Here is a trick I use often in an iTerm pane to see the evolution of the commits graph of a repository in "real-time". It basically is an endless loop, that every 3 seconds, clears the screen, then displays the commits graph of all branches.

watch -n3 --color   git log --oneline --decorate --graph  --color --all

Once watch is running in a pane, you can open a separate pane, use git commands as usual and see how the impact on the repository graph.

If you use this command often, a git alias comes in handy. Here is how to create one named plog-watch.

git config --global alias.plog-watch '!watch -n3 --color   git log --oneline --decorate --graph  --color --all'

Once created, you can use it like so.

git plog-watch

Pretty Log output

Here is a useful alias to display the log. For each commit display the following:

  • short SHA-1 of the commit
  • Author Name
  • Any tags, branch names... (aka ref-names in git parlance) associated to the commit
  • Commit message
  • Relative date

You only need to add it once like so:

git config --global  alias.plog "log --graph --format='%Cgreen%h %Cred%aN%Cblue%d%Creset %s %C(yellow)(%cr)%Creset'"

And then each time you type git plog you get a nicer log output.

plog screenshot

List only my commits

It is based on the alias plog (see "Pretty Log" above), so if you have not already created it please do so beforehand. Here is how to configure it once for your system.

git config--global alias.mine '!git plog --author="$(git config user.name) <$(git config user.email)>"'

From now on, you can use it like so.

git mine  # My commits on the current branch
git mine --since "one week ago" master # The commits I have made in master since one week ago
git mine master..develop  # My commits in develop that are not yet in master

List my today's commits

This git alias lists the commits I made today since midnight. It is based on the alias plog (see "Pretty Log" above), so if you have not already created it please do so beforehand.

# One time configuration
git config --global alias.today `!git plog --since=midnight --author="$(git config user.name) <$(git config user.email)>"'

You can then use it like so.

git today

List the commits I have made since the last 7 days

This git alias lists the commits I made since the last 7 days. It is based on the alias plog (see "Pretty Log" above), so if you have not already created it please do so beforehand.

# One time configuration
git config --global alias.today `!git plog --since "one week ago" --author="$(git config user.name) <$(git config user.email)>"'

You can then use it like so.

git week

Even more useful, have a look at the git-standup utility to easily find the commits you (or someone else) have done for the last X days.

List commits present on the local branch but not on the remote branch

Here is how the local branch (master) evolved compared to its remote counterpart (origin/master). In other words lists the commits present on master but do not do not exist in origin/master.

git checkout master # For the sake of exampple

git log origin/master..master

# equivalent to 
#   git log --not origin/master master
# or 
#   git log @{u}..HEAD
# or 
#   git log @{u}..    # HEAD is implied when not mentioned
  • @{u} denotes the remote branch (origin/master in this example). However using @{u} is a generic way to denote the remote branch whatever its name!
  • HEAD denotes the current local branch. Likewise it is a generic way to denote the tip of the current branch whatever its name.

Here is a handy git alias that does exactly that.

git config --global alias.outgoing '!git remote update && git plog @{u}..'

From now on, git outgoing lists the outgoing commits that would be pushed to the remote branch with git push origin master. This stackoverflow post explains this visually.

List commits present on the remote branch but not on the local branch

Here is how the remote branch (origin/master) evolved compared to its local counterpart (master).

git checkout master

git log master..origin/master

# equivalent to 
#   git log --not master origin/master
# or 
#   git log HEAD..@{u}   # HEAD denotes the current branch (master in this example)
# or 
#   git log ..@{u}    # HEAD is implied when not mentioned
  • @{u} denotes the remote branch (origin/master in this example)
  • HEAD denotes the current local branch

Here is a handy git alias that does exactly that, git incoming lists the incoming commits that you would retrieve from the remote branch with git pull.

git config --global alias.incoming '!git remote update && git plog ..@{u}'

This stackoverflow post gives a visual clue about what the double dots (..) does.

List commits in between a tag and the tip of a branch

List the commits in between the tag 1.7.0.22 (excluded) and the tip of the master branch (included), that is the commits that are on master but not on 1.7.0.22.

git log 1.7.0.22..master

# which is equivalent to 
#   git log ^1.7.0.22  master
# or 
#   git log master --not 1.7.0.22

List all Commits from a Merged Branch

Here is how to get all the commits from the feature/123 branch that was merged in master. Assuming the SHA1 of the merge commit is abc.

git log abc^-

List files in the repository

List files in in the current branch

git ls-tree  

#  git ls-tree -r HEAD --name-only   # a more verbose alternative

List files in a branch

List the files in the repository for the branch my_branch.

git ls-tree -r my_branch --name-only 

Source: http://superuser.com/a/429694/67956

List file differences between 2 commits

For instance to list the differences between master and develop for the file path/to/file.

git diff master..develop -- path/to/file

You can also list the differences on a commit by commit basis.

git log -u master..develop -- path/to/file 

List branches and tags containing a commit

Here is how to list the branches containing the commit whti SHA1 123456 and the tags referencing this commit.

git branch --all --contains 123456
git tag --contains 123456

Below a handy git alias you can create once to perform both of these actions in one feel swoop.

git config --global alias.whereis '!f() { echo Branches: >&2; git branch --all --contains "$1"; echo Tags: >&2; git tag --contains "$1"; }; f'

Once created you can use it on this computer logged in as you, like so.

git whereis 123456

Where is the Working Directory?

git rev-parse --show-toplevel

/Users/eric/dev/project

List the root commit

Log the very first commit of the current branch:

git log --max-parents=0

Display the SHA1 of the very first commit:

git log --max-parents=0 --format=%H

List the commits of a deleted file

git plog --full-history -- path/to/deleted_file

List the deleted files

Each line contains (among other things) the path of a removed file and the SHA1 of commit that removed it.

git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e '}'

Restore a deleted file

git checkout $SHA1_OF_COMMIT_THAT_REMOVED_FILE~1 -- path/to/removed_file
Clone this wiki locally