Git
Git snippets
Git Merge Master into Branch
git checkout feature/bump_hugo
git merge origin/main
git push
Pull all submodules
git submodule update --init --recursive
Update submodules
git pull --recurse-submodules
git clone --recursive git@github.com:adelerhof/technote.git
branches
git branch -a
git checkout -b feature/bump_hugo
git push -u origin feature/bump_hugo
Update all Git repositories and submodules
Add to ~/.profile:
alias git-pull-all="for dir in ./*; do (if test -d "$dir/.git"; then echo "Updating $dir.." && cd "$dir" && git pull --recurse-submodules; fi); done"
for dir in ./*; do (if test -d "$dir/.git"; then echo "Updating $dir.." && cd "$dir" && git pull --recurse-submodules; fi); done
Git prompt
RED="\033[0;31m"
YELLOW="\033[0;33m"
GREEN="\033[0;32m"
NO_COLOR="\033[0m"
function parse_git_branch () {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
function git_color () {
VAR=`git status 2>/dev/null`
if [ $? == 0 ]
then
COLOR="$RED"
echo ${VAR} | tail | grep "nothing to commit" > /dev/null
if [ $? == 0 ]
then
COLOR="${GREEN}"
fi
fi
echo -n -e "$COLOR"
}
PS1="[\[$GREEN\]\u@\h\[$NO_COLOR\]:\w\[\$(git_color)\]\$(parse_git_branch)\[$NO_COLOR\]]$ "
Git config
Set author info
git config --global user.name “Blaataap”
git config --global user.email “blaataap@blaataap.com”
Check Git settings
git config --list
Branches
git checkout <branch> # gets you "on branch <name>"
git fetch origin # gets you up to date with origin
git merge origin/master
Create New Branch
Create a new git branch and switch to it
git checkout -b <branch name>
and create it on origin too
git push --set-upstream origin <branch name>
Create branch based on onher branch
git checkout -b latest blaatbranch
Check used branch
git{} branch
Tracking Remote Branches
To follow additional branches in your local repo follow these steps:
# Find out all existing remote branches
git branch -r
# And track one of them locally
git branch --track <local name> origin/<name>
Remove Branch
Remove git branch locally with
git branch -d
and remove on origin too
git branch -d -r origin/
git push origin :
Alternatively remove on origin and then prune locally.
Remove stale
When remote branches disappear clean them from your local repo with
git remote prune origin
Rebasing
To rebase on master
git rebase master
Solve Merge Conflicts
When a rebase fails manually fix files and
git add <files>
git rebase --continue
Reset to a previous commit
git branch
git reset --hard HEAD~1 # 1 to move 1 commit
git checkout
git push -f
Commits
Amending changes
git add
git commit --amend
Apply patches
A detailed description can be found here. You should always run the following commands:
git apply --stat cool_feature.patch # Check what the patch will do
git apply --check cool_feature.patch # Check if the patch fails
git am --signoff < cool_feature.patch
Create patches
git format-patch -1 # Creates one patch file for the commit
git format-patch -2 HEAD # Creates two patch files for last two commits on HEAD
git format-patch -3 HEAD --stdout # Print last 3 commit changes on stdout
Solving Mistakes
Accidental “git add”
git reset HEAD []
Accidental commit of too many files
git reset --soft HEAD^
git status # to list all added files
git reset <files> # to remove incorrectly added files
# Commit afterwards
Stashing Changes
For a detailed explanation check here. This feature is useful to put debugging or experimental changes to the “background”. Here are the commands:
git stash "Some test I made" # Stash some changes away
git stash list # List stashes
git stash show stash@{0} # Show changes file in last stash
git stash show -p stash@{0} # Show patch for last stash
git stash apply stash@{0} # Get last stash active again
git stash drop stash@{0} # Delete last stash
git stash pop # Apply and remove last stash
git stash clear # Delete all stashes
# Stash just some files by adding all others first
# and using --keep-index
git add <files>
git stash --keep-index
List Commits in One Line Each
git rev-list --all --pretty=oneline
Search in Commits
To search all commits for lines containing a certain change:
git log -p -S --
git log -p -G --
Tags
git fetch --all --tags --prune
git checkout tag/<tag> -b <branch>
git clone <repo> --branch=<tag>
git tag # List all tags
git tag <tag> # Create tag
git tag -a <tag> -m <msg> # Create annotated tag
git tag -d <tag> # Deletes tag in your local repo
git push origin :<tag> # Deletes tag remote
Misc
Update submodules
git submodule update --init --recursive
Enable git password Caching
To keep passwords for 1h run
git config --global credential.helper 'cache --timeout=3600'
Remove all repo files from a directory
If you ever need to remove all git related files from a local working repo and make it just a normal directory:
git clean -ffrx
List Branch in Bash Prompt PS1
There are several documentations online e.g. this one. In the end it boils down to running “git branch” on each prompt and to use an environment function __git_ps1() that is set up by “git branch” to print the branch if there is one. So if your current $PS1 is
export PS1='\u@\h:\w\$ "
you could extend it to
export PS1='\u@\h:\w$(git branch &>/dev/null; echo $(__git_ps1 "(%s)"))\$ '
to show the branch name in braces after the directory name and before the $ like this:
blaataap@server:~/project/src(master)$
Push Dry Run
git push --dry-run --porcelain
git-write-tree: error building trees
git reset --mixed
Merge two repos
One simple way to merge two repos is to add one repo (repo1) into a subdirectory of another repository (repo2)
cd repo2
git remote add repo1 <path to repo1>
git fetch repo1
git merge -s ours --no-commit repo1/master
# Ignore the merge error!
git read-tree --prefix=<subdir> -u repo1/master
git commit
That’s it. Check “git log” to see if changes of repo1 appear.
Comfort merging with opening PRs in a browser
This can be done via git command aliases invoking xdg-open. An example solution
[alias]
curbranch = rev-parse --symbolic-full-name --abbrev-ref HEAD
bpush = !sh -c 'git push origin $(git curbranch) 2>&1 |grep -o "https://.*" |xargs xdg-open'
bp = !sh -c 'echo "Pull" && git pull origin master && echo "Push" && git bpush'
with now “git bp” pulling, pushing and opening the PR for further review work.
Checkout at a specific time
git checkout 'master@{2019-01-01 01:00:00}'
cherrypick changes in a specific commit from branch ‘A’ to branch ‘B’
git checkout B
git cherry-pick <commit hash from branch A>
know what changed on a specific commit
git show <commit hash>
Resync git repo
git fetch origin && git reset --hard origin/master && git clean -f -d
Resync forked repo
git remote add upstream https://github.com/lwindolf/lzone-cheat-sheets.git
git fetch upstream
git checkout master
git merge upstream/master
Delete remote branch
git push origin --delete <branch>