tools: Add git utility scripts.
This commit is contained in:
parent
d05e932968
commit
ea105ffec5
70
tools/clean-branches
Normal file
70
tools/clean-branches
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# usage: clean-branches
|
||||||
|
# Deletes any local branches which are ancestors of origin/master,
|
||||||
|
# and also any branches in origin which are ancestors of
|
||||||
|
# origin/master and are named like $USER-*.
|
||||||
|
|
||||||
|
# usage: clean-branches --reviews
|
||||||
|
# Deletes all the above mentioned branches as well as branches
|
||||||
|
# created by the scripts like `fetch-rebase-pull-request`. Be careful
|
||||||
|
# as this would also remove other branches woth names like review-*
|
||||||
|
|
||||||
|
review=0
|
||||||
|
if [ $# -ne 0 ] && [ "$1" == "--reviews" ]; then
|
||||||
|
review=1
|
||||||
|
fi
|
||||||
|
push_args=()
|
||||||
|
|
||||||
|
function is_merged {
|
||||||
|
! git rev-list -n 1 origin/master.."$1" | grep -q .
|
||||||
|
}
|
||||||
|
|
||||||
|
function clean_ref {
|
||||||
|
ref="$1"
|
||||||
|
case "$ref" in
|
||||||
|
*/master | */HEAD)
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
|
||||||
|
refs/heads/review-*)
|
||||||
|
if [ $review -ne 0 ]; then
|
||||||
|
echo -n "Deleting local branch $(echo "$ref" | sed 's!^refs/heads/!!')"
|
||||||
|
echo " (was $(git rev-parse --short "$ref"))"
|
||||||
|
git update-ref -d "$ref"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
refs/heads/*)
|
||||||
|
if is_merged "$ref"; then
|
||||||
|
echo -n "Deleting local branch $(echo "$ref" | sed 's!^refs/heads/!!')"
|
||||||
|
echo " (was $(git rev-parse --short "$ref"))"
|
||||||
|
git update-ref -d "$ref"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
refs/remotes/origin/$USER-*)
|
||||||
|
if is_merged "$ref"; then
|
||||||
|
remote_name="$(echo "$ref" | sed 's!^refs/remotes/origin/!!')"
|
||||||
|
echo -n "Deleting remote branch $remote_name"
|
||||||
|
echo " (was $(git rev-parse --short "$ref"))"
|
||||||
|
# NB: this won't handle spaces in ref names
|
||||||
|
push_args=("${push_args[@]}" ":$remote_name")
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$(git symbolic-ref HEAD)" != 'refs/heads/master' ]; then
|
||||||
|
echo "Check out master before you run this script." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
git fetch --prune origin
|
||||||
|
|
||||||
|
eval "$(git for-each-ref --shell --format='clean_ref %(refname);')"
|
||||||
|
|
||||||
|
if [ "${#push_args}" -ne 0 ]; then
|
||||||
|
git push origin "${push_args[@]}"
|
||||||
|
fi
|
13
tools/clean-repo
Normal file
13
tools/clean-repo
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Remove .pyc files to prevent loading stale code.
|
||||||
|
#
|
||||||
|
# You can run it automatically on checkout:
|
||||||
|
#
|
||||||
|
# echo ./tools/clean-repo > .git/hooks/post-checkout
|
||||||
|
# chmod +x .git/hooks/post-checkout
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
find . -name "*.pyc" -exec rm -f {} \;
|
||||||
|
find . -name "__pycache__" -prune -exec rm -rf {} \;
|
43
tools/deploy-branch
Normal file
43
tools/deploy-branch
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function error_out {
|
||||||
|
echo -en '\e[0;31m'
|
||||||
|
echo "$1"
|
||||||
|
echo -en '\e[0m'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
status=$(git status --porcelain | grep -v '^??')
|
||||||
|
[ ! -z "$status" ] && error_out "Working directory or index not clean"
|
||||||
|
|
||||||
|
old_ref=$(git rev-list --max-count=1 HEAD)
|
||||||
|
branch=$1
|
||||||
|
branch_ref=$(git rev-list --max-count=1 "$branch")
|
||||||
|
|
||||||
|
[ $? -ne 0 ] && error_out "Unknown branch: $branch"
|
||||||
|
|
||||||
|
if [ "$old_ref" == "$branch_ref" ]; then
|
||||||
|
new_ref=master
|
||||||
|
else
|
||||||
|
ref_name=$(git describe --all --exact "$old_ref")
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
new_ref=$(echo "$ref_name" | perl -pe 's{^(heads|remotes)/}{}')
|
||||||
|
else
|
||||||
|
new_ref=$old_ref
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$branch" ] && error_out "You must specify a branch name to deploy"
|
||||||
|
|
||||||
|
git fetch -p
|
||||||
|
|
||||||
|
git rebase origin/master "$branch"
|
||||||
|
[ $? -ne 0 ] && error_out "Rebase onto origin/master failed"
|
||||||
|
|
||||||
|
git push . HEAD:master
|
||||||
|
git push origin master
|
||||||
|
[ $? -ne 0 ] && error_out "Push of master to origin/master failed"
|
||||||
|
|
||||||
|
git checkout "$new_ref"
|
||||||
|
git branch -D "$branch"
|
||||||
|
git push origin ":$branch"
|
16
tools/fetch-pull-request
Normal file
16
tools/fetch-pull-request
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if ! git diff-index --quiet HEAD; then
|
||||||
|
set +x
|
||||||
|
echo "There are uncommitted changes:"
|
||||||
|
git status --short
|
||||||
|
echo "Doing nothing to avoid losing your work."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
request_id="$1"
|
||||||
|
remote=${2:-"upstream"}
|
||||||
|
git fetch "$remote" "pull/$request_id/head"
|
||||||
|
git checkout -B "review-original-${request_id}"
|
||||||
|
git reset --hard FETCH_HEAD
|
17
tools/fetch-rebase-pull-request
Normal file
17
tools/fetch-rebase-pull-request
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if ! git diff-index --quiet HEAD; then
|
||||||
|
set +x
|
||||||
|
echo "There are uncommitted changes:"
|
||||||
|
git status --short
|
||||||
|
echo "Doing nothing to avoid losing your work."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
request_id="$1"
|
||||||
|
remote=${2:-"upstream"}
|
||||||
|
git fetch "$remote" "pull/$request_id/head"
|
||||||
|
git checkout -B "review-${request_id}" $remote/master
|
||||||
|
git reset --hard FETCH_HEAD
|
||||||
|
git pull --rebase
|
15
tools/reset-to-pull-request
Normal file
15
tools/reset-to-pull-request
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if ! git diff-index --quiet HEAD; then
|
||||||
|
set +x
|
||||||
|
echo "There are uncommitted changes:"
|
||||||
|
git status --short
|
||||||
|
echo "Doing nothing to avoid losing your work."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
request_id="$1"
|
||||||
|
remote=${2:-"upstream"}
|
||||||
|
git fetch "$remote" "pull/$request_id/head"
|
||||||
|
git reset --hard FETCH_HEAD
|
68
tools/review
Normal file
68
tools/review
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def exit(message):
|
||||||
|
# type: (str) -> None
|
||||||
|
print('PROBLEM!')
|
||||||
|
print(message)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def run(command):
|
||||||
|
# type: (str) -> None
|
||||||
|
print('\n>>> ' + command)
|
||||||
|
subprocess.check_call(command.split())
|
||||||
|
|
||||||
|
def check_output(command):
|
||||||
|
# type: (str) -> str
|
||||||
|
return subprocess.check_output(command.split()).decode('ascii')
|
||||||
|
|
||||||
|
def get_git_branch():
|
||||||
|
# type: () -> str
|
||||||
|
command = 'git rev-parse --abbrev-ref HEAD'
|
||||||
|
output = check_output(command)
|
||||||
|
return output.strip()
|
||||||
|
|
||||||
|
def check_git_pristine():
|
||||||
|
# type: () -> None
|
||||||
|
command = 'git status --porcelain'
|
||||||
|
output = check_output(command)
|
||||||
|
if output.strip():
|
||||||
|
exit('Git is not pristine:\n' + output)
|
||||||
|
|
||||||
|
def ensure_on_clean_master():
|
||||||
|
# type: () -> None
|
||||||
|
branch = get_git_branch()
|
||||||
|
if branch != 'master':
|
||||||
|
exit('You are still on a feature branch: %s' % (branch,))
|
||||||
|
check_git_pristine()
|
||||||
|
run('git fetch upstream master')
|
||||||
|
run('git rebase upstream/master')
|
||||||
|
|
||||||
|
def create_pull_branch(pull_id):
|
||||||
|
# type: (int) -> None
|
||||||
|
run('git fetch upstream pull/%d/head' % (pull_id,))
|
||||||
|
run('git checkout -B review-%s FETCH_HEAD' % (pull_id,))
|
||||||
|
run('git rebase upstream/master')
|
||||||
|
run('git log upstream/master.. --oneline')
|
||||||
|
run('git diff upstream/master.. --name-status')
|
||||||
|
|
||||||
|
print()
|
||||||
|
print('PR: %d' % (pull_id,))
|
||||||
|
print(subprocess.check_output(['git', 'log', 'HEAD~..',
|
||||||
|
'--pretty=format:Author: %an']))
|
||||||
|
|
||||||
|
def review_pr():
|
||||||
|
# type: () -> None
|
||||||
|
try:
|
||||||
|
pull_id = int(sys.argv[1])
|
||||||
|
except Exception:
|
||||||
|
exit('please provide an integer pull request id')
|
||||||
|
|
||||||
|
ensure_on_clean_master()
|
||||||
|
create_pull_branch(pull_id)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
review_pr()
|
Loading…
Reference in a new issue