-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
In this section
-
<commit-ish>
denotes any revision that refers to a commit. To learn more, read this.
- http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
- https://github.com/torvalds/linux/pull/17#issuecomment-5659933
- http://chris.beams.io/posts/git-commit/
git commit -v
The option -v
of git commit
launches the editor with the usual list of modified files plus the difference (git diff
) below, so that you can take a look at the changes while writing the commit message.
Do not worry the diff is not part of the commit message when you save the file.
git cherry-pick 1234567
Add the commit with the SHA1 1234567
to the tip of the current branch.
The new commit has the same commit message and modification but a different SHA1, date.
Assuming we want to pick the commits a
, b
, c
(ordered by date) to rebase them on the current branch.
git log -3 c # ordered by reverse chronological order (most recent first)
c
b
a
Here is how to do this.
git cherry-pick a^..c
Add the commits from SHA1 a
up to and including c
to the tip of the current branch.
Commit a
must be older than c
.
FYI, a..c
denotes the commits b
and c
, that is from a
(not included) up to and including c
.
This is why I append a caret after a
to make sure it is included in the range.
- Generate a patch file for a commit (say the commit with the SHA1
1234567
for instance).
git format-patch -1 1234567 --output - > file.patch
- Apply the patch
# Show patch stats
git apply --stat file.patch
# Check for error before applying
git apply --check file.patch
# Apply the patch
git am < file.patch
This may be useful when the very last commit does not contain the correct (user name or) user email because you made a commit with the wrong user name and/or email. This can be changed provided you did not pushed the commit a remote repository.
Say for instance, I have on my computer both personal and corporate repositories. I need to use a distinct e-mail address for each kind:
- personal: eric@perso.example.org
- corporate: eric@corp.example.com
I configured user.email
and/or user.email
globally with my personal name and email address like so.
git config --global user.name "Eric Bouchut"
git config --global user.email eric@perso.example.org
Then I clone a corporate repository, commit a change. I notice immediately after while running git log that I forgot to set my corporate e-mail address (eric@corp.example.com) for this project.
git log -1
commit 3c7abd382b653fc58f3ca890f220cb4de9adb65a
Author: Eric Bouchut <eric@perso.example.org>
Date: Fri Mar 4 14:45:18 2016 +0100 │
Change settings
The last commit (git log -1
) contains my personal email address eric.perso.example.org
instead of the corporate one eric@corp.example.com
!
Assuming I did not pushed this commit to any remote repository, here how to fix this. First, when in the repository I set my corporate e-mail address for this corporate repository.
# cd into the repository beforehand
#
# git config user.name "Eric Bouchut"
git config user.email eric@corp.example.com
I then fix the author name and email of the very last commit, like so
git commit --amend --reset-author --no-edit
The option --amend
asks git to change the most recent commit, --no-edit
left the commit message unchanged and --reset-author
replaces the author user name and e-mail address with the one in the local git configuration, that is Eric Bouchut <eric@corp.example.com>
.
The above command basically does the same thing as:
git commit --amend --no-edit --author "Eric Bouchut <eric@corp.example.com>"
This is now fixed, as I can see the email address changed.
git log -1
commit 77f5b4bd0f7813379dd9a2f6d8d2658a55e9cadc
Author: Eric Bouchut <eric@corp.example.com>
Date: Fri Mar 4 14:49:01 2016 +0100 │
Change settings
Say you are in the middle of editing the commit message in vim, and you want to cancel the commit.
Typing :q!<CR>
will not prevent the commit from being made.
You have two options:
- Make sure the commit message is empty and save it using
:wq<CR>
- or type
:cquit!<CR>
The latter does:
- not save the file
exit with an error code
Git will then figure out vim failed and cancel the commit.
git commit
# You are now in vim typing your commit message
# and figure out you would like to prevent the commit from being made
# Type this:
:cquit!<CR>
See girevisions(7) and Revisions Selection in the Pro-Git book.
To get the SHA1 that corresponds to a ref-name like master.
# Convert ref-name ==> SHA1
# master ==> ?
git rev-parse master
43dc2f87931f720f348c9a6ab4c67aa825afac18
You can also use this to get the SHA1 of a tag.
To get the list of ref-names that correspond to a SHA1:
# Convert SHA1 ==> ref-name(s)
# 43dc2f87931f720f348c9a6ab4c67aa825afac18 ==> ?
git name-rev --name-only 43dc2f87931f720f348c9a6ab4c67aa825afac18
master
git describe --all --contains 43dc2f87931f720f348c9a6ab4c67aa825afac18
master
Say you want to see what the file foo/bar/joe
looks like at the commit 1234560
.
git show 1234560:foo/bar/joe
If you omit the SHA1 commit, HEAD
is used instead.
HEAD denotes the tip of the current branch, say master
if you are on that branch.
git show :foo/bar/joe
# Same as
# git show HEAD:foo/bar/joe
Say you want to get the file foo/bar/joe
at the commit 1234560
.
git checkout 1234560 -- foo/bar/joe
This will overwrite the working copy of the file foo/bar/joe
with what it looked like at commit 1234560
.
git ls-tree --name-only -r <commit-ish>
git ls-tree --name-only -r HEAD
README.md
LICENSE
In the above example, the commit referenced by HEAD contains 2 files README.md
and LICENSE
git diff-tree --no-commit-id --name-only -r <commit-ish>
There is at least two ways to get this:
git diff-tree --no-commit-id --name-only -r HEAD
README.md
git log --name-only -1 HEAD
commit 36718c78caf9247c7dfb81a3844fa2c781bdee17
Author: Eric Bouchut <eric@example.com>
Date: Mon Jan 26 22:19:49 2015 -0500
Updated README
README.md
Here the only file modified in the commit referenced by HEAD is README.md
.
I want to restore the working tree to the state it was in at commit 1234560
because what I have done after this commit is either buggy or does not work.
I however do not want to rewrite the history by removing commits (1661fc2
and 59e2e45
) because I already have pushed them upstream.
git revert
will undo the modifications up to but not including commit 1234560
.
git log --oneline --decorate
1661fc2 (HEAD, master) New layout engine
59e2e45 Tweak settings panel
1234560 Finalize UI
...
3e06842 First commit
- Ensure you working tree is clean by either ignoring, stashing or committing the files that are not yet in the repository.
- Revert to the commit
1234560
git revert -n 1234560..HEAD
This modifies the working tree to cancel the changes done after commit 1234560
and up to the tip of the current branch (1661fc2
and 59e2e45
).
The -n
flag asks git revert
not to commit the changes which gives us the opportunity to review them.
- Commit the changes to the repository
git commit -m "Revert to 1234560"
To determine if a Git repository contains a commit with a given SHA1 (say 123456 for instance), use the following:
git branch -a --contains 123456 # 123456 is the SHA1 of the commit I'm searching for
* search_query
remotes/origin/search_query
In this example, the branches search_query
and origin/search_query
contains the commit whose SHA1 is 123456
.
Say you comited a big file or a private file (including passwords...) a while ago. You now want to remove it from the repository so that it no longer exists.