From 0e076141e8a63280d1b61b7aa140a5bb4972cf39 Mon Sep 17 00:00:00 2001 From: Misty Stanley-Jones Date: Thu, 9 Oct 2014 09:38:24 +1000 Subject: [PATCH] HBASE-12207 Add a script to help keep your Git repository tidy. --- dev-support/rebase_all_git_branches.sh | 140 +++++++++++++++++++++++++++++++++ src/main/docbkx/developer.xml | 37 ++++++++- 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100755 dev-support/rebase_all_git_branches.sh diff --git a/dev-support/rebase_all_git_branches.sh b/dev-support/rebase_all_git_branches.sh new file mode 100755 index 0000000..0567e34 --- /dev/null +++ b/dev-support/rebase_all_git_branches.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +# Licensed 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" + +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 + ;; + *) + # Print usage instructions + echo "Usage:" + echo " Rebase all branches in DEFAULT_DIR: $0" + echo " Rebase all branches in a specific directory: $0 -d " + exit 0 + ;; + 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 does not exist or 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 +git branch -lvv | grep "\[origin/"|sed -e 's/\*//g'|awk {'print $1'} |while read i; +do + git checkout -q $i + # Exit if git status 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 + + git pull -q --rebase + status=$? + if [ "$status" -ne 0 ]; then + echo "Unable to pull changes in $i: $status Exiting." + exit 1 + fi + echo "Refreshed $i from remote." +done + +for i in `git branch --list|sed -e "s/\*//g"`; do + # Check JIRA status to see if we still need this branch + if [[ $i == HBASE-* ]] || [[ $i == hbase-* ]]; then + jira=$(echo $i |awk '{print toupper($0)}') + jira_url='https://issues.apache.org/jira/browse' + # The JIRA status looks like this in the HTML: + # span id="resolution-val" class="value resolved" > + # The following is a bit brittle, but matches lines with + # resolution-val and gets the 'resolved' (or unresolved) part + jira_status=$(curl -s $jira_url/$jira|grep resolution-val|sed -e "s/.*class=\"value\ //"|cut -d'"' -f 1) + if [ "$jira_status" = "resolved" ]; then + # the JIRA seems to be resolved or is at least not unresolved + #echo "$i is resolved. Delete manually: git branch -D $i" + deleted_branches="$i $deleted_branches" + fi + fi + + git checkout -q $i + + # Exit if git status 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 + + # 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 +if [[ $deleted_branches ]]; then + echo "Deleted branches: $deleted_branches" + read -p "Delete them? " yn + case $yn in + [Yy]) + git branch -D $deleted_branches + ;; + *) + echo -e "To delete them manually, issue the following command:\n \ + git branch -D $deleted_branches" + ;; + esac +fi +git checkout -q master +exit 0 \ No newline at end of file diff --git a/src/main/docbkx/developer.xml b/src/main/docbkx/developer.xml index 57f2490..4e1a08e 100644 --- a/src/main/docbkx/developer.xml +++ b/src/main/docbkx/developer.xml @@ -1780,6 +1780,40 @@ justification="I know what I'm doing") +
+ Git Best Practices + + + Use the correct method to create patches. See . + + + Avoid git merges. Use git pull --rebase or git + fetch followed by git rebase. + + + Do not use git push --force. If the push does not work, fix + the problem or ask for help. + + + Please contribute to this document if you think of other Git best + practices. +
+ <code>rebase_all_git_branches.sh</code> + The dev-support/rebase_all_git_branches.sh script is + provided to help keep your Git repository clean. Use the -h + parameter to get usage instructions. The script automatically refreshes your + tracking branches, attempts an automatic rebase of each local branch against its + remote branch, and gives you the option to delete any branch which represents a + closed HBASE- JIRA. The script has one optional configuration + option, the location of your Git directory. You can set a default by editing the + script. Otherwise, you can pass the git directory manually by using the + -d parameter, followed by an absolute or relative directory + name, or even '.' for the current working directory. The script checks the + directory for sub-directory called .git/, before + proceeding. +
+
Submitting Patches @@ -1787,7 +1821,8 @@ justification="I know what I'm doing") contribute patches in our new GIT context, caveat the fact that we have a different branching model and that we don't currently do the merge practice described in the following, the accumulo doc - on how to contribute and develop after our move to GIT is worth a read. + on how to contribute and develop after our move to GIT is worth a read. + See also . If you are new to submitting patches to open source or new to submitting patches to Apache, start by reading the