-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_mixed_workflows.sh
More file actions
executable file
·222 lines (189 loc) · 5.92 KB
/
Copy pathtest_mixed_workflows.sh
File metadata and controls
executable file
·222 lines (189 loc) · 5.92 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#!/bin/bash
#
# Test mixed merge/rebase workflows where feature2 is NOT fully up to date
# with feature1 at the time of squash-merge.
#
# Scenarios:
# A) feature2 rebased onto an intermediate state of feature1, then feature1
# got more commits that feature2 never picked up.
# B) feature2 merged feature1 once, then rebased onto a later feature1 state,
# but feature1 got yet more commits after that.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../command_utils.sh"
simulate_push() {
log_cmd git update-ref "refs/remotes/origin/$1" "$1"
}
# Extract just the +/- lines from a diff (ignoring headers and context)
diff_changes() {
grep '^[+-]' | grep -v '^[+-][+-][+-]'
}
run_scenario() {
local SCENARIO_NAME="$1"
echo ""
echo "============================================"
echo " Scenario $SCENARIO_NAME"
echo "============================================"
echo ""
TEST_REPO=$(mktemp -d)
cd "$TEST_REPO"
log_cmd git init -b main
log_cmd git config user.email "test@example.com"
log_cmd git config user.name "Test User"
# 10-line file to keep changes well-separated
for i in $(seq 1 10); do echo "line $i" >> file.txt; done
log_cmd git add file.txt
log_cmd git commit -m "Initial commit"
simulate_push main
}
assert_diff_is() {
local LABEL="$1"
local EXPECTED="$2"
local ACTUAL
ACTUAL=$(log_cmd git diff main...feature2 | diff_changes)
if [[ "$ACTUAL" == "$EXPECTED" ]]; then
echo "✅ $LABEL"
else
echo "❌ $LABEL"
echo "Expected changed lines:"
echo "$EXPECTED"
echo "Actual changed lines:"
echo "$ACTUAL"
exit 1
fi
}
assert_idempotent() {
local BEFORE AFTER
BEFORE=$(git rev-parse feature2)
run_update_pr_stack
cd "$TEST_REPO"
AFTER=$(git rev-parse feature2)
if [[ "$BEFORE" == "$AFTER" ]]; then
echo "✅ Idempotent"
else
echo "❌ Idempotence failed"
exit 1
fi
}
squash_merge_feature1() {
log_cmd git checkout main
log_cmd git merge --squash feature1
log_cmd git commit -m "Squash merge feature1"
SQUASH_COMMIT=$(git rev-parse HEAD)
simulate_push main
echo "Squash commit: $SQUASH_COMMIT"
}
run_update_pr_stack() {
log_cmd \
env \
SQUASH_COMMIT=$SQUASH_COMMIT \
MERGED_BRANCH=feature1 \
TARGET_BRANCH=main \
GH="$SCRIPT_DIR/mock_gh.sh" \
GIT="$SCRIPT_DIR/mock_git.sh" \
$SCRIPT_DIR/../update-pr-stack.sh
}
########################################################################
# Scenario A: rebase onto intermediate feature1, then feature1 advances
########################################################################
run_scenario "A: rebased onto intermediate feature1, then feature1 advances"
# feature1: two commits (lines 2 and 3)
log_cmd git checkout -b feature1
sed -i '2s/.*/f1 commit 1/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f1: commit 1"
simulate_push feature1
# feature2: branched from feature1 after commit 1, changes line 9
log_cmd git checkout -b feature2
sed -i '9s/.*/f2 content/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f2: change line 9"
simulate_push feature2
# feature1 gets commit 2
log_cmd git checkout feature1
sed -i '3s/.*/f1 commit 2/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f1: commit 2"
simulate_push feature1
# Developer rebases feature2 onto feature1 (picks up commit 2)
log_cmd git checkout feature2
log_cmd git rebase feature1
simulate_push feature2
# feature1 gets commit 3 — feature2 does NOT pick this up
log_cmd git checkout feature1
sed -i '4s/.*/f1 commit 3/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f1: commit 3"
simulate_push feature1
echo ""
echo "=== Graph before squash-merge ==="
log_cmd git log --graph --oneline --all
echo ""
squash_merge_feature1
run_update_pr_stack
cd "$TEST_REPO"
# The diff should show only feature2's unique change
assert_diff_is "Scenario A: diff shows only f2's change" "$(cat <<'EOF'
-line 9
+f2 content
EOF
)"
assert_idempotent
########################################################################
# Scenario B: merge then rebase, then feature1 advances again
########################################################################
run_scenario "B: merge then rebase, then feature1 advances again"
# feature1: commit 1 (line 2)
log_cmd git checkout -b feature1
sed -i '2s/.*/f1 commit 1/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f1: commit 1"
simulate_push feature1
# feature2 from feature1, changes line 9
log_cmd git checkout -b feature2
sed -i '9s/.*/f2 content/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f2: change line 9"
simulate_push feature2
# feature1 gets commit 2
log_cmd git checkout feature1
sed -i '3s/.*/f1 commit 2/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f1: commit 2"
simulate_push feature1
# Developer merges feature1 into feature2
log_cmd git checkout feature2
log_cmd git merge --no-edit feature1
simulate_push feature2
# feature1 gets commit 3
log_cmd git checkout feature1
sed -i '4s/.*/f1 commit 3/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f1: commit 3"
simulate_push feature1
# Developer rebases feature2 onto latest feature1 (rewrite away the merge)
log_cmd git checkout feature2
log_cmd git rebase feature1
simulate_push feature2
# feature1 gets commit 4 — feature2 does NOT pick this up
log_cmd git checkout feature1
sed -i '5s/.*/f1 commit 4/' file.txt
log_cmd git add file.txt
log_cmd git commit -m "f1: commit 4"
simulate_push feature1
echo ""
echo "=== Graph before squash-merge ==="
log_cmd git log --graph --oneline --all
echo ""
squash_merge_feature1
run_update_pr_stack
cd "$TEST_REPO"
assert_diff_is "Scenario B: diff shows only f2's change" "$(cat <<'EOF'
-line 9
+f2 content
EOF
)"
assert_idempotent
########################################################################
echo ""
echo "All mixed-workflow tests passed! 🎉"