208 lines
5.8 KiB
Bash
Executable File
208 lines
5.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
# This script assumes that your remote is called "origin"
|
|
# and that your local master branch is called "master".
|
|
# I am sure it could be made more abstract but these are the defaults.
|
|
|
|
# Edit this line to point to your default directory,
|
|
# or always pass a directory to the script.
|
|
|
|
DEFAULT_DIR="EDIT_ME"
|
|
|
|
function print_usage {
|
|
cat << __EOF
|
|
|
|
$0: A script to manage your Apache HBase Git repository.
|
|
|
|
If run with no arguments, it reads the DEFAULT_DIR variable, which you
|
|
can specify by editing the script.
|
|
|
|
Usage: $0 [-d <dir>]
|
|
$0 -h
|
|
|
|
-h Show this screen.
|
|
-d <dir> The absolute or relative directory of your Git repository.
|
|
__EOF
|
|
}
|
|
|
|
function get_all_branches {
|
|
# Gets all git branches present locally
|
|
all_branches=()
|
|
for i in `git branch --list | sed -e "s/\*//g"`; do
|
|
all_branches+=("$(echo $i | awk '{print($1)}')")
|
|
done
|
|
}
|
|
|
|
function get_tracking_branches {
|
|
# Gets all branches with a remote tracking branch
|
|
tracking_branches=()
|
|
for i in `git branch -lvv | grep "\[origin/" | sed -e 's/\*//g' | awk {'print $1'}`; do
|
|
tracking_branches+=("$(echo $i | awk '{print($1)}')")
|
|
done
|
|
}
|
|
|
|
function check_git_branch_status {
|
|
# Checks the current Git branch to see if it's dirty
|
|
# Returns 1 if the branch is dirty
|
|
git_dirty=$(git diff --shortstat 2> /dev/null | wc -l|awk {'print $1'})
|
|
if [ "$git_dirty" -ne 0 ]; then
|
|
echo "Git status is dirty. Commit locally first." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function get_jira_status {
|
|
# This function expects as an argument the JIRA ID,
|
|
# and returns 99 if resolved and 1 if it couldn't
|
|
# get the status.
|
|
|
|
# The JIRA status looks like this in the HTML:
|
|
# span id="resolution-val" class="value resolved" >
|
|
# The following is a bit brittle, but filters for lines with
|
|
# resolution-val returns 99 if it's resolved
|
|
jira_url='https://issues.apache.org/jira/rest/api/2/issue'
|
|
jira_id="$1"
|
|
curl -s "$jira_url/$jira_id?fields=resolution" |grep -q '{"resolution":null}'
|
|
status=$?
|
|
if [ $status -ne 0 -a $status -ne 1 ]; then
|
|
echo "Could not get JIRA status. Check your network." >&2
|
|
exit 1
|
|
fi
|
|
if [ $status -ne 0 ]; then
|
|
return 99
|
|
fi
|
|
}
|
|
|
|
# Process the arguments
|
|
while getopts ":hd:" opt; do
|
|
case $opt in
|
|
d)
|
|
# A directory was passed in
|
|
dir="$OPTARG"
|
|
if [ ! -d "$dir/.git/" ]; then
|
|
echo "$dir does not exist or is not a Git repository." >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
h)
|
|
# Print usage instructions
|
|
print_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Invalid argument: $OPTARG" >&2
|
|
print_usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$dir" ]; then
|
|
# No directory was passed in
|
|
dir="$DEFAULT_DIR"
|
|
if [ "$dir" = "EDIT_ME" ]; then
|
|
echo "You need to edit the DEFAULT_DIR in $0." >&2
|
|
$0 -h
|
|
exit 1
|
|
elif [ ! -d "$DEFAULT_DIR/.git/" ]; then
|
|
echo "Default directory $DEFAULT_DIR is not a Git repository." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
cd "$dir"
|
|
|
|
# For each tracking branch, check it out and make sure it's fresh
|
|
# This function creates tracking_branches array and stores the tracking branches in it
|
|
get_tracking_branches
|
|
for i in "${tracking_branches[@]}"; do
|
|
git checkout -q "$i"
|
|
# Exit if git status is dirty
|
|
check_git_branch_status
|
|
git pull -q --rebase
|
|
status=$?
|
|
if [ "$status" -ne 0 ]; then
|
|
echo "Unable to pull changes in $i: $status Exiting." >&2
|
|
exit 1
|
|
fi
|
|
echo "Refreshed $i from remote."
|
|
done
|
|
|
|
# Run the function to get the list of all branches
|
|
# The function creates array all_branches and stores the branches in it
|
|
get_all_branches
|
|
|
|
# Declare array to hold deleted branch info
|
|
deleted_branches=()
|
|
|
|
for i in "${all_branches[@]}"; do
|
|
# Check JIRA status to see if we still need this branch
|
|
# JIRA expects uppercase
|
|
jira_id="$(echo $i | awk '{print toupper($0)'})"
|
|
if [[ "$jira_id" == HBASE-* ]]; then
|
|
# Returns 1 if the JIRA is closed, 0 otherwise
|
|
get_jira_status "$jira_id"
|
|
jira_status=$?
|
|
if [ $jira_status -eq 99 ]; then
|
|
# the JIRA seems to be resolved or is at least not unresolved
|
|
deleted_branches+=("$i")
|
|
fi
|
|
fi
|
|
|
|
git checkout -q "$i"
|
|
|
|
# Exit if git status is dirty
|
|
check_git_branch_status
|
|
|
|
# If this branch has a remote, don't rebase it
|
|
# If it has a remote, it has a log with at least one entry
|
|
git log -n 1 origin/"$i" > /dev/null 2>&1
|
|
status=$?
|
|
if [ $status -eq 128 ]; then
|
|
# Status 128 means there is no remote branch
|
|
# Try to rebase against master
|
|
echo "Rebasing $i on origin/master"
|
|
git rebase -q origin/master > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "Failed. Rolling back. Rebase $i manually."
|
|
git rebase --abort
|
|
fi
|
|
elif [ $status -ne 0 ]; then
|
|
# If status is 0 it means there is a remote branch, we already took care of it
|
|
echo "Unknown error: $?" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Offer to clean up all deleted branches
|
|
for i in "${deleted_branches[@]}"; do
|
|
read -p "$i's JIRA is resolved. Delete? " yn
|
|
case $yn in
|
|
[Yy])
|
|
git branch -D $i
|
|
;;
|
|
*)
|
|
echo "To delete it manually, run git branch -D $deleted_branches"
|
|
;;
|
|
esac
|
|
done
|
|
git checkout -q master
|
|
exit 0
|