-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcherry-pick-for
executable file
·92 lines (84 loc) · 3.2 KB
/
cherry-pick-for
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
#!/bin/bash
set -euo pipefail
if [ $# -lt 2 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo "Usage: $0 (--no-checkout-and-pull|BRANCH) (COMMITS...|https://github.com/ORG/REPO/pull/NUMBER)"
echo "Switches to the given branch, pulls it, cherry-picks all given commits or all commits of the"
echo "given GitHub PR, and pushes the branch"
echo "WARNING: Does not work for changes on symbolic links! Cherry pick the PR's commits manually,"
echo "this helper script is not really needed anymore for change tracking because this is done through"
echo "files in the changelog/*/ folders now."
echo "Parameters:"
echo " --no-checkout-and-pull: If given instead of a branch, skips switching and pulling but pushes in the end"
echo "Environment variables:"
echo " MERGE_COMMIT: Create a GitHub-style merge commit if a URL is given (defaults to 1)"
echo " PUSH: Push the branch to upstream (defaults to 1)"
echo " ORIGIN: Remote to use when checking out the tracking branch (defaults to origin)"
exit 1
fi
PUSH="${PUSH-1}"
MERGE_COMMIT="${MERGE_COMMIT-1}"
ORIGIN="${ORIGIN-origin}"
BRANCH="$1"
COMMITS="${@:2}"
if [ "$BRANCH" = "--no-checkout-and-pull" ]; then
BRANCH="HEAD"
else
echo "Checking out $BRANCH"
git checkout --recurse-submodules "$BRANCH" || git checkout --recurse-submodules --track "$ORIGIN/$BRANCH"
echo "Pulling $BRANCH"
git pull --recurse-submodules
fi
# Remove BRANCH from arguments to get the COMMITS to the front
shift
if [ "${COMMITS:0:4}" = http ]; then
URL="$COMMITS"
if [[ "$URL" = *" "* ]]; then
echo "Error: Only one URL supported as argument"
exit 1
fi
echo "Going to merge $URL"
if [ "$MERGE_COMMIT" = 1 ]; then
TEMP_BRANCH="pick$RANDOM"
META="$(curl -s -S -f -L "$URL" | grep '<title>.*GitHub</title>')"
PR_MSG1="Merge$(echo "$META" | awk -F'·' '{ print $2 }' | tr '[:upper:]' '[:lower:]')"
PR_MSG2="from$(echo "$META" | awk -F'·' '{ print $3 }')"
PR_TITLE="$(echo "$META" | awk -F'·' '{ print $1 }' | cut -d '>' -f 2- | rev | cut -d ' ' -f 4- | rev)"
COMMIT_MSG="$PR_MSG1$PR_MSG2
$PR_TITLE"
git checkout -b "$TEMP_BRANCH"
fi
echo "If you need to resolve conflicts, follow the \"git status\" instructions, then run:"
if [ "${MERGE_COMMIT}" = 1 ]; then
echo " git checkout --recurse-submodules -"
echo " git merge --no-ff -m \"$COMMIT_MSG\" $TEMP_BRANCH"
echo " git branch -d $TEMP_BRANCH"
fi
echo " git push"
echo
curl -s -S -f -L "$URL".patch | git am --3way
echo "Successfully picked $URL"
if [ "$MERGE_COMMIT" = 1 ]; then
git checkout --recurse-submodules -
git merge --no-ff -m "$COMMIT_MSG" "$TEMP_BRANCH"
git branch -d "$TEMP_BRANCH"
fi
else
echo "Going to pick $COMMITS"
for COMMIT in $COMMITS; do
echo "Cherry-picking $COMMIT for $BRANCH"
# Remove current COMMIT from arguments to get the list of remaining commits
shift
if [ $# -gt 0 ]; then
echo "If you need to resolve conflicts, continue with: $0 --no-checkout-and-pull $@"
else
echo "If you need to resolve conflicts, continue with: git push"
fi
git cherry-pick "$COMMIT"
done
echo "Successfully picked $COMMITS"
fi
if [ "$PUSH" = 1 ]; then
echo "Pushing changes"
git push
fi
echo "Done"