Skip to main content

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 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.

# Show working directory git branch.
source ~/.mystuff/
# 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