-
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/
The short version of a SHA1 is composed of its first 7 characters. In order to transform a long SHA1 into a short one, we can use cut like so:
# Long SHA1
git rev-parse master
242d362cf1b5ccce4be5e23e10f1fa3474cdf828
# Short SHA1
git rev-parse --short master
242d362
# Short SHA1
git rev-parse master | cut -c 1-7
242d362
This example displays the long and short version of the SHA1 of the local master
branch.
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 SHA-1 1234567
to the tip of the current branch.
The new commit has the same commit message and modification but a different SHA-1, 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 SHA-1 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 SHA-1
1234567
for instance).
git format-patch -1 1234567 --stdout > 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 SHA-1 that corresponds to a ref-name like master.
# Convert ref-name ==> SHA-1
# master ==> ?
git rev-parse master
43dc2f87931f720f348c9a6ab4c67aa825afac18
You can also use this to get the SHA-1 of a tag.
To get the list of ref-names that correspond to a SHA-1:
# Convert SHA-1 ==> ref-name(s)
# 43dc2f87931f720f348c9a6ab4c67aa825afac18 ==> ?
git name-rev --name-only 43dc2f87931f720f348c9a6ab4c67aa825afac18
master
git describe --all --contains 43dc2f87931f720f348c9a6ab4c67aa825afac18
master
For the raw commit information associated with the git revision (SHA1, ref, branch name) passed as argument:
- SHA1 of the commit
- SHA1 of the tree
- SHA1 of each parent
- Author
- Author Date
- Committer
- Committer Date
- Commit Message
git show --pretty=raw HEAD
commit 7d35dc219fcbb98a293c3c7881e1dd80ab9151e1
tree 30695b87cce4814dcb04c61ecc502b3c2eb5feb8
parent caa1546c5266fba6deb9ce86b563623badefafcd
author Eric Bouchut <ebouchut@gmail.com> 1522153547 +0200
committer Eric Bouchut <ebouchut@gmail.com> 1522153551 +0200
Git: Add git alias "untrack"
This removes a file from the git index.
The side effect is that the file will be removed from the repository
on the next commit
diff --git a/tag-git/gitconfig b/tag-git/gitconfig
index d521135..9b4f290 100644
--- a/tag-git/gitconfig
+++ b/tag-git/gitconfig
@@ -33,6 +33,7 @@
tags = !git tag -l | sort -V
stashpp = ![[ -z $(git status --porcelain -uno) ]] && git pull || git stash && git pull && git stash pop
aliases = !git config --get-regexp 'alias.*' | colrm 1 6 | sed 's/[ ]/ = /'
+ untrack = rm --cache --
[apply]
whitespace = nowarn
[core]
Another option using the plumbing command cat-file
.
git cat-file -p HEAD
tree 30695b87cce4814dcb04c61ecc502b3c2eb5feb8
parent caa1546c5266fba6deb9ce86b563623badefafcd
author Eric Bouchut <ebouchut@gmail.com> 1522153547 +0200
committer Eric Bouchut <ebouchut@gmail.com> 1522153551 +0200
Git: Add git alias "untrack"
This removes a file from the git index.
The side effect is that the file will be removed from the repository
on the next commit
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 SHA-1 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
Show the content of the file README.md
as present in the tag v1.9.3
.
git show v1.9.3:CHANGELOG.md
Show the content of the file README.md
as present in the branch origin/release/1.9.4
.
git show origin/release/1.9.4:README.md
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
.
git show :/regex --
For instance here is how to search for the most recent commit whose message starts with Vim
.
git show :/^Vim --
git log -Sstring
Log commits where the string (factories
in the below example) has been added or removed from a file.
git log -Sfactories
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"
The below command search for the commit with SHA-1 123456
in all the branches and list their names:
git branch --all --contains 123456
* search_query
remotes/origin/search_query
The branches search_query
and origin/search_query
contain the commit with the SHA-1 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.
http://stackoverflow.com/a/15729420/386517
git commit -m "Description" --allow-empty
Making the very first commit an empty one may prove to be helpful should you need to amend/rebase the second commit. Without an empty commit you simply cannot do it. I often use this trick when creating the git repository of a Rails app where the message of the first/empty commit holds a short description of what the App is about.
Replace HEAD
with the SHA1 of a commit for which you want to know the SHA1 of the tree.
git rev-parse HEAD^{tree}