Essential Git Commands
A quick summary of the commands you use most often in Git, the version control system (VCS).
# Config
Config is Git's environment settings at the operating system level.
The newline configuration prevents line ending compatibility problems between Windows and Unix-like operating systems (macOS).
The name and email are used to show author information when you create a version. They can differ from your user information on services such as GitHub, but it is better to keep them the same if you can.
| Command | Description |
|---|---|
git -v |
Check the Git version |
git config --global core.autocrlf input |
Set newline characters (macOS) |
git config --global core.autocrlf true |
Set newline characters (Windows) |
git config --global user.name '<name>' |
Set the user name |
git config --global user.email '<email>' |
Set the user email |
git config --global init.defaultBranch main |
For Git versions below v2.28, set the main branch name to main |
git config --global pull.rebase true |
Make rebase the default behavior when you run the pull command (optional) |
git config --global --list |
Check the list of configurations |
git config --global --unset <key> |
Delete a configuration item |
git config --global --unset-all <key> |
Delete duplicate configuration items |
1vim ~/.gitconfig
# Init
Init starts Git version control for a project.
A remote alias is a name that refers to a remote repository. If you have a single remote, we recommend using origin.
| Command | Description | Example |
|---|---|---|
git init |
Start version control for the project | |
git remote |
Check the list of remote repositories | |
git remote -v |
Check the URLs of remote repositories | |
git remote add <remote-alias> <URL> |
Add a remote repository | git remote add origin https://github.com/ParkYoungWoong/heropy.git |
git clone <URL> |
Clone a remote repository | git clone https://github.com/ParkYoungWoong/heropy.git |
rm -rf .git |
Reset version control (macOS) | |
rd /s /q .git |
Reset version control (Windows CMD) | |
Remove-Item -Recurse -Force .git |
Reset version control (Windows PowerShell) |
# Track
Tracking means specifying the targets (files) whose versions you manage.
Staging means preparing tracked files to create a version.
| Command | Description | Example |
|---|---|---|
git status |
Check the changes in the current branch | |
git add <file> |
Track and stage a specific file | git add ./src/main.js |
git add . |
Track and stage all files | |
git mv <fileA> <fileB> |
Rename a staged file | git mv ./mnin.js ./main.js |
git rm -r --cached <file> |
Remove from the tracking list (after updating .gitignore) |
git rm -r --cached ./src |
git clean -fdn |
List the untracked files that can be deleted | |
git clean -fd |
Delete untracked files | |
git restore --staged <file> |
Unstage a specific file (v2.23) | git restore --staged ./src/main.js |
git restore --staged . |
Unstage all files (v2.23) |
# Commit
A commit records (creates) the current work as a single version.
| Command | Description |
|---|---|
git commit -m '<message>' |
Create a version (you can add line breaks to the message before closing the quote) |
git commit -am '<message>' |
Stage tracked files and create a version |
git commit > i > enter the message > esc > :wq |
Write the message in the Vim editor and create a version |
git commit --amend |
Overwrite the previous commit with the current commit, Empty Commit (requires a force (-f) push afterward) |
git commit --amend -m '<message>' |
Edit the previous commit message (requires a force (-f) push afterward) |
git add <missing-file>git commit --amend --no-edit |
Add the currently staged changes to the previous commit and keep the message (requires a force (-f) push afterward) |
# Log
Log means checking the versions you created and their history, changes, authors, and so on.
| Command | Description | Example |
|---|---|---|
git log |
Check the version history of the current branch | |
git log -<number> |
Check only the given number of latest versions | git log -2 |
git log --all |
Check the history of all branches | |
git log --oneline |
Check a condensed version history | |
git log --graph |
Check the version history as a graph | |
git reflog |
Check the entire local version control history | |
git show |
Check the latest version of the current branch | |
git show <branch> |
Check the latest version of a specific branch | git show dev |
git show <hash> |
Check a specific version | git show 1a2b3c4d |
git blame <file> |
Check who worked on a specific file | git blame ./src/main.js |
git blame -L <start>,<end> <file> |
Check who worked on a specific file from the start line to the end line | git blame -L 10,20 ./src/main.js |
git blame -L <start> <file> |
Check who worked on a specific file from the start line to the last line | git blame -L 10 ./src/main.js |
git blame -L ,<end> <file> |
Check who worked on a specific file from the first line to the end line | git blame -L ,20 ./src/main.js |
git branch --show-current |
Check the current branch name (v2.22) |
# Branch
A branch is a point where version control diverges, so that you can split work in a project and do it in parallel.
| Command | Description | Example |
|---|---|---|
git branch |
Check the list of local branches | |
git branch -r |
Check the list of remote branches | |
git branch -a |
Check the list of local and remote branches | |
git branch -vv |
Check the upstream (remote branch) linked to each local branch | |
git branch <branch> |
Create a branch | git branch dev |
git branch -D <branch> |
Delete a branch | git branch -D dev |
git branch -d <branch> |
Delete a branch that has been merged (safe delete) | git branch -d dev |
git branch -m <branch> |
Rename the current branch | git branch -m main |
git branch -m <old-branch> <new-branch> |
Rename a specific branch | git branch -m master main |
git branch --show-current |
Check the current branch name (v2.22) | |
git checkout <branch> |
Switch branches | git checkout dev |
git checkout -b <branch> |
Create a branch and switch to it | git checkout -b dev |
git checkout <hash> |
Check out a specific version | git checkout 1a2b3c4d |
git switch <branch> |
Switch branches (v2.23) | git switch dev |
git switch -c <branch> |
Create a branch and switch to it (v2.23) | git switch -c dev |
# Push
Push uploads the version history of the local repository to a remote repository.
The force flag (--force, -f) ignores conflicts and overwrites the remote repository, so use it only when you are sure.
| Command | Description | Example |
|---|---|---|
git push <remote-alias> <branch> |
Push to a remote repository | git push origin dev |
git push <remote-alias> --all |
Push all branches to a remote repository | git push origin --all |
git push <remote-alias> <branch> -f |
Force push to a remote repository | git push origin dev -f |
git push <remote-alias> <branch> -u |
Push to a remote repository, and you can omit the arguments afterward | git push origin dev -u, then git push |
# Pull
Pull downloads the version history of a remote repository to the local repository.
| Command | Description | Example |
|---|---|---|
git pull <remote-alias> <branch> |
Pull a branch from a remote repository | git pull origin dev |
git pull --rebase <remote-alias> <branch> |
Overwrite the local branch with the branch from the remote repository | git pull --rebase origin dev |
# Fetch
Fetch syncs the latest history of a remote repository with the local copy of the remote history, and it does not affect local branches.
| Command | Description | Example |
|---|---|---|
git fetch |
Fetch the branch list of the current remote repository | |
git fetch <remote-alias> |
Fetch the branch list of a specific remote repository | git fetch origin |
git fetch --all |
Fetch the branch lists of all remote repositories | |
git fetch --prune |
Fetch the branch list from the remote repository and overwrite the local list of remote branches |
# Diff
Diff compares two versions, files, and so on to show the differences.
| Command | Description | Example |
|---|---|---|
git diff <file> |
Check the changes in a file | |
git diff <fileA> <fileB> |
Compare files A and B | |
git diff <branch> |
Compare a specific branch with the current branch | git diff dev |
git diff <branchA> <branchB> |
Compare branches A and B | git diff main dev |
git diff <branchA>:<file> <branchB>:<file> |
Compare a file in branches A and B | git diff main:src/main.js dev:src/main.js |
git diff <hash> |
Compare the current version with a specific version | git diff 1a2b3c4d |
git diff <hashA> <hashB> |
Compare versions A and B | git diff 1a2b3c4d 5e6f7g8h |
# Rollback
Rollback means canceling and throwing away all the changes you are currently working on.
| Command | Description | Example |
|---|---|---|
git checkout HEAD -- <file> |
Roll back a specific file | git checkout HEAD -- ./src/main.js |
git restore <file> |
Roll back a specific file (v2.23) | git restore ./src/main.js |
git restore . |
Roll back all files (v2.23) | |
git reset --hard HEAD |
Roll back all files |
# Reset
Reset moves to a specific version and removes the version history after it.
| Command | Description | Example |
|---|---|---|
git reset --hard HEAD~<number> |
Reset to the given number of versions back | git reset --hard HEAD~2 |
git reset --hard HEAD~1 |
Reset to the previous version (1 version back) |
|
git reset --hard HEAD~ |
Reset to the previous version (1 omitted) |
|
git reset --hard <hash> |
Reset to a specific version | git reset --hard 1a2b3c4d |
git reset --hard HEAD^ |
Delete the last version | |
git reset --hard |
Discard changes | |
git reset --soft |
Stage changes | |
git reset --mixed |
Do not stage changes |
# Revert
Revert cancels a specific version and creates a new version that cancels it.
| Command | Description | Example |
|---|---|---|
git revert <hash> |
Cancel a specific version and create a new version | git revert 1a2b3c4d |
# Stash
Stash saves the changes you are working on separately, without creating a version.
| Command | Description | Example |
|---|---|---|
git stash list |
Check the list of stashed work | |
git stash |
Stash the current work | |
git stash -a |
Stash, including untracked files | |
git stash -m '<message>' |
Stash the current work with a message | |
git stash -am '<message>' |
Stash the current work with a message, including untracked files | |
git stash show <number> |
Show the stash with a specific number | git stash show 2 |
git stash apply |
Apply the most recent stash to the current branch | |
git stash apply <number> |
Apply the stash with a specific number to the current branch | git stash apply 2 |
git stash drop |
Delete the most recent stash | |
git stash drop <number> |
Delete the stash with a specific number | git stash drop 2 |
git stash pop |
Apply the most recent stash and delete it from the list | |
git stash clear |
Delete all stashes |
# Merge
Merge combines two branches into one.
| Command | Description | Example |
|---|---|---|
git merge <branch> |
Merge a specific branch into the current branch | git merge dev |
git merge --abort |
Abort the merge when there is a conflict |
If the two branches have different content and a conflict occurs during the merge, you have to resolve the conflict and commit again.
'Current Change' means the work in the current branch (main), and 'Incoming Change' means the work in the branch being merged (dev).
After resolving the conflict, stage the modified files (git add) and create the merge version (git commit).
12345<<<<<< HEAD (Current Change) main / abc ======= dev / xyz >>>>>> dev (Incoming Change)
# Rebase
Rebase places (moves) the history of the current branch after the latest version of the target branch.
123(main)-- A - B - C \ (dev)----- D - E
1(main)-- A - B - C - D - E
| Command | Description | Example |
|---|---|---|
git rebase <branch> |
Rebase the current branch onto the target branch | git rebase main |
git rebase --continue |
Continue the rebase | |
git rebase --abort |
Abort the rebase |
Here is how to rebase the dev branch onto the main branch.
git checkout dev: Switch to the branch you want to rebase.git rebase main: Start rebasing the current branch (dev) onto the target branch (main).- If a conflict occurs, resolve it.
git add .: Stage after resolving the conflict.git rebase --continue: Continue the rebase.- Edit the version message and save (
:wq). - Repeat steps 3-6, and the rebase is complete!
# Cherry-pick
Cherry-pick selectively applies specific versions (commits) from another branch to the current branch.
It is useful when you want to bring in only the versions you need, without merging the whole branch.
| Command | Description | Example |
|---|---|---|
git cherry-pick <hash> |
Apply a specific version to the current branch | git cherry-pick 1a2b3c4d |
git cherry-pick <hashA> <hashB> |
Apply several versions to the current branch | git cherry-pick 1a2b3c4d 5e6f7g8h |
git cherry-pick <hashA>..<hashB> |
Apply the versions after A up to B (A not included) | git cherry-pick 1a2b3c4d..5e6f7g8h |
git cherry-pick --no-commit <hash> |
Apply only the changes, without committing | git cherry-pick --no-commit 1a2b3c4d |
git cherry-pick --continue |
Continue the cherry-pick after resolving conflicts | |
git cherry-pick --abort |
Abort the cherry-pick |
# Alias
An alias lets you register a frequently used Git command under a short name.
| Command | Description | Example |
|---|---|---|
git config --global alias.<alias> '<command>' |
Register an alias | git config --global alias.co 'checkout' |
git config --global --unset alias.<alias> |
Delete an alias | git config --global --unset alias.co |
git config --global --get-regexp alias |
Check the list of registered aliases |
12345git config --global alias.co 'checkout' git config --global alias.br 'branch' git config --global alias.ci 'commit' git config --global alias.st 'status' git config --global alias.lg 'log --oneline --graph --all'
12345git co dev # git checkout dev git br -a # git branch -a git ci -m 'message' # git commit -m 'message' git st # git status git lg # git log --oneline --graph --all
# Tag
A tag marks a specific version with a name, and it is mainly used to manage release versions.
A lightweight tag just attaches a name, while an annotated tag also records information such as the author, date, and message.
| Command | Description | Example |
|---|---|---|
git tag |
Check the list of tags | |
git tag -l '<pattern>' |
Check the list of tags that match a pattern | git tag -l 'v1.*' |
git tag <tag> |
Create a lightweight tag | git tag v1.0.0 |
git tag -a <tag> -m '<message>' |
Create an annotated tag | git tag -a v1.0.0 -m 'First release' |
git tag <tag> <hash> |
Create a tag on a specific version | git tag v1.0.0 1a2b3c4d |
git tag -d <tag> |
Delete a tag | git tag -d v1.0.0 |
git show <tag> |
Check tag information | git show v1.0.0 |
git push <remote-alias> <tag> |
Push a specific tag to the remote | git push origin v1.0.0 |
git push <remote-alias> --tags |
Push all tags to the remote | git push origin --tags |
git push <remote-alias> --delete <tag> |
Delete a remote tag | git push origin --delete v1.0.0 |
git checkout <tag> |
Check out a specific tag | git checkout v1.0.0 |
A lightweight tag is a pointer that simply points to a specific version, and only a name is created, without any extra information.
12345git tag v1.0.0 git show v1.0.0 # commit 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t # Author: Heropy <thesecon@gmail.com> # Date: Mon Apr 22 09:00:00 2024 +0900
An annotated tag includes meta information such as the author, date, and message in the tag itself, and annotated tags are recommended for release tags.
1234567891011git tag -a v1.0.0 -m 'First release' git show v1.0.0 # tag v1.0.0 # Tagger: Heropy <thesecon@gmail.com> # Date: Mon Apr 22 09:00:00 2024 +0900 # # First release # # commit 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t # Author: Heropy <thesecon@gmail.com> # Date: Mon Apr 22 09:00:00 2024 +0900
# Submodule
A submodule lets you include and manage another Git repository as a subdirectory inside a Git repository.
It is useful when you want to reference a shared library or an external project while keeping its version control independent.
| Command | Description | Example |
|---|---|---|
git submodule add <URL> |
Add a submodule | git submodule add https://github.com/user/lib.git |
git submodule add <URL> <path> |
Add a submodule at a specific path | git submodule add https://github.com/user/lib.git ./libs/lib |
git submodule init |
Initialize submodules (register the .gitmodules information in the local config) |
|
git submodule update |
Update submodules to the registered versions | |
git submodule update --init |
Initialize and update in one step | |
git submodule update --init --recursive |
Initialize and update, including nested submodules | |
git submodule update --remote |
Update submodules to the latest remote versions | |
git submodule status |
Check the status of submodules | |
git submodule foreach '<command>' |
Run a command in every submodule | git submodule foreach 'git pull origin main' |
git clone --recurse-submodules <URL> |
Clone a repository including its submodules | git clone --recurse-submodules https://github.com/user/project.git |
git submodule deinit <path> |
Unregister a submodule | git submodule deinit ./libs/lib |
git rm <path> |
Remove a submodule (after unregistering it) | git rm ./libs/lib |
When you first clone a repository that includes submodules, the submodule directories are empty.
You need to get the submodule contents with the git submodule update --init --recursive command.
123git clone https://github.com/ParkYoungWoong/hello-submodule.git cd hello-submodule git submodule update --init --recursive
To remove a submodule completely, unregister it and delete its files in order.
1234git submodule deinit ./hello-submodule git rm ./hello-submodule rm -rf .git/modules/hello-submodule git commit -m "Remove submodule"
# Worktree
A worktree lets you check out several branches of one Git repository at the same time in separate directories and work on them.
A normal branch switch such as git switch changes the branch within one directory.
So if you want to change branches while you have changes in progress, you have to stash them or create a version (commit).
The files you opened in your IDE, the build cache, and the development server state are all reset as well.
With worktrees, each branch lives in its own independent directory.
So you can start working in another branch right away without stopping your current work.
| Command | Description | Example |
|---|---|---|
git worktree add <path> |
Create a new branch named after the path and add a worktree | git worktree add ./.worktrees/hotfix/signup-error |
git worktree add <path> -b <branch> |
Create a new branch with a different name and add a worktree | git worktree add ./.worktrees/hotfix/signup-error -b hotfix/new-branch-name |
git worktree add <path> <branch> |
Add a worktree with an existing branch | git worktree add ./.worktrees/hotfix hotfix/existing-branch-name |
git worktree list |
Check the list of all worktrees | |
git worktree remove <path> |
Remove a worktree | git worktree remove ./.worktrees/hotfix/signup-error |
git worktree prune |
Clean up worktree information for deleted directories | |
git worktree move <path> <new-path> |
Move a worktree to another location | git worktree move ./.worktrees/feature ./.worktrees/new-feature |
If you need an urgent bug fix while developing on the main branch, you can use a worktree as follows.
The files in the project root do not change, so you can handle the urgent work while keeping your IDE state and development server.
123456789101112131415# While working on the main branch, create a worktree for an urgent bug fix git worktree add ./.worktrees/hotfix/signup-error # Move to the worktree directory, make the fix, and create a version cd ./.worktrees/hotfix/signup-error git add . git commit -m "Fix sign-up bug" # Move back to the main branch directory and merge cd ../../.. git merge hotfix/signup-error # Delete the worktree and the branch git worktree remove ./.worktrees/hotfix/signup-error git branch -d hotfix/signup-error
Thanks for reading to the end.
Likes and kind comments help keep this blog going!