Skip to content

Commit 378b22a

Browse files
committed
[s2854] Add missing backporting scripts
1 parent 425aea2 commit 378b22a

File tree

3 files changed

+364
-1
lines changed

3 files changed

+364
-1
lines changed

sd2_revision_nr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#ifndef __SD2_REVISION_NR_H__
22
#define __SD2_REVISION_NR_H__
3-
#define SD2_REVISION_NR "s2853"
3+
#define SD2_REVISION_NR "s2854"
44
#endif // __SD2_REVISION_NR_H__

tool/backporting/mangos-backport.sh

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
#!/bin/bash
2+
#
3+
# mangos-backport - a bash helper for backporting in git for MaNGOS project
4+
# Copyright (C) 2009 freghar <compmancz@gmail.com>
5+
#
6+
# This program is free software; you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation; either version 2 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program; if not, write to the Free Software
18+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19+
# 02110-1301, USA
20+
#
21+
22+
# The script works pretty simple - each time an empty commit is made,
23+
# copying author and message from the original one.
24+
# Then the original commit is cherry-picked -n (no commit)
25+
# and the changes are git commit --amended to the prepared empty commit.
26+
27+
### general definitions
28+
29+
## internals
30+
BATCH_PROCESS=0
31+
VERBOSE=0
32+
33+
## user-tunable
34+
PORT_FROM="SD2-WotLK"
35+
AUTORESOLVE="sd2_revision_nr.h"
36+
GIT_AMEND_OPTS="-s"
37+
GIT_RECOVER="git reset --hard HEAD^"
38+
CONFLICT_RETVAL=2 # for batch usage
39+
GIT_PATH="./"
40+
41+
42+
### print error to stderr
43+
function print_error {
44+
echo -e "${@}" 1>&2
45+
}
46+
47+
### prints help
48+
function print_help {
49+
echo -e "Usage: ${0##*/} [-vb] <revspec>" \
50+
"\nBackports a specified commit to current branch." \
51+
"\n\n -b Batch processing (no interaction)." \
52+
"\n (runs amend without calling \$EDITOR)" \
53+
"\n -v Be verbose." \
54+
"\n -n Never automatically commit." \
55+
"\n"
56+
}
57+
58+
### verbose print
59+
function verbose_print {
60+
[[ ${VERBOSE} > 0 ]] && echo "${@}"
61+
}
62+
63+
### runs a command and handles it's output verbosity
64+
#function verbose_run {
65+
# if [[ ${VERBOSE} > 0 ]]; then
66+
# "${@}"
67+
# return $?
68+
# else
69+
# "${@}" 1 > /dev/null
70+
# return $?
71+
# fi
72+
#}
73+
74+
### catches output of a command and returns it's retval
75+
#function catch_out {
76+
# pick_out=$(${@} 2>&1)
77+
# return $?
78+
#}
79+
80+
### recover from an error, deleting empty commit
81+
function git_recover {
82+
print_error "----------"
83+
print_error "Caught an error, checking for last commit ..."
84+
85+
# check if the last commit is empty,
86+
# ie. it has the same tree object dependency as it's parent
87+
local head_tree=$(git log -1 --pretty="%T" HEAD)
88+
local prev_tree=$(git log -1 --pretty="%T" HEAD^)
89+
if [[ $head_tree == $prev_tree ]]; then
90+
print_error "Last commit empty, running ${GIT_RECOVER}" \
91+
"\nto previous HEAD (should be ${CURRENT_HEAD})."
92+
print_error "----------"
93+
${GIT_RECOVER}
94+
else
95+
print_error "Last commit isn't empty (or git log failed) -" \
96+
"something strange happened,\ncheck git log" \
97+
"and do the cleanup (if needed) by hand."
98+
fi
99+
exit 1
100+
}
101+
102+
### amend the empty commit, assigning new tree
103+
function git_autoamend {
104+
105+
# if the index is empty, there's nothing to amend
106+
if [[ -z $(git diff-index --cached HEAD) ]]; then
107+
git_retval=$?
108+
[[ $git_retval != 0 ]] && git_recover
109+
110+
print_error "The index is empty, nothing to amend. This should" \
111+
"not happen during normal\nworkflow, so you" \
112+
"probably did something crazy like picking\na" \
113+
"commit to a branch where it already exists."
114+
git_recover
115+
fi
116+
117+
verbose_print "----------"
118+
if [[ ${BATCH_PROCESS} > 0 ]]; then
119+
if [[ ${VERBOSE} > 0 ]]; then
120+
git commit ${GIT_AMEND_OPTS} --amend -C HEAD
121+
git_retval=$?
122+
else
123+
git commit ${GIT_AMEND_OPTS} --amend -C HEAD 1> /dev/null
124+
git_retval=$?
125+
[[ $git_retval == 0 ]] && echo \
126+
"Commit ${COMMIT_HASH} picked."
127+
fi
128+
else
129+
git commit ${GIT_AMEND_OPTS} --amend -c HEAD
130+
git_retval=$?
131+
fi
132+
[[ $git_retval != 0 ]] && git_recover
133+
}
134+
135+
136+
### main()
137+
138+
## arguments
139+
140+
# arg parsing
141+
while getopts "vbn" OPTION; do
142+
case $OPTION in
143+
v)
144+
VERBOSE=1
145+
;;
146+
b)
147+
BATCH_PROCESS=1
148+
;;
149+
n)
150+
NO_AUTOCOMMIT=1
151+
;;
152+
\?)
153+
print_help
154+
exit 1
155+
;;
156+
esac
157+
done;
158+
shift $(( $OPTIND - 1 ))
159+
ORIG_REF=${1}
160+
161+
# check for needed arguments
162+
if [[ -z ${ORIG_REF} ]]; then
163+
print_help
164+
exit 1
165+
fi
166+
167+
## startup checks
168+
169+
# check for needed commands
170+
for cmd in git grep sed wc; do
171+
if [[ -z $(which ${cmd}) ]]; then
172+
print_error "error: ${cmd}: command not found"
173+
exit 1
174+
fi
175+
done;
176+
177+
# are we in git root dir?
178+
if [[ ! -d .git/ ]]; then
179+
print_error "error: not in repository root directory"
180+
exit 1
181+
fi
182+
183+
# is the index clean?
184+
if [[ ! -z $(git diff-index HEAD) ]]; then
185+
print_error "error: dirty index, run mixed/hard reset first"
186+
exit 1
187+
fi
188+
189+
## original commit infos
190+
191+
# current HEAD commit hash
192+
CURRENT_HEAD=$(git show -s --pretty=format:'%h' HEAD)
193+
[[ $? != 0 ]] && exit 1
194+
195+
# author with email
196+
COMMIT_AUTHOR=$(git show -s --pretty=format:'%an <%ae>' ${ORIG_REF})
197+
[[ $? != 0 ]] && exit 1
198+
199+
# commit object hash (abbrev)
200+
COMMIT_HASH=$(git show -s --pretty=format:'%h' ${ORIG_REF})
201+
[[ $? != 0 ]] && exit 1
202+
203+
# subject (with removed revision number)
204+
COMMIT_SUBJECT=$(git show -s --pretty=format:'%s' ${ORIG_REF} | sed -r 's/\[[a-z]?[0-9]*\] //')
205+
[[ $? != 0 ]] && exit 1
206+
COMMIT_REVISION=$(git show -s --pretty=format:'%s' ${ORIG_REF} | sed -r 's/\[([a-z]?[0-9]*).*/\1/')
207+
[[ $? != 0 ]] && exit 1
208+
if [ "$COMMIT_REVISION" != "" ]; then COMMIT_REVISION="[$COMMIT_REVISION] -"; fi
209+
210+
# body
211+
COMMIT_BODY=$(git show -s --pretty=format:'%b' ${ORIG_REF})
212+
[[ $? != 0 ]] && exit 1
213+
214+
# whole message (yea, it could be done without echo)
215+
COMMIT_MESSAGE=$(echo -e "${COMMIT_SUBJECT}\n\n${COMMIT_BODY}\n\n(based on commit $PORT_FROM$COMMIT_REVISION ${COMMIT_HASH})")
216+
[[ $? != 0 ]] && exit 1
217+
218+
## new empty commit ready, so create it
219+
verbose_print "Creating new empty commit on current HEAD (${CURRENT_HEAD}}."
220+
verbose_print "----------"
221+
if [[ ${VERBOSE} > 0 ]]; then
222+
git commit --author="${COMMIT_AUTHOR}" -m "${COMMIT_MESSAGE}" \
223+
--allow-empty
224+
[[ $? != 0 ]] && exit 1
225+
else
226+
git commit --author="${COMMIT_AUTHOR}" -m "${COMMIT_MESSAGE}" \
227+
--allow-empty 1> /dev/null
228+
[[ $? != 0 ]] && exit 1
229+
fi
230+
231+
232+
## first, try cherry-picking the commit and catch conflicts.
233+
## - if there are none, simply amend and exit
234+
## - if there are none related to $AUTORESOLVE, only prepare
235+
## the backported commit
236+
## - when multiple conflicts occur, including $AUTORESOLVE,
237+
## do the resolution for the one file, prepare the commit
238+
## and let user resolve the rest (+ amend)
239+
## - when only single ($AUTORESOLVE) conflict occur, resolve it
240+
## and fire up $EDITOR to autocommit
241+
242+
pick_out=$(git cherry-pick -n ${ORIG_REF} 2>&1)
243+
pick_retval=$?
244+
245+
# exit if there was a fatal app error
246+
if [[ $pick_retval > 1 ]]; then
247+
print_error "${pick_out}"
248+
git_recover
249+
fi
250+
251+
# get a list of unmerged files
252+
unmerged_files=$(git diff-files --diff-filter=U | sed 's/^[^\t]*\t//')
253+
git_retval=$?
254+
if [[ $git_retval != 0 ]]; then
255+
print_error "${pick_out}"
256+
git_recover
257+
fi
258+
259+
# simply amend if the pick was successful
260+
if [[ $pick_retval == 0 && -z $unmerged_files ]]; then
261+
verbose_print "${pick_out}"
262+
verbose_print "----------"
263+
if [[ ${NO_AUTOCOMMIT} > 0 ]]; then
264+
verbose_print "No conflicts to resolve, nothing to do."
265+
verbose_print "Please run git commit ${GIT_AMEND_OPTS} --amend" \
266+
"after making all necessary changes."
267+
verbose_print "Use ${GIT_RECOVER} to recover."
268+
else
269+
verbose_print "No conflicts to resolve, running amend."
270+
git_autoamend
271+
fi
272+
exit 0
273+
fi
274+
275+
# sanity check
276+
if [[ -z $unmerged_files ]]; then
277+
print_error "${pick_out}"
278+
print_error "----------"
279+
print_error "git cherry-pick failed with status 1," \
280+
"\nbut no unmerged files were found."
281+
git_recover
282+
fi
283+
284+
# if $AUTORESOLVE isn't there (but other conflicts are), simply exit
285+
if [[ -z $(echo "${unmerged_files}" | grep ${AUTORESOLVE}) ]]; then
286+
print_error "${pick_out}"
287+
echo "----------"
288+
verbose_print "${AUTORESOLVE} not found as unmerged."
289+
echo "Please run git commit ${GIT_AMEND_OPTS} --amend" \
290+
"after resolving all conflicts."
291+
echo "To recover from the resolution, use ${GIT_RECOVER}."
292+
exit ${CONFLICT_RETVAL}
293+
fi
294+
295+
# do the resolution - use old version of the file
296+
if [[ -f ${AUTORESOLVE} ]]; then
297+
verbose_print "${pick_out}"
298+
verbose_print "----------"
299+
verbose_print "Auto-resolving ${AUTORESOLVE} using old version."
300+
git show :2:${AUTORESOLVE} > ${AUTORESOLVE}
301+
[[ $? != 0 ]] && git_recover
302+
git add ${AUTORESOLVE}
303+
[[ $? != 0 ]] && git_recover
304+
# echo "Resolution of ${AUTORESOLVE} finished successfuly."
305+
else
306+
print_error "${pick_out}"
307+
print_error "----------"
308+
print_error "error: ${AUTORESOLVE} not found, cannot resolve"
309+
git_recover
310+
fi
311+
312+
# if $AUTORESOLVE was the only conflict, amend the commit
313+
if [[ $(echo "${unmerged_files}" | wc -l) == 1 ]]; then
314+
verbose_print "----------"
315+
if [[ ${NO_AUTOCOMMIT} > 0 ]]; then
316+
verbose_print "All done, autocommit disabled, nothing to do."
317+
verbose_print "Please run git commit ${GIT_AMEND_OPTS} --amend" \
318+
"after making all necessary changes."
319+
verbose_print "Use ${GIT_RECOVER} to recover."
320+
else
321+
verbose_print "All done, running git commit ${GIT_AMEND_OPTS} --amend ..."
322+
git_autoamend
323+
fi
324+
exit 0
325+
326+
# else let the user do all other conflict resolutions
327+
else
328+
print_error "${pick_out}"
329+
echo "----------"
330+
echo "Please run git commit ${GIT_AMEND_OPTS} --amend" \
331+
"after resolving all conflicts."
332+
echo "To recover from the resolution, use ${GIT_RECOVER}."
333+
exit ${CONFLICT_RETVAL}
334+
fi

tool/backporting/update-commit-log.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/sh
2+
3+
# Simple helper script to create SD2-Backporting Lists
4+
5+
# By user defined (remote/branch to the to-be-backported history)
6+
COMPARE_PATH="origin-wotlk/master"
7+
TODO_FILE="tool/backporting/todo_wotlk_commits.log"
8+
COMPARE_NAME="WotLK"
9+
10+
# param1 must be the commit hash of last backported commit (of original commit)
11+
if [ "$#" != "1" ]
12+
then
13+
echo "You must provide the last commit's hash of the \"$TODO_FILE\" file"
14+
exit 1
15+
fi
16+
17+
# are we in git root dir?
18+
if [[ ! -d .git/ ]]; then
19+
echo "ERROR: This script is expected to be called from repository root directory"
20+
echo "Try: tool/backporting/update-commit-log.sh"
21+
exit 1
22+
fi
23+
24+
HASH=$1
25+
26+
git log $HASH..$COMPARE_PATH --pretty=format:"${COMPARE_NAME}_COMMIT %h by %an (commiter %cn) \" %s \"" --reverse --dirstat >> $TODO_FILE
27+
echo "" >> $TODO_FILE
28+
echo "FILE LAST UPDATE BASED ON $(git log -1 --pretty="%h (by %an) \" %s \"" $COMPARE_PATH)" >> $TODO_FILE
29+
echo "" >> $TODO_FILE

0 commit comments

Comments
 (0)