Working with GIT
Useful GIT Commands
List all local and remote branches
git branch -a
List all files changed by a specific commit
git show --pretty="" --name-only COMMIT_ID
Aborting a rebase
If the working folder gets messed up while resolving a merge conflict caused by a re-base it is possible to start over by aborting the rebase.
git rebase --abort
Delete untracked files and directories
git clean -dn
The more usefull arguments for this command are:
-n previews -f actualy deletes -d includes directories.
Reset Repository, discarding all changes
git reset --hard
Checkout a file from another branch
Instead of cherry-picking an entire commit, it is possible to check out a file from another branch into the current working folder.
git checkout branchname filename
Show the commit history for a specific file
git log -p -- [path to file]
Show objects using the most space
The following command shows all git blob objectss sorted from the smallest to the largest. This command is useful to see which commits are using lots of space in the repository.
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| sed -n 's/^blob //p' \
| sort --numeric-sort --key=2 \
| cut -c 1-12,41- \
| $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
Git Configuration
Run git commands recursively
Adding the following alias to git config allows running git commands recursively on all git repositories within a subfolder.
git config --global alias.all '!f() { ls -R -d \*/.git | xargs -I{} bash -c "echo {} && git -C {}/../ $1"; }; f'
With the alias in place, it is now possible to run the following command to work on multiple repositories at the same time.
git all pull
git all "checkout master"
Visually pleasing git logs.
Adding the following alias to git config allows viewing the git log in a more digestible format.
Read the full article from the author of this neat trick. 👉 Mattias Geniar: Pretty git log in one line
git config --global alias.logline "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
After the previous alias the git log can be viewed with better formatting and concise information.
git logline
Show GIT info in BASH prompt
Show the currently checked out branch in the bash prompt while maintaining bash prompt colors. Download the .git-prompt.sh file from the GIT main repository and save it to a location in your local file system. In this case in subfolder called .mystuff which is located inside of my home folder. https://github.com/git/git/tree/master/contrib/completion
# Show working directory git branch.
source ~/.mystuff/.git-prompt.sh
# PS1='\n\033[01;34m\]\w\[\033[95m\]$(__git_ps1 " (%s)")\n${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\\$
# PS1='\n👻 \t \[\033[01;34m\]\w\[\033[95m\]$(__git_ps1 " (%s)")\n\[\033[00m\]\[\033[32m\]${debian_chroot:+($debian_chroot)}\u@\h\[\033[00m\]:\\$ '
# Enable AWS autoprompt
PS1='\n👻 \t - \[\033[32m\]${debian_chroot:+($debian_chroot)}\u@\h\[\033[00m\]\[\033[95m\]$(__git_ps1 " (%s)")\n\[\033[01;34m\]\w\[\033[00m\] \$ '
Windows Config Settings
On windows systems git will attempt to automatically convert between windows and linux style line-endings, this causes issues when workging with repositoies located inside of the WSL from both inside linux (bash) and powershell.
Since most modern code editors can be configured to use Linux style line endings it is easiest to disable the automatic conversion of line endings.
git config --global core.autocrlf false
This setting can also be encoded into the git repository. Simply check in a file called .gitattributes with the following settings into the repository root. More info
- text=auto eol=lf
_.{cmd,[cC][mm][dD]} text eol=crlf
_.{bat,[bB][aa][tT]} text eol=crlf
Additionally on the windows side disable tracking the file mode. Without this option (default) git diff will flag the difference in file permissions, which are inherently different when navigating to the linux subsystem through powershell.
On the windows side disable this globally. git config core.fileMode false
Conflict Style
GIT can be configured to provide three way merge information for resolving merge conflicts. Do to so issue the following command.
git config --global merge.conflictstyle diff3
After configuring this option git will also provide the common ancestor of the two file version being compared.
Patching between branches
Suppose you are working on a feature branch that is shared with a co-worker. Both of you are committing to this feature branch. Also, to ensure you keep up to date with changes from the rest of the team one of your regulary merges changes from develop into your feature branch.
Several days / weeks pass and now you wish to cleanly merge your changes and re-organise your commits. One way to do this is by constructing a patch. The patch will essentially contain only those changes missing from the develop branch and not include all commits that were merged. Note, this will essentially look like all your changes happend at once and all comitts from yourself and your team made will be gone. Instead you can now re-organise a new set of commits.
git diff $(git merge-base develop feature/foo) > /tmp/patch.diff
git checkout develop
git apply /tmp/patch.diff