Git
Basic actions
Clone a remote repo:
git clone $REMOTE_REPO_URL
Get the status of your repo:
git status
Get the status of your repo listing all the files:
git status -u
Stage a change:
git add $FILE_PATH
Choose chunks of code you want to stage:
git add -p $FILE_PATH
Commit a change and sign it:
git commit -s -m "$COMMIT_MESSAGE"
Add new changes to the last commit:
git commit --amend
Push your change to a remote repo:
git push -u origin $BRANCH_NAME
Create a branch:
git checkout -b $BRANCH_NAME
Search some code in the git history:
git rev-list --all | xargs git grep -F ‘$STRING_TO_SEARCH’
Standardise commit messages
Using Commitizen to have a common format.
Install commitizen
globally:
npm install -g commitizen
Install the commitizen adapter globally:
npm install -g cz-conventional-changelog
Create a .czrc
file in the home directory, with the path referring to the preferred, globally-installed, commitizen
adapter:
echo "{ \"path\": \"$(npm root -g)/cz-conventional-changelog\" }" > ~/.czrc
Now, use git cz
to handle the commit.
Here is are the type of changes that you can commit:
feat:
A new featurefix:
A bug fixdocs:
Documentation only changesstyle:
Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)refactor:
A code change that neither fixes a bug nor adds a featureperf:
A code change that improves performancetest:
Adding missing or correcting existing testschore:
Changes to the build process or auxiliary tools and libraries such as documentation generation
Check differences
Check all changes since last commit:
git diff --color-words
Check changes since last commit for a specific file:
git diff --color-words HEAD $PATH_TO_FILE
Check changes between two commits:
git diff --color-words $COMMIT_NUMBER $COMMIT_NUMBER
Check changes between two commits for a specific file:
git diff --color-words $COMMIT_NUMBER $COMMIT_NUMBER $PATH_TO_FILE
Check changes between two branches:
git diff --color-words $BRANCH_NAME $BRANCH_NAME
Check changes between two branches for a specific file:
git diff --color-words $BRANCH_NAME $BRANCH_NAME $PATH_TO_FILE
Check stages changes:
git diff --staged
Commit history managment
Check commit history:
git log --oneline --graph --color
Better git log:
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
Check commit history with changes:
git log -p
Add file change to the last commit:
git commit --am -s -m "$COMMIT_MESSAGE"
Count the number of commits on a specific branch:
git rev-list --count $BRANCH_NAME
Branch managment
Delete local branch:
git branch -d $BRANCH_NAME
Delete remote branch:
git push origin --delete $BRANCH_NAME
Pulls the changes from the remote branch to the local branch and makes a merge:
git pull origin $BRANCH_NAME
Rebase a base branch in current branch:
git rebase $BASE_BRANCH
Rebase a remote branch in current branch:
git pull --rebase origin master
Rebase a remote branch in current branch and stash changes:
git pull --rebase --autostash origin master
Rename a branch:
git branch -m $BRANCH_OLD_NAME $BRANCH_NEW_NAME
git push origin :$BRANCH_OLD_NAME $BRANCH_NEW_NAME
git push origin -u $BRANCH_NEW_NAME
Copy a file from a branch to the current one:
git checkout $BRANCH_TO_COPY_FROM $PATH_OF_THE_FILE_TO_COPY
Delete local branch that has been deleted remotely:
git branch --merged master | grep -E -v "master|main" | xargs -n 1 git branch -d
Delete local branch that are not master
:
git branch | grep -E -v "master|main" | xargs -n 1 git branch -d
Start a new git repository
git init
git add .
git commit -m "First commit"
git remote add origin $REPO_URL
git push -u origin master
Config managment
To set the default config to be used, used git config --global --edit
:
[color]
ui = true
[alias]
lop = log --pretty=format:"%C(yellow)%h\\ %Cred%ad\\ %Cblue%an%Cgreen%d\\ %Creset%s" --date=short
ll = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --numstat
Check current config:
git config -l
Set username for the repo:
git config user.name "$NAME"
Set username globally:
git config --global user.name "$NAME"
Set email for the repo:
git config user.email "$EMAIL"
Set email globally:
git config --global user.email "$EMAIL"
Set a GPG key to be used to sing commits:
gpg --list-secret-keys --keyid-format LONG
# Copy the GPG key ID that starts with sec
git config user.signingkey 30F2B65B9246B6CA
# Automatically sign commits
git config commit.gpgsign true
Set GPG program to use (usefull to solve gpg: signing failed: secret key not available
):
git config --global gpg.program gpg2
Enable credential helper to not have to retype your password each time you want to do something:
git config credential.helper store
Submodules
Clone repo with submodules (5 submodules at once):
git clone --recursive --jobs 5 $GIT_SUBMODULE_REPO_URL
Pull all the submodules updates:
git pull --recurse-submodules
Create a submodule:
git submodule add -b master --name $SUBMODULE_NAME $GIT_SUBMODULE_REPO_URL $SUBMODULE_PATH
Delete a submodule:
# Delete the relevant section from the .gitmodules file
git add .gitmodules
git submodule deinit $PATH_TO_SUBMODULE
git rm $PATH_TO_SUBMODULE
git commit -m "Removed submodule"
rm -rf .git/modules/$PATH_TO_SUBMODULE
Tips and tricks
I committed and immediately realized I need to make one small change:
# make your change
git add . # or add individual files
git commit --amend --no-edit
I accidentally committed something to master that should have been on a new branch:
# create a new branch from the current state of master
git branch $SOME_NEW_BRANCH
# remove the last commit from the master branch
git reset HEAD~ --hard
git checkout $SOME_NEW_BRANCH
# your commit lives in this branch now
I accidentally committed to the wrong branch:
# undo the last commit, but leave the changes available
git reset HEAD~ --soft
git stash
# move to the correct branch
git checkout $NAME_OF_THE_CORRECT_BRANCH
git stash pop
git add . # or add individual files
git commit -m "your message here";
# now your changes are on the correct branch
I need to undo the last commit:
git revert --no-edit HEAD
# git will create a new commit that undoes the last commit
I need to undo a commit from like 5 commits ago:
# find the commit you need to undo
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git revert --edit [saved hash]
# git will create a new commit that undoes that commit with the message you will have specified
I need to undo a commit from like 5 commits ago:
# find the commit you need to undo
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git revert --no-edit [saved hash]
# git will create a new commit that undoes that commit
I need to undo a commit from like 5 commit ago, and I want to review the changes made by the revert statement before committing them:
# find the commit you need to undo
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git revert --no-commit [saved hash]
# git will not create a new commit that undoes that commit
I need to undo my changes to a file:
# find a hash for a commit before the file was changed
git log
# use the arrow keys to scroll up and down in history
# once you've found your commit, save the hash
git checkout [saved hash] -- path/to/file
# the old version of the file will be in your index
git commit -m "Wow, you don't have to copy-paste to undo"
Thanks to Frumusanu Razvan for this tricks
Trigger the CI without making changes to the code base:
git commit --allow-empty -s -m "Trigger CI"