Skip to content

Instantly share code, notes, and snippets.

@metlos
Last active October 12, 2022 14:47
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save metlos/9368527 to your computer and use it in GitHub Desktop.
Save metlos/9368527 to your computer and use it in GitHub Desktop.
git aliases for pull requests and other useful stuff
[alias]
tracking-branch = !git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)
current-branch = !git rev-parse --abbrev-ref HEAD
#last commit
last = log -1
#assumes the upstream repo is called origin
#and the name of the remote with the forked repo is passed as a
#argument
#updates the master branch in the fork with the latest changes in
#upstream origin repository.
#Stays on the current branch and keeps the changes in the working
#tree.
update-fork = "!sh -c '\
cur_branch=`git rev-parse --abbrev-ref HEAD`;\
git stash -u; \
git checkout master; \
git pull --ff-only origin master; \
git push $1 master; \
git fetch --all; \
git checkout $cur_branch; \
git stash pop;' -"
#lists all "tips" of branches - i.e. any commit appearing without
#an outgoing "edge" is represents a branch not merged anywhere else
#if no argument is given, shows all branches (local and remote).
#if an argument is given, limits the branches to the given remote.
unmerged = "!sh -c '\
if [ -z $1 ]; then \
what=\"--all\"; \
else \
what=\"--remotes=$1\"; \
fi; \
git log $what --graph --oneline --decorate --simplify-by-decoration --topo-order;' -"
#a simple linear log of the current branch
lg = log --decorate --oneline --topo-order --no-merges
#"large" log - shows merges from other branches et al
llog = log --graph --oneline --decorate --topo-order
#shows the commits made on this branch that are not present on the
#other branch specified as an argument
#
#git checkout feature
#git branch-log master
#
branch-log = !git log --oneline --decorate --graph --first-parent --topo-order --no-merges $1..HEAD
#same as branch-log but includes merge commits, too
branch-full-log = !git log --oneline --decorate --graph --first-parent --topo-order $1..HEAD
#prunes all remote branches
prune-all = !git remote | xargs -n 1 git remote prune
# lists all open pull requests in the repo
# git pr-opened origin
pr-opened = "!sh -c '\
user_and_repo=`git remote show $1 | grep \"Fetch URL\" | sed -E \"s/.*github.com[:\\/]([a-zA-Z_\\-]+)\\/([a-zA-Z_\\-]+)\\.git$/\\1 \\2/\"`; \
user=`echo $user_and_repo | cut -d\" \" -f1`; \
repo=`echo $user_and_repo | cut -d\" \" -f2`; \
git ls-remote $1 \
| grep -E \"refs\\/pull\\/[[:digit:]]+\\/head\" \
| while read line; do \
commit=`echo $line | cut -d\" \" -f1`;\
ref=`echo $line | cut -d\" \" -f2`;\
exists=`git rev-list $1 | grep $commit | wc -l`;\
if [ -z $exists -o $exists -eq 0 ]; then\
merged=0;\
else\
merged=`git branch -r --no-color --contains $commit | grep -E \"$1/master$\" | wc -l`; \
fi;\
if [ $merged -eq 0 ]; then \
pull=`echo $ref | sed \"s/refs\\/pull\\///\" | sed \"s/\\/head//\"`; \
title=`curl -si https://api.github.com/repos/$user/$repo/pulls/$pull | grep \"\\\"title\\\": \" | sed \"s/^ *\\\"title\\\": \\\"//\" | sed \"s/\\\",$//\"`; \
echo \"pull/$pull: $title\"; \
fi \
done' -"
# gives the commit hash of a pull request
# git pr-hash origin 3
pr-hash = "!sh -c '\
git ls-remote $1 \
| grep -E \"refs/pull/$2/head\" \
| cut -f1' -"
# merges given pull request into the current branch
# the commit message will have the same for as if done using the
# merge button on github.com
#
# git pr-merge origin 5
pr-merge = "!sh -c '\
user_and_repo=`git remote show $1 | grep \"Fetch URL\" | sed -E \"s/.*github.com[:\\/]([a-zA-Z_\\-]+)\\/([a-zA-Z_\\-]+)\\.git$/\\1 \\2/\"`; \
user=`echo $user_and_repo | cut -d\" \" -f1`; \
repo=`echo $user_and_repo | cut -d\" \" -f2`; \
tmpfile=`mktemp`; \
curl -si https://api.github.com/repos/$user/$repo/pulls/$2 > $tmpfile; \
pull_author=`cat $tmpfile | awk \"{if (/ *\\\"head\\\"/) head=\\\\$1; if (/ *\\\"login\\\": \\\"/) value=\\\\$2}{if (head && value) print value; if (head && value) exit}\" | sed -E \"s/\\\"([^\\\"]+)\\\".*/\\1/\"`; \
pull_ref=`cat $tmpfile | awk \"{if (/ *\\\"head\\\"/) head=\\\\$1; if (/ *\\\"ref\\\": \\\"/) label=\\\\$2}{if (head && label) print label; if (head && label) exit}\" | sed -E \"s/\\\"([^\\\"]+)\\\".*/\\1/\"`; \
pull_title=`cat $tmpfile | grep \"\\\"title\\\": \" | sed \"s/^ *\\\"title\\\": \\\"//\" | sed \"s/\\\",$//\"`; \
rm $tmpfile; \
git fetch $1 pull/$2/head; \
git merge --no-ff -m \"Merged pull request #$2 from $pull_author/$pull_ref\n\n$pull_title\" FETCH_HEAD; \
' -"
# checks out given pull request to a new local branch
# if branch name not specified it defaults to "pull/<number>"
#
# git pr-checkout origin 12 pull/12
pr-checkout = "!sh -c '\
name=$3; \
if [ -z $name ]; then name="pull/$2"; fi; \
git fetch $1 pull/$2/head:$name; \
git checkout $name' -"
# Checks out a branch and also updates the local maven cache to contain the artifacts that were last built on that branch, if any.
# The saved caches are stored in ~/.m2/cache-overrides directory.
#
# This requires 2 properties in the git repo configuration:
# mvn-cache.name = the name of the cache... If you have multiple repos that you would like to switch like this, the name is used to
# distinguish between them in the cache-overrides directory
# mvn-cache.groupId = a list of groupIds of the maven artifacts to put into the cache. This could theoretically be deduced from the maven build
# but the developer knows this anyway, so it's easier to just ask :) Use git config --add to add multiple values to this
# config property.
mvn-checkout = "!sh -c '\
cacheOverride=`git config mvn-cache.name`; \
cacheGroupIds=`git config --get-all mvn-cache.groupId`; \
if [ -z \"$cacheOverride\" -o -z \"$cacheGroupIds\" ]; then \
echo \"mvn-cache.name and mvn-cache.groupId git config properties must be set.\"; \
else \
oldBranch=`git rev-parse --abbrev-ref HEAD`; \
oldHash=`git rev-parse HEAD`; \
git checkout $@; \
if [ $? -eq 0 ]; then \
newBranch=`git rev-parse --abbrev-ref HEAD`; \
newHash=`git rev-parse HEAD`; \
isDifferentCommit=1; [ $oldHash != $newHash ] && isDifferentCommit=0; \
for gid in $cacheGroupIds; do \
gidAsDir=`echo $gid | sed \"s/\\\\./\\\\//g\"`; \
echo \"Copying artifacts of groupId \\\"$gid\\\" built on the \\\"$oldBranch\\\" branch to a separate cache.\"; \
if [ ! -d ~/.m2/cache-overrides/$cacheOverride/$oldBranch/$gid ]; then \
mkdir -p ~/.m2/cache-overrides/$cacheOverride/$oldBranch/$gid; \
fi; \
rm -Rf ~/.m2/cache-overrides/$cacheOverride/$oldBranch/$gid/*; \
if [ -d ~/.m2/repository/$gidAsDir ]; then \
if [ `ls -1 ~/.m2/repository/$gidAsDir | wc -l` -ne 0 ]; then \
cp -R ~/.m2/repository/$gidAsDir/* ~/.m2/cache-overrides/$cacheOverride/$oldBranch/$gid; \
fi; \
if [ "$isDifferentCommit" -eq 0 ]; then \
rm -Rf ~/.m2/repository/$gidAsDir/*; \
fi; \
else \
mkdir -p ~/.m2/repository/$gidAsDir; \
fi; \
if [ -d ~/.m2/cache-overrides/$cacheOverride/$newBranch/$gid ]; then \
if [ $isDifferentCommit -eq 0 ]; then \
echo \"Replacing local maven cache with the cache of the branch \\\"$newBranch\\\".\"; \
if [ `ls -1 ~/.m2/cache-overrides/$cacheOverride/$newBranch/$gid/ | wc -l` -ne 0 ]; then \
cp -R ~/.m2/cache-overrides/$cacheOverride/$newBranch/$gid/* ~/.m2/repository/$gidAsDir/; \
fi; \
else \
echo \"Keeping the current local Maven cache for groupId \\\"$gid\\\" because the new branch points to the same commit as the old one.\"; \
fi; \
else \
if [ $isDifferentCommit ]; then \
echo \"No previously saved cache for branch \\\"$newBranch\\\". Local maven cache clear for groupId \\\"$gid\\\".\"; \
else \
echo \"Keeping the current local Maven cache for groupId \\\"$gid\\\" because the new branch points to the same commit as the old one.\"; \
fi; \
fi; \
done; \
fi; \
fi; \
' -"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment