Accept alternate squash solution

- validate the upstream requirement of exactly two commits
- accept soft reset followed by a replacement commit
- reject resetting to one commit without creating the squashed commit
- document squash validation parity
This commit is contained in:
Joe Tretter
2026-06-08 15:12:28 -05:00
parent 06c60356e5
commit a70350000c
3 changed files with 12 additions and 4 deletions

View File

@@ -115,7 +115,7 @@ This file records the upstream Ruby setup and validation intent beside the Andro
| `cherry-pick` | Top commits are "Filled in README..." then "Added fancy branded output". | Same commit message order plus `README.md` tracked. | Equivalent. | | `cherry-pick` | Top commits are "Filled in README..." then "Added fancy branded output". | Same commit message order plus `README.md` tracked. | Equivalent. |
| `grep` | Answer is TODO count `4`. | Answer is `4`. | Equivalent. | | `grep` | Answer is TODO count `4`. | Answer is `4`. | Equivalent. |
| `rename_commit` | Parent commit message is corrected to `First commit`. | No `coommit` remains and `First commit` exists; the in-app rebase editor uses the subject text on a `reword` line as the replacement message. | Equivalent outcome with a single mobile editor step. | | `rename_commit` | Parent commit message is corrected to `First commit`. | No `coommit` remains and `First commit` exists; the in-app rebase editor uses the subject text on a `reword` line as the replacement message. | Equivalent outcome with a single mobile editor step. |
| `squash` | Commit count is two. | Commit count at most two and "Adding README" remains. | Slightly stricter on preserving the base README commit. | | `squash` | Commit count is two. | Commit count is exactly two; interactive rebase and soft-reset/recommit solutions are accepted. | Equivalent. |
| `merge_squash` | Commit count is three and all long-feature changes are included. | Squash action recorded and a commit exists. | Known gap: Android does not yet verify all squash file/content effects. | | `merge_squash` | Commit count is three and all long-feature changes are included. | Squash action recorded and a commit exists. | Known gap: Android does not yet verify all squash file/content effects. |
| `reorder` | `git log` subject order matches `Third.*Second.*First.*Initial`. | Modeled commit order becomes First, Second, Third. | Equivalent relative to Android's oldest-first commit list. | | `reorder` | `git log` subject order matches `Third.*Second.*First.*Initial`. | Modeled commit order becomes First, Second, Third. | Equivalent relative to Android's oldest-first commit list. |
| `bisect` | Answer is hash prefix `18ed2ac` after using Ruby/make fixture. | Learner can run `git bisect start`, mark `HEAD` bad and `known-good` good, run `git bisect run ./test-balance.sh`, then answer the last good commit hash. | Same bisect lesson, different fixture and final answer target to keep the Android flow clear without Ruby/make. | | `bisect` | Answer is hash prefix `18ed2ac` after using Ruby/make fixture. | Learner can run `git bisect start`, mark `HEAD` bad and `known-good` good, run `git bisect run ./test-balance.sh`, then answer the last good commit hash. | Same bisect lesson, different fixture and final answer target to keep the Android flow clear without Ruby/make. |

View File

@@ -19,8 +19,8 @@ android {
applicationId = "solutions.tretter.githugandroid" applicationId = "solutions.tretter.githugandroid"
minSdk = 26 minSdk = 26
targetSdk = 35 targetSdk = 35
versionCode = 169 versionCode = 170
versionName = "0.1.168" versionName = "0.1.169"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true

View File

@@ -28,11 +28,19 @@ internal fun squashLevel(): Level = level(
addCommit("Updating README (squash this commit into Adding README)", "README") addCommit("Updating README (squash this commit into Adding README)", "README")
true true
}, },
validator = repoPredicate { repo -> repo.commits.size <= 2 && repo.commits.any { it.message == "Adding README" } }, validator = repoPredicate { repo -> repo.commits.size == 2 },
testCases = listOf( testCases = listOf(
levelTestCase( levelTestCase(
"interactive squash", "interactive squash",
"GIT_SEQUENCE_EDITOR=\"sed -i '2,\$s/^pick /squash /'\" GIT_EDITOR=true git rebase -i HEAD~4", "GIT_SEQUENCE_EDITOR=\"sed -i '2,\$s/^pick /squash /'\" GIT_EDITOR=true git rebase -i HEAD~4",
), ),
levelTestCase(
"soft reset and recommit",
"git reset --soft HEAD~4",
"git commit -m \"New commit message\"",
),
),
negativeTestCases = listOf(
levelTestCase("reset without replacement commit", "git reset --soft HEAD~4"),
), ),
) )