-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathcherry-pick.sh
executable file
·141 lines (128 loc) · 4.22 KB
/
cherry-pick.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env bash
# To be run from the root of the Flambda backend repo.
# Cherry pick a commit from upstream repo and apply it to flambda-backend repo.
#
# Intended for experimental middle- and backend-related changes made on the upstream repo
# to be applied to the corresponding new directories:
#
# Changes in the upstream "asmcomp" directory are applied to "backend" subdirectory.
# Changes in the upstream "middle_end" directory are applied to "middle_end" subdirectory.
# Other changes are apply to "ocaml" subdirectory.
#
# To apply the changes into ocaml/asmcomp and ocaml/middle-end as well, invoke
# this script with "-everywhere" command line flag.
#
# To apply the changes from flambda-backend's "ocaml/asmcomp" subdirectory
# to "backend" subdirectory, invoke this script with "-across" command line flag.
#
# To backport a change from upstream to ocaml/ directory only, simply invoke
# "git cherry-pick REVISION" from "ocaml" subdirectory.
# Alternatively, invoke this script with "-ocaml-only"
#
# If a patch does not apply cleanly, the script stops, and the rest of
# the patches need to be applied manually. If "git am" or "git apply"
# fail, try "patch -p1 < file.patch" but be careful about "git add ." after it,
# because it generates .rej and .orig files that we do not want to commit by mistake.
#
# CR-someday gyorsh: there must be a simpler way to do it.
# if not, this script is too long and should be rewritten in ocaml.
set -eu -o pipefail
usage () {
cat <<EOF
Usage:
$0 REVISION [-everywhere|-ocaml-only|-across]
EOF
exit 1
}
everywhere=false
ocamlonly=false
across=false
if [ $# -eq 0 ]; then
echo "ERROR: missing arguments"
usage
elif [ $# -gt 2 ]; then
echo "ERROR: too many arguments"
usage
else
while [ $# -ge 1 ]; do
if [ "$1" = "-everywhere" ]; then
everywhere=true
elif [ "$1" = "-ocaml-only" ]; then
ocamlonly=true
elif [ "$1" = "-across" ]; then
across=true
else
rev=$1
fi
shift
continue
done
fi
if [ -z "${rev+x}" ]; then
echo "Missing REVISION"
usage
fi
# check that git status is empty
if [[ -n $(git status -s) ]] ; then
echo "Git status is not empty"
exit 2
fi
dir="."
subtree="."
patches=()
format_patch () {
temp=$(mktemp -d)
mkdir -p "$temp"
if [ "$dir" = "." ] ; then
relative=""
else
relative="--relative=$dir"
fi
patchfile=$(git format-patch -p $relative \
--src-prefix=a/$subtree/ --dst-prefix=b/$subtree/ \
-o "$temp" "$rev" -1 -- "$files")
if [ -s "$patchfile" ]; then
# patch file is not empty
echo "$patchfile"
patches+=("$patchfile")
else
# patch file is empty, ignore it
rm "$patchfile"
rmdir "$temp"
fi
}
apply_patches () {
for index in "${!patches[@]}"; do
patchfile="${patches[$index]}"
echo "Applying $patchfile"
if [ "$index" -eq 0 ] ; then
# use the commit details of the first patch
git am -3 "$patchfile" "--committer-date-is-author-date"
else
# for subsequent patches, just amend the previous commit
git apply -3 "$patchfile" #"--whitespace=fix" ?
git add .
git commit --amend --no-edit
fi
temp=$(dirname "$patchfile")
rm "$patchfile"
rmdir "$temp"
done
}
if [ "$ocamlonly" = true ] || [ "$everywhere" = true ] ; then
subtree="ocaml" dir="." files=":!Changes :!boot" format_patch
if [ "$everywhere" = true ] ; then
subtree="backend" dir="asmcomp" files="." format_patch
subtree="middle_end" dir="middle_end" files="." format_patch
fi
elif [ "$across" = true ] ; then
subtree="backend" dir="ocaml/asmcomp" files="." format_patch
subtree="middle_end" dir="ocaml/middle_end" files="." format_patch
dir="backend" subtree="ocaml/asmcomp" files="." format_patch
dir="middle_end" subtree="ocaml/middle_end" files="." format_patch
else
subtree="backend" dir="asmcomp" files="." format_patch
subtree="middle_end" dir="middle_end" files="." format_patch
subtree="ocaml" dir="." files=":!Changes :!boot :!asmcomp :!middle_end" format_patch
fi
apply_patches