HBASE-22518 yetus personality is treating branch-1.4 like earlier branches for hadoop...
[hbase.git] / dev-support / make_patch.sh
blob3737dc992fa1fb35e8738c5a6d1fea2ee620944b
1 #!/bin/bash
2 #/**
3 # * Licensed to the Apache Software Foundation (ASF) under one
4 # * or more contributor license agreements. See the NOTICE file
5 # * distributed with this work for additional information
6 # * regarding copyright ownership. The ASF licenses this file
7 # * to you under the Apache License, Version 2.0 (the
8 # * "License"); you may not use this file except in compliance
9 # * with the License. You may obtain a copy of the License at
10 # *
11 # * http://www.apache.org/licenses/LICENSE-2.0
12 # *
13 # * Unless required by applicable law or agreed to in writing, software
14 # * distributed under the License is distributed on an "AS IS" BASIS,
15 # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # * See the License for the specific language governing permissions and
17 # * limitations under the License.
18 # */
20 # Make a patch for the current branch based on its tracking branch
22 patch_version=''
24 # Process args
25 while getopts "ahtd:b:" opt; do
26 case "${opt}" in
27 a) addendum='-addendum'
30 patch_dir=$OPTARG
33 tracking_branch=$OPTARG
36 patch_version=".$(date -u +%Y%m%d-%H%M%S)"
39 echo -e "Usage: $0 [-h] [-a] [-t] [-d] <directory> \n\
40 Must be run from within the git branch to make the patch against.\n\
41 -h - display these instructions.\n\
42 -a - Add an 'addendum' prefix to the patch name.\n\
43 -t - Use the current timestamp as the version indicator.\n\
44 -b - Specify the base branch to diff from. (defaults to the tracking branch or origin master)\n\
45 -d - specify a patch directory (defaults to ~/patches/)"
46 exit 0
48 esac
49 done
51 # Find what branch we are on
52 branch=$(git branch | grep '^\*' | cut -d' ' -f2- )
53 if [ ! "${branch}" ]; then
54 echo "Can't determine the git branch. Exiting." >&2
55 exit 1
58 # Exit if git status is dirty
59 git_dirty=$(git diff --shortstat 2> /dev/null | wc -l)
60 echo "git_dirty is ${git_dirty}"
61 if [ "${git_dirty}" -ne 0 ]; then
62 echo "Git status is dirty. Commit locally first.">&2
63 exit 1
66 # Determine the tracking branch if needed.
67 # If it was passed in from the command line
68 # with -b then use dthat no matter what.
69 if [ ! "${tracking_branch}" ]; then
70 git log -n 1 "origin/${branch}" > /dev/null 2>&1
71 status=$?
72 if [ "${status}" -eq 128 ]; then
73 # Status 128 means there is no remote branch
74 tracking_branch='origin/master'
75 elif [ "${status}" -eq 0 ]; then
76 # Status 0 means there is a remote branch
77 tracking_branch="origin/${branch}"
78 else
79 echo "Unknown error: $?" >&2
80 exit 1
85 # Deal with invalid or missing ${patch_dir}
86 if [ ! "${patch_dir}" ]; then
87 echo -e "Patch directory not specified. Falling back to ~/patches/."
88 patch_dir=~/patches
91 if [ ! -d "${patch_dir}" ]; then
92 echo "${patch_dir} does not exist. Creating it."
93 mkdir "${patch_dir}"
96 # If this is against a tracking branch other than master
97 # include it in the patch name
98 tracking_suffix=""
99 if [[ "${tracking_branch}" != "origin/master" \
100 && "${tracking_branch}" != "master" ]]; then
101 tracking_suffix=".${tracking_branch#origin/}"
104 # Determine what to call the patch
105 if [[ "${patch_version}" == "" ]]; then
106 # If we do NOT have the timestamp we must find the version to use
107 version=0
108 # Check to see if any patch exists that includes the branch name
109 status=$(find "${patch_dir}" -maxdepth 1 -type f -name "${branch}${tracking_suffix}.v[0-9][0-9].patch" 2>/dev/null|grep -c -v addendum)
110 if [[ "${status}" -eq 0 ]]; then
111 # This is the first patch we are making for this release
112 version=1
113 elif [[ "${status}" -ge 1 ]]; then
114 # At least one patch already exists -- find the last one
115 for i in {99..1}; do
116 # Check to see the maximum version of patch that exists
117 versionfiles=$(find "${patch_dir}" -maxdepth 1 -type f -name "${branch}${tracking_suffix}.v$(printf "%02d" "$i").patch" 2> /dev/null | wc -l)
118 if [ 0 -lt "${versionfiles}" ]; then
119 version=$((i+1))
120 break
122 done
124 if [ -n "${addendum}" ]; then
125 # Don't increment the patch # if it is an addendum
126 echo "Creating an addendum"
127 if [ "${version}" -ge 1 ]; then
128 # We are making an addendum to a different version of the patch
129 version=$((version-1))
132 patch_version=".v$(printf "%02d" "${version}")"
136 patch_name="${branch}${tracking_suffix}${patch_version}${addendum}.patch"
138 # Do we need to make a diff?
139 git diff --quiet "${tracking_branch}"
140 status=$?
141 if [ "${status}" -eq 0 ]; then
142 echo "There is no difference between ${branch} and ${tracking_branch}."
143 echo "No patch created."
144 exit 0
147 # Check whether we need to squash or not
148 local_commits=$(git log "${tracking_branch}..${branch}" | grep -c 'Author:')
149 if [ "$local_commits" -gt 1 ]; then
150 read -p "$local_commits commits exist only in your local branch. Interactive rebase?" yn
151 case $yn in
152 [Yy]* )
153 git rebase -i "${tracking_branch}"
155 [Nn]* )
156 echo "Creating ${patch_dir}/${patch_name} using git diff."
157 git diff "${tracking_branch}" > "${patch_dir}/${patch_name}"
158 exit 0
160 esac
163 echo "Creating patch ${patch_dir}/${patch_name} using git format-patch"
164 git format-patch --no-prefix --stdout "${tracking_branch}" > "${patch_dir}/${patch_name}"