Short code snippets for all your development needs.
The Git snippet collection contains a variety of short tips and tricks for all currently maintained versions of git. It includes most commonly-used commands and covers various use-cases in the form of simplified documentation, complete with multiple examples.
Now, let's start our learning about Git !
Git Configuration🐙
Git aliases⭐
Use the command below to create aliases, replacing <alias>
with the name of the alias and <command>
with the command to be aliased:
$ git config --global alias.<alias> <command>
Additionally, you can use git config --global -e
to open the git configuration file in the git text editor and add many aliases all at once.
$ git config --global -e
Example 1
$ git config --global alias.br branch
Example 2
$ git config --global alias.undo "reset HEAD~1"
Example 3
$ git config --global alias.cm "commit -m 'update on `date +%Y-%m-%d`'"
Useful aliases
[alias]
co = checkout
cob = checkout -b
coo = !git fetch && git checkout
br = branch
brd = branch -d
st = status
aa = add -A .
unstage = reset --soft HEAD^
cm = commit -m
amend = commit --amend -m
fix = commit --fixup
undo = reset HEAD~1
rv = revert
cp = cherry-pick
pu = !git push origin `git branch --show-current`
fush = push -f
mg = merge --no-ff
rb = rebase
rbc = rebase --continue
rba = rebase --abort
rbs = rebase --skip
rom = !git fetch && git rebase -i origin/master --autosquash
save = stash push
pop = stash pop
apply = stash apply
rl = reflog
Disable fast forward merging by default⭐
Disables the default fast forwarding on merge commits.
Use git config --add merge.ff false
to disable fast-forward merging for all branches, even if it is possible.
You can use the --global
flag to configure this option globally.
$ git config [--global] --add merge.ff false
Example
$ git config --global --add merge.ff false
$ git checkout my-branch
$ git merge master
# Will never fast forward even if it's possible
Former merge
(Fast-forward)
$ git-log
* a8c017f (HEAD -> master) update on 2021-10-09
* 3a6eba4 (origin/master) 2021年10月 9日 8:47:28
* 4975bc2 update
* ceecd3d hello git cm
* fc60abe Merge remote-tracking branch 'origin'
|\
| * 38c5cfb users
* | dd7a2ca account
|/
* f6f067d add .gitignore.
* e990479 add remote.txt at gitee
* 620fea2 (origin/main, dev2) update on dev2
* fa343b7 comment
$ git checkout dev1
Switched to branch 'dev1'
$ git merge master
Updating 7163b62..a8c017f
Fast-forward
.gitignore | 0
dev2.txt | 0
readme.txt | 8 +++++---
remote.txt | 1 +
4 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 .gitignore
create mode 100644 dev2.txt
create mode 100644 remote.txt
$ git-log
* a8c017f (HEAD -> dev1, master) update on 2021-10-09
* 3a6eba4 (origin/master) 2021年10月 9日 8:47:28
* 4975bc2 update
* ceecd3d hello git cm
* fc60abe Merge remote-tracking branch 'origin'
|\
| * 38c5cfb users
* | dd7a2ca account
|/
* f6f067d add .gitignore.
* e990479 add remote.txt at gitee
* 620fea2 (origin/main, dev2) update on dev2
* fa343b7 comment
Configured merge
(Merge made by the 'recursive' strategy)
$ git-log
* a8c017f (HEAD -> dev1, master) update on 2021-10-09
* 3a6eba4 (origin/master) 2021年10月 9日 8:47:28
* 4975bc2 update
* ceecd3d hello git cm
* fc60abe Merge remote-tracking branch 'origin'
|\
| * 38c5cfb users
* | dd7a2ca account
|/
* f6f067d add .gitignore.
* e990479 add remote.txt at gitee
* 620fea2 (origin/main, dev2) update on dev2
* fa343b7 comment
$ git checkout dev2
Switched to branch 'dev2'
Your branch is up to date with 'origin/main'.
$ git merge master
Merge made by the 'recursive' strategy.
.gitignore | 0
remote.txt | 1 +
2 files changed, 1 insertion(+)
create mode 100644 .gitignore
create mode 100644 remote.txt
$ git-log
* 270d59c (HEAD -> dev2) Merge branch 'master' into dev2
|\
| * a8c017f (master, dev1) update on 2021-10-09
| * 3a6eba4 (origin/master) 2021年10月 9日 8:47:28
| * 4975bc2 update
| * ceecd3d hello git cm
| * fc60abe Merge remote-tracking branch 'origin'
| |\
| | * 38c5cfb users
| * | dd7a2ca account
| |/
| * f6f067d add .gitignore.
| * e990479 add remote.txt at gitee
|/
* 620fea2 (origin/main) update on dev2
* fa343b7 comment
Now, do you clear the difference of 'Fast-forward' and 'recursive' strategy ?
List all git aliases
Prints a list of all git aliases.
- Use
git config -l
to list all variables set in the configuration file. - Use the pipe operator (
|
) to pipe the output andgrep alias
to only keep aliases. - Use the pipe operator (
|
) to pipe the output andsed 's/^alias\.//g'
to remove thealias.
part from each alias.
Example
$ git config -l | grep alias | sed 's/^alias\.//g'
Set default push branch name⭐
Use the name of the current branch when pushing by default as the name of the remote branch.
- Use
git config push.default current
to set the name of the remote branch to the one of the current local branch as the default. - You can use the
--global
flag to configure this option globally.
$ git config [--global] push.default current
Example
$ git config --global push.default current
$ git checkout -b my-branch
$ git push -u
Then pushes to origin/my-branch!
Original state:
State changed:
Configure git user information
Configures user information for git.
- Use
git config user.email <email>
to set the user's email for the current repository. - Use
git config user.name <name>
to set the user's name for the current repository. - You can use the
--global
flag to configure global user information.
$ git config [--global] user.email <email>
$ git config [--global] user.name <name>
Example
# Configures user for current repository
$ git config user.email "cool.duck@qua.ck"
$ git config user.name "Duck Quackers"
# Configures global git user
$ git config --global user.email "cool.duck@qua.ck"
$ git config --global user.name "Duck Quackers"
Configure line endings
Configures the line endings for a repository.
- Use
git config core.eol [lf | crlf]
to configure the line endings. lf
is the UNIX line endings (\n
), whereascrlf
is the DOS line ending (\r\n
).
$ git config core.eol [lf | crlf]
Example
# Configured to use UNIX line endings
$ git config core.eol lf
For more information about this knowledge: About CRLF & LF
Autocorrect git commands
Configure git to autocorrect mistyped commands.
- Use
git config --global help.autocorrect 1
to enable git's autocorrect.
$ git config --global help.autocorrect 1
Example
$ git config --global help.autocorrect 1
# Runs `git status` instead
$ git sttaus
Configure the git text editor
Configure the text editor used by git.
- Use
git config --global core.editor <editor-command>
to call<editor-command>
as the git text editor.
$ git config --global core.editor <editor-command>
Example
# Sets 'VS Code' as the git text editor
$ git config --global core.editor "code --wait"
# Sets 'vim' as the git text editor
$ git config --global core.editor "vim"
Edit git configuration file⭐
Open the git configuration file in the git text editor.
$ git config --global -e
Git Commit🏆
Propaedeutics🔥
View commits in a specific date range⭐
Prints all commits in the specified date range.
- Use
git log --since=<date-from> --until=<date-to>
to view a log of all commits between<date-from>
and<date-on>
. - You can use only
--since=<date-from>
to see all commits since a specific date or only--until=<date-on>
to view all commits up to a specific date. - Use arrow keys to navigate, press
Q
to exit.
$ git log [--since=<date-from>] [--until=<date-on>]
Example 1
$ git log --since='Apr 1 2021' --until='Apr 4 2021'
Example 2
$ git log --since='2 weeks ago'
View a short summary of commits without merge commits
Prints a short summary of all commits excluding merge commits.
- Use
git log --oneline --no-merges
to list a short summary of all commits without merge commits.
$ git log --oneline --no-merges
Example
$ git-log
* 06b7d6b (dev1) Merge branch 'dev2' into dev1
|\
| | * d93117e (HEAD -> master) Commit from the past!!!
| | * e460e34 (gitee/master) Commit from the past
| | * 26fb3b1 update on 2021.10.11
| | * 8f6a3f2 add LICENSE.
| |/
| * 270d59c (gitee/dev2, dev2) Merge branch 'master' into dev2
| |\
| |/
|/|
* | a8c017f update on 2021-10-09
...
$ git log --oneline --no-merges
d93117e (HEAD -> master) Commit from the past!!!
e460e34 (gitee/master) Commit from the past
26fb3b1 update on 2021.10.11
8f6a3f2 add LICENSE.
a8c017f update on 2021-10-09
...
Create a commit with a different date
Sometimes, you might run into a situation where you need to create a commit with a different date than the current one. Luckily, you can handle this using GIT_AUTHOR_DATE
and GIT_COMMITTER_DATE
:
$ GIT_AUTHOR_DATE='Mon May 18 19:32:10 2020 -0400' \
GIT_COMMITTER_DATE='Mon May 18 19:32:10 2020 -0400' \
git commit -m 'Commit from the past'
⭐As shown in the example above, you can set both values to any date you like and your code will be committed on that date. Note that the format for the values above is 'date +"%s %z"'
, also referred to as internal raw git format, but you can also use other formats, such as RFC 2822 (Mon, 18 May 2020 19:32:10 -0400
), ISO 8601 (2020-05-18 19:32:10 -0400
), local (Mon May 18 19:32:10 2020
), short (2020-05-18
) or relative (5.seconds.ago
, 2.years.3.months.ago
, 6am yesterday
).
Example
Check the date:
View a short summary of commits
Prints a short summary of all commits.
- Use
git log --oneline
to list a short summary of all commits.
$ git log --oneline
Manually find the commit that introduced a bug⭐
Uses a binary search algorithm to manually find which commit in history introduced a bug.
- Use
git bisect start
to start the process. - Use
git bisect good <commit>
to mark a<commit>
as "good", indicating it is known to be bug-free. - Use
git bisect bad <commit>
to mark a different<commit>
as "bad" indicating it has the bug. - Use
git bisect (bad | good)
marking each subsequent commit as "good" or "bad" depending if it has the bug or not. - Use
git bisect reset
to reset to the original branch. You can optionally specify a<commit>
to reset to.
$ git bisect start
$ git bisect good <commit>
$ git bisect bad <commit>
$ git bisect (bad | good)
$ git bisect reset [<commit>]
Rough Example
$ git bisect start
$ git bisect good 3050fc0de
$ git bisect bad c191f90c7
$ git bisect good # Current commit is good
$ git bisect bad # Current commit is buggy
# ... some time later the bad commit will be printed
$ git bisect reset # Goes to the original branch
Detailed Example🔥
Do you still not understand yet? Don't worry, here shows another detailed example to ensure you catch on it.
git bisect
is a useful command to find which commit introduced an error.
The principle is simple: narrow down the history of code submissions in a dichotomy. The idea of "dichotomy" is to split the commit history into two parts, determine whether the problem is in the first or the second half, and continue this process until it narrows down to a single commit record.
This detailed example explains how to use this command with an example. Here is a codebase, clone it to local.
$ git clone git@github.com:bradleyboy/bisectercise.git
$ cd bisectercise
This repository is a web page - index.html. Open it in your browser.
On the page is a counter with two buttons. When you click the '+' button, you can see that instead of incrementing the counter, it decays, indicating that something is wrong with the code.
Now it's time to find out which code commit actually introduced the error. Firstly, check the code commit history.
$ git log --pretty=oneline
As we can see, this repository has a total of 101 commits. The earliest first submitted hash is 4d83cF
.
git bisect start
starts error checking in the following format:
git bisect start [end-id] [start-id]
In the code above, the "end point" is the most recent commit, and the "start point" is the more recent commit. This history between them is the extent of the error.
In this example, we select the entire code history. The starting point is the first commit 4D83CF
and the end point is the most recent HEAD
. Of course, you can specify other scopes as well.
$ git bisect start HEAD 4d83cf
After executing the command above, the codebase switches to the commit within the range, which in this case is commit 51(half).
Now refresh the browser and click the '+' button to see that it increments normally. Use git bisect good
to indicate that this commit (51st) is ok.
$ git bisect good
Since there is no problem with the 51st commit, it means that the error was introduced later in the code's history. Execute the above command and Git automatically switches to the midpoint of the second half (commit 76).
Now refresh the browser and click the '+' button to see that the increment does not work properly. Use git bisect bad
to signal that there is a problem with this commit (76).
$ git bisect bad
After the above command is executed, Git automatically switches to the midpoint of commit 51 to commit 76 (commit 63).
This process is then repeated until the offending commit is successfully found. Git will give you the following prompt.
b47892 is the first bad commit
Now that you've found the problematic commit, you can examine the code to determine exactly what went wrong.
Then, use git bisect reset
command to exit the error check and return to the latest code commit.
$ git bisect reset
Now you can start fixing the bug.
(Over)
For more info(ruan-yifeng): ruanyifeng.com/blog/2018/1…
Automatically find the commit that introduced a bug⭐
Uses a binary search algorithm and a given script to find which commit in history introduced a bug.
- Use
git bisect start
- Use
git bisect good <commit>
to mark a<commit>
as "good", indicating it is known to be bug-free. - Use
git bisect bad <commit>
to mark a different<commit>
as "bad" indicating it has the bug. - Use
git bisect run <command>
to run the given<command>
on each subsequent commit to find which commit introduce the bug. - Use
git bisect reset
to reset to the original branch. You can optionally specify a<commit>
to reset to.
$ git bisect start
$ git bisect good <commit>
$ git bisect bad <commit>
$ git bisect run <commit>
$ git bisect reset [<commit>]
Rough Example
$ git bisect start
$ git bisect good 3050fc0de
$ git bisect bad c191f90c7
$ git bisect run npm test # Run `npm test` for each commit
# ... some time later the bad commit will be printed
$ git bisect reset # Goes to the original branch
Detailed Example🔥
A linear code commit history is a great help in automating problem location, allowing us to go back from the current problematic commit to the first problematic commit in history.
Even better, we can use a split lookup to find the problematic commit in order () time.
For example, in a codebase, there is a linear commit history between and . We know a test that passes at but fails at . We can checkout , , till , and run the tests after each checkout to find the first commit that fails the test.
However, the method above is extremely inefficient. So, Git provides us with automated test scripts. Here is the demo:
$ git clone git@github.com:jungejason/git-bisect-run-demo.git
cd git-bisect-run-demo
57715@Wu-Yikun MINGW64 /d/Wyk's WorkSpace/git-bisect-run-demo (master)
$ git bisect start
57715@Wu-Yikun MINGW64 /d/Wyk's WorkSpace/git-bisect-run-demo (master|BISECTING)
$ git bisect bad HEAD
57715@Wu-Yikun MINGW64 /d/Wyk's WorkSpace/git-bisect-run-demo (master|BISECTING)
$ git log --grep='C101' --oneline | cat
f1a0469 C101 - change another number
57715@Wu-Yikun MINGW64 /d/Wyk's WorkSpace/git-bisect-run-demo (master|BISECTING)
$ git bisect good f1a0469
Bisecting: 49 revisions left to test after this (roughly 6 steps)
[94d9240b05a108395fb2969fe2a4b6c21fce8e1b] C150 - some change
57715@Wu-Yikun MINGW64 /d/Wyk's WorkSpace/git-bisect-run-demo ((94d9240...)|BISECTING)
$ git bisect run bash test.sh
running bash test.sh
Test Passed
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[8753c8521a465956807e26fe7a3ee79daa5cceb2] C175 - some change
running bash test.sh
Test Passed
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[4e7bafdc9cbab4b2409f7d2d78822200c4578c5b] C187 - some change
running bash test.sh
Test Failed
Bisecting: 5 revisions left to test after this (roughly 3 steps)
[7028c24aea20364fa69af786e31a5e5267c34c36] C181 - some change
running bash test.sh
Test Failed
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[c8e79ede15330e6247cbfe7b212c483483b2433d] C178 - some change
running bash test.sh
Test Passed
Bisecting: 0 revisions left to test after this (roughly 1 step)
[327fc00b43b5041cb2fc626ab8589c607111f164] C180 - some change
running bash test.sh
Test Passed
7028c24aea20364fa69af786e31a5e5267c34c36 is the first bad commit
commit 7028c24aea20364fa69af786e31a5e5267c34c36
Author: Jason Ge <gejun_1978@yahoo.com>
Date: Tue Oct 1 16:50:32 2019 +0800
C181 - some change
Summary: add one line
Test: none
inventory.csv | 1 +
1 file changed, 1 insertion(+)
bisect run success
$ git bisect reset
git bisect run
automatically finds .
7028c24aea20364fa69af786e31a5e5267c34c36 is the first bad commit
commit 7028c24aea20364fa69af786e31a5e5267c34c36
Author: Jason Ge <gejun_1978@yahoo.com>
Date: Tue Oct 1 16:50:32 2019 +0800
C181 - some change
Summary: add one line
Test: none
inventory.csv | 1 +
1 file changed, 1 insertion(+)
bisect run success
For more info: jungejason.github.io/git-bisect-…
Change the last commit's message
Updates the last commit's message without changing its contents.
- Use
git commit --amend -m <message>
to replace the last commit's message with the new<message>
$ git commit --amend -m <message>
# or
$ git commit --amend
⭐At this time, if there are any changes in the staging area, they will be submitted together.
Example
$ git add .
$ git commit -m "Fix the newtork."
$ git commit --amend -m "Fix the network Bug."
Attention: While
View commits by author
Prints all commits by the specified author.
- Use
git log --author=<author>
to retrieve all commits by the specified<author>
. - Use arrow keys to navigate, press
Q
to exit.
$ git log --author=<author>
Example
$ git log --author="wyk"
# commit c191f90c7766ee6d5f24e90b552a6d446f0d02e4
# Author: wyk
# Date: Tue Apr 6 11:11:08 2021 +0300
# [...]
Remove a file from the last commit
Removes a file from the last commit without changing its message.
- Use
git rm —-cached <file>
to remove the specified<file>
from the index. - Use
git commit —-amend
to update the contents of the last commit, without changing its message.
$ git rm --cache <file>
$ git commit --amend
Example
$ git rm --cached "30-seconds.txt"
$ git commit --amend
# Removes `30-seconds.txt` from the last commit
Commit without running git hooks
Creates a new commit skipping the pre-commit and commit-msg hooks.
- Use
git commit --no-verify -m <message>
to commit staged changes without running git hooks.
$ git commit --no-verify -m <message>
Example
# Make some changes to files, ones that your precommit hook might not allow
$ git add .
$ git commit --no-verify -m "Unsafe commit"
# Creates a commit with the message "Unsafe commit", without running git hooks
Edit the last commit
Updates the last commit's contents without changing its message
- Use
git commit --amend --no-edit
to add any staged changes to the last commit, without changing its message.
$ git commit --amend --no-edit
Example
$ git add .
$ git commit -m "Fix the network bug"
# Edit or add files
$ git add .
$ git commit --amend --no-edit
# The last commit includes the edited/added files
Rewind back n commits🔥
Rewinds the current branch by a given number of commits.
- Use
git reset HEAD~<n>
to rewind the current branch<n>
commits. - This command will uncommit and unstage changes, but leave them in the working directory.
- You can use the
--hard
flag to uncommit, unstage and delete changes instead.
$ git reset [--hard] HEAD~<n>
Example
$ git reset HEAD~5
# Rewinds back 5 commits but keeps changes in the working directory
$ git reset --hard HEAD~3
# Rewinds back 3 commits and deletes changes
Origin state :
execute git reset HEAD~4
:
🔥 Tips :
-
HEAD
equals withHEAD~0
-
HEAD^
equals withHEAD~1
-
HEAD^^
equals withHEAD~2
-
HEAD^^^
equals withHEAD~3
-
...
⭐git reset HEAD^
: Keeps the changes !
⭐git reset --hard HEAD^
: Deletes changes !
Rewind back to a specific commit
Rewinds the current branch by a given number of commits.
- Use
git reset <commit>
to rewind the current branch to the specified<commit>
. - This command will uncommit and unstage changes, but leave them in the working directory.
- You can use the
--hard
flag to uncommit, unstage and delete changes instead.
$ git reset [--hard] <commit>
Example
$ git reset 3050fc0d3
# Rewinds back to `3050fc0d3` but keeps changes in the working directory
$ git reset --hard c0d30f305
# Rewinds back to `c0d30f305` and deletes changes
Undo a commit
Undoes a specified commit without rewriting history.
- Use
git revert <commit>
to revert the specified<commit>
, creating a new commit with the inverse of the commit's changes.
$ git revert <commit>
Example
$ git revert 3050fc0d3
# Reverts the commit `3050fc0d3`
Undo the last commit⭐
Undoes the last commit without rewriting history.
- Use
git revert HEAD
to revert the last commit, creating a new commit with the inverse of the commit's changes.
$ git revert HEAD
Example
$ git revert HEAD
# Reverts the last commit
As you can see, revert
is differed from reset
, because revert
retains historical commits(but undoes the staging area and workspace), reset
not.
View last commit
Prints the last commit.
- Use
git log -1
to view the last commit. - Use arrow keys to navigate, press
Q
to exit.
$ git log -1
Example
$ git log -1
Create a fixup commit❓
Creates a fixup commit that can be autosquashed in the next rebase.
- Use
git commit --fixup <commit>
to create a fixup commit for the specified<commit>
. - After running
git rebase --autosquash
, fixup commits will be automatically squashed into the commits they reference.
git commit --fixup <commit>
Example
$ git add .
$ git commit --fixup 3050fc0de
# Created a fixup commit for `3050fc0de`
$ git rebase HEAD~5 --autosquash
# Now the fixup commit has been squashed
Create a commit by a different author
Creates a new commit by the specified author.
- Use
git commit -m <message>
to create a new commit with the specified<message>
. - Use the
--author
option to change the<name>
and<email>
of the commit's author.
$ git commit -m <message> --author='<name> <email>'
Example
# Make some changes to files
$ git add .
$ git commit -m "Fix the network bug" --author="Duck Quackers <cool.duck@qua.ck>"
# Creates a commit by `Duck Quackers`
Add files to the staging area
Adds files to the staging area.
- Use
git add <pathspec>
to add files to the staging area. <pathspec>
can be a filename or a folder.
$ git add <pathspec>
Example
$ git add "update.txt"
# Add the file `update.txt` to the staging area
$ git add src/*.json
# Add all files with a `.json` extension in the `src` directory
$ git add .
# Adds all changes to the staging area
Remove files from the staging area
Removes files from the staging area.
- Use
git restore --staged <pathspec>
to remove files from the staging area. <pathspec>
can be a filename or a folder.
$ git restore --staged <pathspec>
Example
$ git restore --staged "update.txt"
# Remove the file `update.txt` from the staging area
$ git restore --staged src/*.json
# Remove all files with a `.json` extension in the `src` directory
$ git restore --staged .
# Remove all changes from the staging area
⭐This command(git restore --staged
) is distinguished from git rm --cached
:
git restore --staged
: Changes to be committed ==> Changes not staged for commitgit rm --cached
: Changes to be committed ==> Untracked files
🔥 For more info about Undo: juejin.cn/post/702204…
View a summary of changes between two commits
Prints a summary of changes between two given commits.
- Use
git shortlog <commit>..<other-commit>
to view a summary of changes between the two given commits. - Use arrow keys to navigate, press
Q
to exit.
$ git shortlog <commit>..<other-commit>
Example
$ git shortlog 866adb3..HEAD
Discard uncommitted changes⭐
Discards all uncommitted changes to the current branch.
- Use
git reset --hard HEAD
to reset the local directory to match the latest commit and discard all unstaged changes.
$ git reset --hard HEAD
# Discards all unstaged changes!
Pick changes from one or more commits❓
Applies the changes introduced by one or more commits.
- Use
git cherry-pick <commit>
to pick changes from a single commit. - Use
git cherry-pick <commit-1> <commit-2>...
to pick changes from all space-separated commits. - Use
git cherry-pick <first-commit>..<last-commit>
to pick changes from a range of commits.
$ git cherry-pick (<commit>... | <first-commit>..<last-commit>)
Example
$ git cherry-pick 3050fc0de # Picks changes from the commit `3050fc0de`
$ git cherry-pick 3050fc0de c191f90c7
# Picks changes from the commits `3050fc0de`, `c191f90c7` and `0b552a6d4`
$ git cherry-pick 3050fc0de..c191f90c7
# Picks changes from the commits in the range `3050fc0de` - `c191f90c7`
📚For more info:
Add a commit message template
Sets up a commit message template for the current repository.
- Use
git config commit.template <file>
to specify<file>
as the commit message template for the current repository.
$ git config commit.template <file>
Example
# Sets message of template.txt as the commit message template
$ git config commit.template template.txt
template.txt:
config and then commit:
commit.template
just provide a template-message to reduce the time it takes to edit your submissions, you need to edit the template-message anyhow.
Once you did not edit the message: Aborting commit !
How does Git's fast-forward mode work?📕
Merging a branch is one of the most common operations when working with Git. Depending on your team and projects you've been a part of, you might have heard of or even used Git's fast-forward mode when merging. Fast-forward mode is the default in Git, however GitHub will essentially override this by default and create a merge commit instead.
Fast-forward merge
As stated above, Git's default is to use fast-forward merge. It will take the commits from the branch being merged and place them at the tip of the branch you're merging into. This creates a linear history, which is also the main advantage of using fast-forward merge. If you want to emulate fast-forward merge on GitHub, you can use the "Rebase and merge" option.
Non fast-forward merge
GitHub, on the other hand, uses non fast-forward merge by default. It will create a merge commit at the tip of the branch you're merging into, optionally referencing the branch being merged in the commit message. This has the advantage of keeping track of branches more explicitly than fast-forward merge. If you want to get the same behavior in a Git terminal, you can use the --no-ff
flag.
As a side note, you can configure the default Git merge behavior, using git config
. To learn how to do so, you can take a look at the relevant snippet.
Merge a branch and create a merge commit⭐
Merges a branch into the current branch, creating a merge commit.
- Use
git checkout <target-branch>
to switch to the branch into which you want to merge. - Use
git merge --no-ff -m <message> <source-branch>
to merge a branch into the current branch, creating a merge commit with the specified<message>
.
$ git checkout <target-branch>
$ git merge --no-ff -m <message> <source-branch>
--no-ff
means Not Fast-forward !
🔥 You can also configure it globally (not recommended), see article: juejin.cn/post/701722…
Git Repository🏭
View differences in changes⭐
Displays differences between staged or unstaged changes and the last commit.
- Use
git diff
to view differences between your unstaged changes and the last commit. - You can use the
--staged
option to view differences between your staged changes and the last commit instead.
$ git diff [--staged]
Example
$ git diff
# Displays the differences between unstaged changes and the last commit
$ git diff --staged
# Displays the differences between staged changes and the last commit
- Distinction
- ⭐unstaged changes: before execute
git add .
, like this picture: - ⭐staged changes: after execute
git add .
, but beforegit commit -m
!
- ⭐unstaged changes: before execute
🔥Here shows the operation:
① before git add
② after git add
& before git commit
③ show the diff after git commit
View a visual graph of the repository
Prints a visual graph of all commits and branches in the repository.
- Use
git log --pretty=oneline --graph --decorate --all
to view a visual graph of the whole repository's history. - Use arrow keys to navigate, press Q to exit.
$ git log --pretty=oneline --graph --decorate --all
Find lost files❓
Prints a list of lost files and commits.
- Use
git fsck --lost-found
to print a list of all dangling objects. - All appropriate files will be extracted into the
.git/lost-found
directory.
Move commits from master to a new branch
Moves local commits from the master
branch to a new branch.
- Use
git branch <branch>
to create a new branch at the tip of the currentmaster
. - Use
git reset HEAD~<n> --hard
to rewind back<n>
commits and discard changes. - Use
git checkout <branch>
to switch to the new branch. - Only works if the changes have only been committed locally and not pushed to the remote.
$ git branch <branch>
$ git reset HEAD~<n> --hard
$ git checkout <branch>
Example
$ git checkout master
$ git add .
$ git commit -m "Fix network bug"
$ git branch patch-1
# `patch-1` branch is created containing the commit "Fix network bug"
$ git reset HEAD~1 --hard # Remove the commit from `master`
$ git checkout patch-1
For more detailed information: juejin.cn/post/702204…
Reset master to match remote
Resets the local master
branch to match the one on the remote.
- Use
git fetch origin
to retrieve the latest updates from the remote. - Use
git checkout master
to switch to themaster
branch. - Use
git reset --hard origin/master
to reset the localmaster
branch to match the one on the remote.
$ git fetch origin
$ git checkout master
$ git reset --hard origin/master # Local `master` branch is now up to date with remote `master`
View "undo" history⭐
View git's reference logs. This is especially useful for finding references that don't show up in commit history.
- Use
git reflog
to display the git reference log. - View your "undo" history
Because sometimes git log doesn't cut it, especially for commands that don't show up in your commit history.
❗ reflog
is basically your safety net after running "scary" commands like git rebase. You'll be able to see not only the commits you made, but each of the actions that led you there.
$ git reflog
vs git-log
:
Clone a repository
Clones an existing repository, creating a local copy of it.
- Use
git clone <url>
to clone an existing repository from<url>
to a local directory. The directory's name will be based on the name of the cloned repository. - Alternatively, use
git clone <url> [<directory>]
to clone the repository into the specified local<directory>
.
$ git clone <url> [<directory>]
Example
$ git clone https://github.com/hello/Hello-World.git
# Clones the repository in a new directory named 'Hello-World'
$ cd Hello-World
$ git clone https://github.com/hello/Hello-World.git my-project
# Clones the repository in a new directory named 'my-project'
$ cd my-project
Change the remote URL⭐
Changes the URL of the remote repository.
- Use
git remote set-url origin <url>
to change the URL of the remote repository to<url>
.
$ git remote set-url origin <url>
Example
$ git remote set-url gitee git@gitee.com:Wu-Yikun/git.git
Git Branch💢
Find branches containing a commit⭐
Prints all the branches containing a specific commit.
- Use
git branch --contains <commit>
to see a list of all branches containing<commit>
.
$ git branch --contains <commit>
Example
# master
$ git branch --contains 8f6a3f2
# dev1、dev2、master
$ git branch --contains 270d59c
Find branches not containing a commit
Prints all the branches not containing a specific commit.
- Use
git branch --no-contains <commit>
to see a list of all branches not containing<commit>
$ git branch --no-contains <commit>
Example
# dev1、dev2
$ git branch --no-contains d93117e
Delete a remote branch
Deletes a remote branch.
- Use
git push -d <remote> <branch>
to delete the specified remote<branch>
on the given<remote>
.
$ git push -d <remote> <branch>
Example
$ git checkout master
$ git push -d gitee patch-1
Later:
Merge a branch
Merges a branch into the current branch.
- Use
git checkout <target-branch>
to switch to the branch into which you want to merge. - Use
git merge <source-branch>
to merge a branch into the current branch.
$ git checkout <target-branch>
$ git merge <source-branch>
Example
$ git checkout master
$ git merge patch-1 # Merges the `patch-1` branch into `master`!
View branches sorted by date
Prints a list of all local branches sorted by date.
- Use
git branch --sort=-committerdate
to display a list of all local branches and sort them based on the date of their last commit. - Use arrow keys to navigate, press Q to exit.
$ git branch --sort=-committerdate
Example
$ git branch --sort=-committerdate
* master
dev1
dev2
View merged branches
Prints a list of all merged local branches.
- Use
git branch -a --merged
to display a list of all merged local branches. - Use arrow keys to navigate, press
Q
to exit.
$ git branch -a --merged
All branches:
Merged branches:
Unmerged branches:
Delete merged branches
Deletes all local merged branches.
- Use
git branch --merged <branch>
to list all branches merged into<branch>
. - Use the pipe operator (
|
) to pipe the output andgrep -v "(^\*|<branch>)"
to exclude the current and the target<branch>
. - Use the pipe operator (
|
) to pipe the output andxargs git branch -d
to delete all of the found branches.
$ git branch --merged <branch> | grep -v "(^\*|<branch>)" | xargs git branch -d
Example
$ git checkout master
$ git branch
# master
# patch-1
# patch-2
# Assuming `patch-1` is merged into master
$ git branch --merged master | grep -v "(^\*|master)" | xargs git branch -d
$ git branch
# master
# patch-2
Delete detached branches❗
Deletes all detached branches.
⭐Detached branches: No branches are associated and only point to a COMMIT!
- Use
git fetch --all --prune
to garbage collect any detached branches. - This is especially useful if the remote repository is set to automatically delete merged branches.
$ git fetch --all --prune
Example
$ git checkout master
$ git branch
dev1
dev2
* master
patch-1
# Assuming `patch-1` is detached
$ git fetch --all --prune
$ git branch
dev2
* master
patch-1
Copy a file from another branch
Copies a file from another branch to the current branch.
- Use
git checkout <branch> <file>
to copy the specified<file>
from the specified<branch>
.
$ git checkout <branch> <file>
Example
$ git checkout patch-2
$ git checkout patch-1 "patch-1.txt"
# `patch-2` branch now contains the patch-1.txt file from `patch-1`
Rename a branch
Renames a local branch.
- Use
git branch -m <old-name> <new-name>
to rename<old-name>
to<new-name>
.
$ git branch -m <old-name> <new-name>
Example
$ git checkout master
$ git branch -m patch-1 patch-2
View current status
Prints the current status of the working tree.
- Use
git status
to view the current status of the working tree. - You can optionally add the
-sb
flag to view the short form of the same output
$ git status [-sb]
Example
$ git status
On branch master
Your branch is behind 'gitee/master' by 10 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Today's Content.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
fixup-commit.txt
patch-1.txt
update - 副本.txt
update.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git status -sb
## master...gitee/master [behind 10]
M "Today's Content.txt"
?? fixup-commit.txt
?? patch-1.txt
?? "update - 副本.txt"
?? update.txt
⭐git status -sb
is more concise than git status
!
Return to previous branch
Switches back to the last branch.
- Use
git checkout -
to switch back to the previous branch.
$ git checkout -
Example
$ git checkout patch-1
$ git checkout master
$ git checkout - # Switches to `patch-1`
Rebase onto another branch❓
Rebases the current branch onto another branch.
- Use
git checkout <branch>
to switch to the<branch>
to be rebased. - Use
git rebase <base-branch>
to rebase the current branch onto<base-branch>
.
$ git checkout <branch>
$ git rebase <base-branch>
Example
$ git checkout patch-1
$ git rebase master
# `patch-1` is rebased onto `master`
$ git checkout patch-2
$ git fetch origin # Fetch latest remote branches
$ git rebase origin/master
# `patch-2` is rebased onto the latest remote `master`
📚Basic information about git rebase
:www.yiibai.com/git/git_reb…
Discard untracked changes
Discards all untracked changes to the current branch.
- Use
git clean -f -d
to discard all untracked changes to the current branch.
$ git clean -f -d
Example
$ git clean -f -d
View difference between two branches⭐
Displays the difference between two branches.
- Use
git diff <branch>..<other-branch>
to view the difference between<branch>
and<other-branch>
.
$ git diff <branch>..<other-branch>
Example
$ git diff patch-1..patch-2
# Displays the difference between branches `patch-1` and `patch-2`
Rename remote branch⭐
Renames a branch both locally and on the remote.
- Use
git branch -m <old-name> <new-name>
to rename the local<old-name>
branch to<new-name>
. - Use
git push origin --delete <old-name>
to delete the old remote branch. - Use
git checkout <new-name>
to switch to the renamed branch. - Use
git push origin -u <new-name>
to set<new-name>
as the remote branch for the renamed branch.
$ git branch -m <old-name> <new-name>
$ git push origin --delete <old-name>
$ git checkout <new-name>
$ git push origin -u <new-name>
Example
$ git checkout master
$ git branch -m patch-1 patch-2 # Renamed the local branch to `patch-2`
$ git push origin --delete patch-1 # Remove remote branch `patch-1`
$ git checkout patch-2
$ git push origin -u patch-2 # Renames(Create) the remote branch `patch-2`
(Over)
🧠Wish you can benefit from this article.
🔥 And welcome to leave your thoughts in the comments section that we can discuss and share ideas with each other.