It is recommended to install Relivator following the detailed instructions in the README.md to feel more confident as you begin learning Git.
It's trueβGit can be complex at first. Consider using resources like this guide, the Git Book, and GitHub Skills to deepen your understanding. The command git commit --help will direct you to information about the git commit
command and its options, so this help command can be beneficial as well. The best way to get comfortable with Git is to use it regularly. Create a small project or use a large web project template like Relivator and experiment with different commands. If you're ever unsure about something related to Git, refer to this detailed guide to learn more.
By following the details in this guide, you will get a solid start with Git, set up your environment, and use some handy aliases to streamline your workflow. Happy gitting!
Ensure you have Git installed. It's also recommended to install: Node.js LTS (Windows/macOS | Linux). Then, run corepack enable pnpm to install pnpm. Additionally, we recommend installing VSCode and GitHub Desktop (Windows/macOS | Linux). If you're a Windows user, also install PowerShell 7.4+.
Before you start creating any commits in Git, you need to set your identity. This is important because your name and email will be added to every commit you make. Since this information is public, use something appropriate.
git config --global user.name "<YOUR_NAME>"
git config --global user.email "<YOUR_EMAIL_ADDRESS>"
To see all your Git settings and ensure they are correct, run:
git config --global --list
Writing good commits is a valuable skill. To learn how to write effective commit messages, refer to the following resources:
- Enhance Your Git Log with Conventional Commits
- Karma Commit Messages
- Semantic Commit Messages
- A Note About Git Commit Messages
- Writing Git Commit Messages
Git aliases are shortcuts for longer commands. They can save you a lot of typing and make your workflow more efficient.
This alias updates your local repository by pulling the latest changes, rebasing, and updating submodules.
# git down
git config --global alias.down '!git pull --rebase --autostash; git submodule update --init --recursive'
This alias pushes your changes to the remote repository, including tags.
# git up
git config --global alias.up '!git push; git push --tags'
Sometimes you stage files by mistake. This alias helps you unstage them.
# git unstage <FILES>
git config --global alias.unstage 'reset HEAD --'
Semantic Versioning is a way to tag your releases with meaningful version numbers. These aliases help automate the process.
# git release-major
git config --global alias.release-major '!latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; set -- $(echo $latest | sed -e s/v// -e "s/\./ /g"); major=$1; minor=$2; patch=$3; major=$((major+1)); minor=0; patch=0; next=v$major.$minor.$patch; git tag -a $next -m ""; echo "Previous release:"; echo -n " "; echo $latest; echo "New release:"; echo -n " "; echo $next'
# git release-minor
git config --global alias.release-minor '!latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; set -- $(echo $latest | sed -e s/v// -e "s/\./ /g"); major=$1; minor=$2; patch=$3; minor=$((minor+1)); patch=0; next=v$major.$minor.$patch; git tag -a $next -m ""; echo "Previous release:"; echo -n " "; echo $latest; echo "New release:"; echo -n " "; echo $next'
# git release-patch
git config --global alias.release-patch '!latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; set -- $(echo $latest | sed -e s/v// -e "s/\./ /g"); major=$1; minor=$2; patch=$3; patch=$((patch+1)); next=v$major.$minor.$patch; git tag -a $next -m ""; echo "Previous release:"; echo -n " "; echo $latest; echo "New release:"; echo -n " "; echo $next'
You can avoid typing git git
by setting up an alias:
# git git status, git git commit, etc.
git config --global alias.git '!cd "$GIT_PREFIX" && git'
To see the changelog from the latest tag to your current commit, use this alias:
# git changelog
git config --global alias.changelog '!git log $(git describe --abbrev=0 --tags)..HEAD --no-merges --pretty=oneline --abbrev-commit'
Find common leftover markers like TODOs or debug prints in your code:
# git leftover
git config --global alias.leftover '!git grep -P -i -I --untracked "((?<![a-zA-Z0-9])(TODO|FIXME|XXX|console\.log|System\.out|var_dump)(?![a-zA-Z0-9]))|([\t ]+$)"'
You can set your favorite text editor to use with Git for writing commit messages, etc. For example, if you prefer gedit
on Ubuntu:
git config --global core.editor "gedit --wait"
Windows and Unix-based systems (like Linux and macOS) handle line endings differently. To avoid issues, configure Git to automatically handle this for you. This will convert line endings to the native Windows format (CRLF) on checkout and back to Unix format (LF) when you push changes.
git config --global core.autocrlf true
When you clone repositories over HTTPS, you need to enter a username and password each time, unlike SSH keys. To make Git remember your passwords and make your life easier, use the following commands based on your operating system:
# On Windows
git config --global credential.helper wincred
# On Ubuntu
sudo apt-get install libgnome-keyring-dev
cd /usr/share/doc/git/contrib/credential/gnome-keyring
sudo make
git config --global credential.helper /usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring
# On macOS
git config --global credential.helper osxkeychain
-
Add the original repository as a remote (do this only once):
git remote add upstream <GIT_URL_OF_ORIGINAL_REPOSITORY>
-
Get updates from the original repository and push them to your fork:
git pull upstream <BRANCH_NAME> git push origin
-
Add the original repository as a remote (do this only once):
git remote add upstream <GIT_URL_OF_ORIGINAL_REPOSITORY>
-
Reset your repository's state:
git remote update git reset --hard upstream/<BRANCH_NAME> git push origin +<BRANCH_NAME>
To list all ignored files:
git clean -ndX
# or
git status --ignored
To see all remote repositories associated with your local repository:
git remote -v
When you've added a file to .gitignore
that was previously in the repository, remove it from the repository:
git rm -r --cached .
git add .
To change the remote URL:
git remote set-url <REMOTE_NAME> <NEW_REMOTE_URL>
To discard all unstaged changes:
git checkout -- .
To discard changes for a specific file or path:
git checkout -- "<PATH_TO_DISCARD_CHANGES_FOR>"
Safe method:
git checkout HEAD~1 .
git commit -m "Undo some commit"
git push <REMOTE_NAME> <BRANCH_NAME>
Dangerous method:
git reset --hard HEAD~1
git push -f <REMOTE_NAME> <BRANCH_NAME>
To keep the changes in your working copy:
git reset --soft HEAD~1
To discard the changes altogether:
git reset --hard HEAD~1
To show unstaged changes only:
git diff
To show staged changes only:
git diff --staged
To show both unstaged and staged changes:
git diff HEAD
To delete a branch locally:
git branch -d <BRANCH_NAME>
To delete a branch on the remote:
git push <REMOTE_NAME> :<BRANCH_NAME>
To add a commit message with both a title and a description:
git commit -m "<TITLE>" -m "<DESCRIPTION>"
To preview what will be deleted:
git clean -ndf
To actually delete the files:
git clean -df
To display the commit log in a condensed format:
git log --pretty=oneline --abbrev-commit
To create a new branch but stay on the current branch:
git branch <NEW_BRANCH_NAME>
To create and switch to a new branch:
git checkout -b <NEW_BRANCH_NAME>
To switch to another branch:
git checkout <OTHER_BRANCH_NAME>
You can mark specific points in your repository's history by adding tags. Tags are commonly used for releases but can be used for other purposes as well.
To tag the current commit, use the following commands. Replace <TAG_NAME>
with the unique name for the tag (e.g., v1.0.4
for versioning) and <DESCRIPTION>
with a description of the changes (optional).
git tag -a "<TAG_NAME>" -m "<DESCRIPTION>"
git push <REMOTE_NAME> --tags
-
Get the patch file for the commit, pull request, or change you want to import. For GitHub pull requests, you can get the patch file by appending
.patch
to the URL of the pull request:curl -L https://github.com/<USER>/<REPO>/pull/<ID>.patch
-
Apply the patch file using
git apply
:curl -L https://github.com/<USER>/<REPO>/pull/<ID>.patch | git apply
-
Optionally, make additional changes to the imported code.
-
Commit the changes, mentioning the original author of the patch:
git commit --author "<ORIGINAL_AUTHOR_NAME> <<ORIGINAL_AUTHOR_EMAIL>>" -m "<YOUR_COMMIT_MESSAGE>"
To create a local copy of an old branch under a new name and push it to the remote:
git checkout -b <NEW_BRANCH_NAME> <OLD_BRANCH_NAME>
git push -u <REMOTE_NAME> <NEW_BRANCH_NAME>
To rename a branch locally and on the remote:
git checkout -b <NEW_BRANCH_NAME> <OLD_BRANCH_NAME>
git push -u <REMOTE_NAME> <NEW_BRANCH_NAME>
git branch -d <OLD_BRANCH_NAME>
git push origin :<OLD_BRANCH_NAME>
To create a new branch with no history and start fresh:
git checkout --orphan <NEW_BRANCH_NAME>
rm -rf ./*
# Add your new files
git add .
git commit -m "Initial commit"
git push -uf <REMOTE_NAME> <NEW_BRANCH_NAME>
To count the total number of commits on a branch:
git rev-list --count <BRANCH_NAME>
# Example: git rev-list --count main
To count commits per author:
git shortlog -s -n
If you mistakenly ran git reset --hard HEAD^
and lost commits, use git reflog
to find the commit and reset to it:
git reflog
git reset 'HEAD@{1}'
To undo the last commit but keep the changes in your working directory:
git reset --soft HEAD~1
To find the size of a folder:
du -hs
To remove files from history, use git filter-branch
:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <pathname>' <commitHASH>
Or use bfg
:
-
Install
bfg
:brew install bfg
-
Run
bfg
to clean commit history:bfg --delete-files *.mp4 bfg --replace-text passwords.txt bfg --delete-folders .git
-
Remove files:
git reflog expire --expire=now --all && git gc --prune=now --aggressive
To replace text, create a passwords.txt
file with the following format:
PASSWORD1 # Replace literal string 'PASSWORD1' with '***REMOVED***' (default)
PASSWORD2==>examplePass # Replace with 'examplePass' instead
PASSWORD3==> # Replace with the empty string
regex:password=\w+==>password= # Replace using a regex
To combine multiple commits into one:
git rebase -i HEAD~<n>
# or
git rebase -i <COMMIT_HASH>
To discard all changes:
git reset
git checkout .
git clean -fdx
git rm -r --cached node_modules
To change the commit message of the most recent commit:
git commit --amend
To apply a commit from another branch as a new commit:
git cherry-pick <YOUR_COMMIT_HASH>
To rename a branch, you can use the following commands:
# Rename the branch from old-name to new-name
git branch -m old-name new-name
# Or, if you are on the branch you want to rename
git branch -m new-name
# Delete the old branch on the remote and push the new branch
git push origin :old-name new-name
# Set the upstream branch for the new branch
git push origin -u new-name
To reset your local branch to match the remote repository's main
branch:
git fetch origin
git reset --hard origin/main
git clean -f # Clean local files
To delete all remote branches that have already been merged:
git branch -r --merged | grep -v main | sed 's/origin\///' | xargs -n 1 git push --delete origin
To reset your local branch to match the remote:
git fetch --all
# Option 1: Reset to main branch
git reset --hard origin/main
# Option 2: Reset to a specific branch
git reset --hard origin/<branch_name>
To get the latest commit of the repository:
git log -1
Press Q
to exit the log view.
To get the full hash of the latest commit:
git log -1 --pretty=%H
# Output
706b92ba174729c6a1d761a8566a74f0a0bf8672
To get the abbreviated hash:
git log -1 --pretty=%h
# Output
706b92b
To store the hash in a variable:
echo $(git log -1 --pretty=%H)
Tag the repository and perform a commit:
# Tag the repository
git tag -a v0.0.1 -m "version v0.0.1"
# Check the tag
git describe
# Output: v0.0.1
# Perform a commit
git commit -am 'chore: do something'
# Describe again
git describe
# Output: v0.0.1-1-g9ba5c76
Set up aliases to simplify common Git commands:
alias gst='git status'
alias gcm='git commit -S -am'
alias gco='git checkout'
alias gl='git pull origin'
alias gpom="git pull origin main"
alias gp='git push origin'
alias gd='git diff | mate'
alias gb='git branch'
alias gba='git branch -a'
alias del='git branch -d'
To get the repository URL and name:
git config --get remote.origin.url
git ls-remote --get-url
git remote get-url origin
# Output: https://github.com/username/repository.git
basename $(git remote get-url origin) .git
# Output: repository
To delete a branch locally:
git push origin --delete <branch_name>
git remote update --prune
git branch | grep -v "main" | xargs git branch -D
To list branches sorted by the last commit date:
git fetch --prune
git branch --sort=-committerdate
- feat: A new feature visible to end users.
- fix: A bug fix visible to end users.
- chore: Changes that don't impact end users (e.g., changes to CI pipeline).
- docs: Changes to documentation.
- refactor: Changes to production code focused on readability, style, or performance.
git branch --merged
git branch --no-merged
To clean up unnecessary files and optimize the local repository:
# Cleanup unnecessary files
git gc
# Prune all unreachable objects from the object database
git prune
# Verify the connectivity and validity of objects in the database
git fsck
# Prune your remote working directory
git remote update --prune
git config --global push.followTags true
To restore a specific file to its state at a given commit:
git restore -s <SHA1> -- <filename>
To download a specific folder from a GitHub repository using SVN:
# Replace tree/main with trunk in the URL
svn export https://github.com/alextanhongpin/pkg.git/trunk/authheader
To create an alias for downloading docker-compose
templates:
alias init-db='svn export https://github.com/alextanhongpin/docker-samples/trunk/postgres/docker-compose.yml'
Ensure you have a changelog edited in your current branch. Use a pre-commit hook to enforce this:
#!/bin/bash
if [[ $(git diff develop -- CHANGELOG.md | wc -l) -eq 0 ]]; then
echo "Don't forget to add CHANGELOG.md"
exit 1
fi
To favor the current branch during a rebase:
git rebase -X theirs ${branch}
More info on merge strategies for rebase
To automate tasks after checking out a branch, use a post-checkout hook:
-
Create and set permissions for the hook:
touch .git/hooks/post-checkout chmod u+x .git/hooks/post-checkout
-
Add the following script to
.git/hooks/post-checkout
:#!/bin/bash # Parameters # $1: Ref of previous head # $2: Ref of new head # $3: Whether this is a file checkout (0) or branch checkout (1). # This is a file checkout - do nothing if [ "$3" == "0" ]; then exit; fi BRANCH_NAME=$(git symbolic-ref --short -- HEAD) NUM_CHECKOUTS=$(git reflog --date=local | grep -o ${BRANCH_NAME} | wc -l) # If the refs of the previous and new heads are the same # and the number of checkouts equals one, a new branch has been created if [ "$1" == "$2" ] && [ ${NUM_CHECKOUTS} -eq 1 ]; then echo "new branch created" else echo "switched branch to ${BRANCH_NAME}" fi
To revert a file to its state in the main branch:
git checkout $(git rev-parse main) -- path-to-file
To amend the latest commit with new changes:
git add --all
git commit --amend
# Note: You may need to force push if the commit has already been pushed
git push --force
If your branch is messy and you want to clean up the commits:
-
Create a new temporary branch:
git checkout -b feature/foo-tmp
-
Create a patch file of changes:
git diff origin/feature/foo origin/main > out.patch
-
Apply the patch to the temporary branch:
git apply out.patch
-
Clean up and rebase as needed, then delete the old branch:
git branch -D feature/foo
-
Rename the temporary branch to the original name:
git branch -m feature/foo
-
Force push the cleaned branch:
git push --force feature/foo
Use git push --force-with-lease
instead of git push --force
for safer forced updates.
Learn more about force-with-lease
To fix up a previous commit:
-
Create a fixup commit:
git commit --fixup <first-commit-hash>
-
Rebase to squash the fixup commit:
git rebase -i --autosquash --root
- Relivator Next.js Template
- Theo's Post
- Martin Heinz's Blog
- Delight-IM's Git Knowledge
- Alex Tan Hong Pin's Cheat Sheet
This guide covers various useful Git commands and techniques, inspired by various resources and composed by Reliverse, making it easier for both beginners and advanced users to manage and optimize their repositories.