My Git Aliases (May 2021)
Git Aliases
Intro
This post will go through my most used git aliases. Aliases can be used to save time on your most used commands, but also can be handy for saving you time trying to search stack overflow for rarely-used but tricky commands. I try to get in the habit of creating an alias any time I find myself using a command a lot, or if I google how to do something and come across a command that I'll probably forget before the next time I need it.
To find your most used commands you can use: history | awk 'BEGIN {FS="[ \t]+|\\|"} {print $3,$4}' | sort | uniq -c | sort -n
. Within that code, if you do print $3
it'll just print the first word of your command e.g. git
or vim
, doing print $3,$4
will print the second word too, e.g. git status
, or git log
.
The Aliases
git lo
,git lop
, andgit mo
- These are all shorthand's for working with remote branches. Let's say someone has pushed to
feature-123
, and you want to review and merge it. You can pull/fetch the changes but unless you're already on that branch, your local branch won't be up to date. To view the most up to date version of the branch without changing to it you'll have to actually look atorigin/feature-123
. - Usage:
git lo feature-123
will rungit log origin/feature-123
, which will show the commits on the remote branch. - Usage:
git lop feature-123
will rungit log -p origin/feature-123
, which will show the code change for each commit. - Usage:
git mo feature-123
will rungit merge origin/feature-123
, which will merge the remote branch.
- These are all shorthand's for working with remote branches. Let's say someone has pushed to
s
- This is an alias for
git status
, which is the command for knowing the current state of things, so it's useful to be able to run it with a single letter.
- This is an alias for
gco -b
,gco -
, andgco --
gco
is an alias forgit checkout
which is another useful command.- Usage:
gco -b feature-123
will rungit checkout -b feature-123
, which will create a branch calledfeature-123
- Usage:
gco -
will rungit checkout -
, which will checkout the previous branch you were on. - Usage:
gco -- path/to/file
will rungit checkout -- path/to/file
, which will get rid of any unstated changes in the file atpath/to/file
.
git short-hash
- Usage:
git short-hash <commit-hash>
will rungit rev-parse --short <commit-hash>
, which will give you a shortened version of the commit hash you give it. - As far as I'm aware, it doesn't serve much of a purpose other than making the hashes you share look nicer.
- Usage:
git file-change-commits
,git file-changes
, andgit show-file
- Usage:
git file-change-commits path/to/file
will rungit log --all --follow path/to/file
, which will show all the commits from any branch that changes the specified file (even if that file has been renamed in the past). - Usage:
git file-changes path/to/file
will run the same as above but with the-p
flag, which will show the code changes in each commit. - Usage:
git show-file some-branch path/to/file
will rungit show some-branch:path/to/file
, which will show you what the specified file looks like on the specified branch. - These are useful for when you know something has changed in a file in the past but can't remember when/why, if you know you changed the file on a specific branch, or if you're trying to resolve merge conflicts.
- Usage:
git branch-commit-diffs
,git branch-code-diffs
, andgit branch-file-diffs
- These are all about finding diffs between two branches.
- Usage:
git branch-commit-diffs branch-1 branch-2
will rungit log --oneline --graph --decorate --abbrev-commit branch-2..branch-1;
. You can also leave off the second branch and it'll use your current commit instead. This will show you a list of commits that are on branch-1 and not on branch-2. - Usage:
git branch-code-diffs branch-1 branch-2
will rungit diff branch-2..branch-1;
. This will show you the diff of the code that's on branch-1 but not on branch-2. - Usage:
git branch-file-diffs branch-1 branch-2 path/to/file
will rungit diff branch-2..branch-1 -- path/to/file;
. This will do the same as the previous command but will only show you the code in the file specified.
git nb
- Usage:
git nb hotfix-123
will rungit fetch && git checkout main && git checkout -b hotfix-123;
. You could also dogit nb hotfix-123 v1.0.0
which would rungit fetch && git checkout v1.0.0 && git checkout -b hotfix-123
- This is useful for creating a new branch when you want it to be branched off somewhere different to your current location. The default will be the
main
branch but you can change it to be a different place.
- Usage:
git branched-off
, andgit released-in
- Usage:
git branched-off feature-123
will rungit describe --tags --abbrev=0 --match 'v*' feature-123;
, which will find the closest tag that starts with 'v' (e.g.v1.0.0
) before the point you've specified. - Usage:
git released-in feature-123
will rungit tag --contains feature-123 'v*' | head -n 1;
, which will find the closest tag that starts with 'v' (e.g.v1.0.0
) after the point you've specified. - These rely on you creating tags when you release a new version and allow you to check the version a branch is ahead of, and the version it was released in (if at all).
- Usage:
stash
,spop
,spull
, andspush
- Usage:
stash
will rungit stash
, which will just stash all un-comitted, tracked changes, and you could dostash save "message"
to save with a message. - Usage:
spop
will rungit stash pop
, which will pop the latest stash so the changes are back in your working directory. - Usage:
spull
will rungit stash && git pull --rebase
, which will stash your changes and then pull. - Usage:
spush
will rungit push && git stash pop
, which will pushed your commits and then unstash your changes. - This means you can commit some things and push even when you have other WIP changes by doing
spull
followed byspush
.
- Usage:
git pset
- Usage:
git pset
will rungit push --set-upstream origin <current_branch_name>;
. This will push a newly created branch to the remote.
- Usage:
git rm-branch
- Usage:
git rm-branch branch-to-delete
will rungit branch -D branch-to-delete && git push -d origin branch-to-delete
, which will first delete your local copy of the branch and then the remote copy.
- Usage:
git recent
- This will run
git for-each-ref --count=10 --sort=-committerdate refs/heads/ --format="%(refname:short)"
, which will list the 10 most recent branches that you were on sorted by last commit.
- This will run
git recap
, andgit today
- These are useful for reminding yourself of what you've been up to which is handy for meetings where you talk about what you've been working on.
- Usage:
git recap Peter
will rungit log --all --oneline --no-merges --author=Peter;
, you can leave off the name and it will default to using whatever your git config email is set to. This will give you a list of all the commits you've made. - Usage:
git today Peter
is the same as above except it limits it to only commits made today.
git reset-to-origin
- Usage:
git reset-to-origin
, will rungit reset --hard origin/<current-branch>
, where<current-branch>
is the name of your current branch. It will get rid of any local changes you have, so that your local branch matches the remote branch.
- Usage:
git edit
, andgit uncommit
- Usage:
git edit
will rungit rebase -i
, which will allow you to (among other things) change commit messages, and squash multiple commits into one. - Usage:
git uncommit
will rungit reset --soft HEAD^
, which will basically undo the act of committing. Your changes will still be staged but will not be committed.
- Usage:
isMerged
- Usage:
isMerged HEAD feature-123
, will run a function to check iffeature-123
has been merged intoHEAD
, i.e. your current location. You could specify another location though.
- Usage:
git stats
- Usage:
git stats
will rungit shortlog -sn --all --no-merges
, which will show you a list of committers and how many commits they have, excluding merge commits.
- Usage:
Aliases
~/.gitconfig
[alias]
lo = "!f() { git log origin/$1; }; f"
lop = "!f() { git log -p origin/$1; }; f"
mo = "!f() { git merge origin/$1; }; f"
recap = "!f() { git log --all --oneline --no-merges --author=${1-$(git config user.email)}; }; f"
recent = for-each-ref --count=10 --sort=-committerdate refs/heads/ --format="%(refname:short)"
today = "!f() { git log --all --since=00:00:00 --oneline --no-merges --author=${1-$(git config user.email)}; }; f"
stats = shortlog -sn --all --no-merges
branched-off = "!f() { git describe --tags --abbrev=0 --match 'v*' ${1-HEAD}; }; f"
released-in = "!f() { git tag --contains ${1-HEAD} 'v*' | head -n 1; }; f"
branch-code-diffs = "!f() { git diff ${2-HEAD}..$1; }; f"
branch-commit-diffs = "!f() { git log --oneline --graph --decorate --abbrev-commit ${2-HEAD}..$1; }; f"
branch-file-diffs = "!f() { git diff ${3-HEAD}..$2 -- $1; }; f"
file-change-commits = "!f() { git log --all --follow $1; }; f"
file-changes = "!f() { git log -p --all --follow $1; }; f"
show-file = "!f() { git show $1:$2; }; f"
nb = "!f() { git fetch && git checkout ${2-main} && git checkout -b $1; }; f"
reset-to-origin = "!f() { git reset --hard origin/${1-$(git rev-parse --abbrev-ref HEAD)}; }; f"
pset = "!f() { git push --set-upstream origin ${1-$(git rev-parse --abbrev-ref HEAD)}; }; f"
rm-branch = "!f() { git branch -D $1 && git push -d origin $1; }; f"
edit = rebase -i
uncommit = reset --soft HEAD^
mv-tag = "!f() { git tag -d $1 && git push origin :refs/tags/$1 && git tag $1 ${2-HEAD} && git push origin $1; }; f"
short-hash = rev-parse --short
~/.zshrc
alias s='git status'
alias gco='git checkout'
alias stash='git stash'
alias spop='git stash pop'
alias spull='git stash && git pull --rebase'
alias spush='git push && git stash pop'
isMerged() {
merge_destination_branch=$1
merge_source_branch=$2
merge_base=$(git merge-base $merge_destination_branch $merge_source_branch)
merge_source_current_commit=$(git rev-parse $merge_source_branch)
if [[ $merge-base = $merge_source_current_commit ]]
then
echo $merge_source_branch is merged into $merge_destination_branch
return 0
else
echo $merge_source_branch is not merged into $merge_destination_branch
return 1
fi
}