-
Notifications
You must be signed in to change notification settings - Fork 11
/
merge-changes-to-workspace-from-stdin.sh
executable file
·114 lines (96 loc) · 3.58 KB
/
merge-changes-to-workspace-from-stdin.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
#!/bin/bash
set -eu
function print_usage_and_die
{
cat >&2 << EOF
usage: $0 [CONFLICT_SCRIPT_DIR]
Cherry-pick citrix changes with additional conflict resolution.
positional arguments:
CONFLICT_SCRIPT_DIR Directory, where conflict resolution scripts live
EOF
exit 1
}
. lib/functions
THIS_DIR="$(cd $(dirname $(readlink -f $0)) && pwd)"
CONFLICT_PATCHES_DIR="${1:-}"
if [ -n "$CONFLICT_PATCHES_DIR" ]; then
CONFLICT_PATCHES_DIR="$(cd $CONFLICT_PATCHES_DIR && pwd)"
fi
echo "Working directory : [$THIS_DIR]"
echo "Conflict patches dir: [$CONFLICT_PATCHES_DIR]"
assert_no_new_repos
(
set -eu
cd .workspace
tmpfile=$(mktemp)
generate_repos > "$tmpfile"
# Cherry pick required changes
while read change; do
set -e
if [ -z "$change" ]; then
echo "Skipping empty line"
continue
fi
if [[ "$change" = \#* ]]; then
echo "Skipping comment $change"
continue
fi
user=$(echo "$change" | cut -d"/" -f 1)
repo=$(echo "$change" | cut -d" " -f 1 | cut -d"/" -f 2)
change_number=$(echo "$change" | cut -d" " -f 2 | cut -d"/" -f 4)
changeref=$(echo "$change" | cut -d" " -f 2)
if [ -z "$user" ] || [ -z "$repo" ] || [ -z "$change_number" ] || [ -z "$changeref" ]; then
echo "Failed to get all parameters"
exit 1
fi
if grep -q "$user $repo.git" "$tmpfile"; then
echo "[MERGE-START] $change"
repo_record=$(grep "$user $repo.git" "$tmpfile")
cd $(var_name "$repo_record")
if git fetch $(source_repo "$repo_record") $changeref && git merge FETCH_HEAD; then
echo "[MERGE-OK]"
else
echo "[MERGE-CONFLICT] Removing commit ids from conflicting files"
git diff --name-only --diff-filter=U | while read conflicting_filename; do
sed -i -e 's/^\(>\+\) \([^ ]\+\) \(.*\)$/\1 \3/g' \
"$conflicting_filename"
done
echo "[MERGE-CONFLICT] Printing diff to standard output"
git --no-pager diff
generic_resolution="$CONFLICT_PATCHES_DIR/generic_resolution.sh"
resolution_script="$CONFLICT_PATCHES_DIR/$change_number"
diff_script="$CONFLICT_PATCHES_DIR/$change_number.diff"
if [ -x $generic_resolution ]; then
echo "[MERGE-CONFLICT] Running generic resolution script generic_resolution.sh"
$generic_resolution
echo "[MERGE-CONFLICT] script done"
fi
echo "[MERGE-CONFLICT] looking for additional resolution script as $resolution_script"
if [ -x "$resolution_script" ]; then
echo "[MERGE-CONFLICT] Applying script $resolution_script"
$resolution_script
echo "[MERGE-CONFLICT] script done"
else
echo "[MERGE-CONFLICT] looking for diff as $diff_script"
if [ -e "$diff_script" ]; then
echo "[MERGE-CONFLICT] applying diff $diff_script"
git apply "$diff_script"
git diff --name-only --diff-filter=U | while read conflicting_filename; do
git add "$conflicting_filename"
done
git commit --no-edit --allow-empty
echo "[MERGE-CONFLICT] applied diff $diff_script"
fi
fi
if [ -n "`git status -s`" ]; then
echo "[MERGE-CONFLICT] Conflict was not resolved by any resolution script"
exit 1
fi
fi
cd ..
else
echo "[SKIPPING] $change"
fi
done
rm "$tmpfile"
)