From 87d6f6554ba3f5e6396e485657a23d0d50bdba1f Mon Sep 17 00:00:00 2001 From: vanphuc Date: Sat, 1 Nov 2025 00:35:13 +0800 Subject: [PATCH 01/13] Add the ff-undo exercise --- ff_undo/.gitmastery-exercise.json | 18 ++++++++++ ff_undo/README.md | 18 ++++++++++ ff_undo/__init__.py | 0 ff_undo/download.py | 36 +++++++++++++++++++ ff_undo/tests/__init__.py | 0 ff_undo/tests/test_verify.py | 42 ++++++++++++++++++++++ ff_undo/verify.py | 59 +++++++++++++++++++++++++++++++ 7 files changed, 173 insertions(+) create mode 100644 ff_undo/.gitmastery-exercise.json create mode 100644 ff_undo/README.md create mode 100644 ff_undo/__init__.py create mode 100644 ff_undo/download.py create mode 100644 ff_undo/tests/__init__.py create mode 100644 ff_undo/tests/test_verify.py create mode 100644 ff_undo/verify.py diff --git a/ff_undo/.gitmastery-exercise.json b/ff_undo/.gitmastery-exercise.json new file mode 100644 index 00000000..53fddb60 --- /dev/null +++ b/ff_undo/.gitmastery-exercise.json @@ -0,0 +1,18 @@ +{ + "exercise_name": "ff-undo", + "tags": [ + "git-branch", + "git-merge", + "git-reset" + ], + "requires_git": true, + "requires_github": false, + "base_files": {}, + "exercise_repo": { + "repo_type": "local", + "repo_name": "play-characters", + "repo_title": null, + "create_fork": null, + "init": true + } +} \ No newline at end of file diff --git a/ff_undo/README.md b/ff_undo/README.md new file mode 100644 index 00000000..2c23c957 --- /dev/null +++ b/ff_undo/README.md @@ -0,0 +1,18 @@ +# ff-undo + + + +## Task + + + +## Hints + + + diff --git a/ff_undo/__init__.py b/ff_undo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ff_undo/download.py b/ff_undo/download.py new file mode 100644 index 00000000..0f4db879 --- /dev/null +++ b/ff_undo/download.py @@ -0,0 +1,36 @@ +from exercise_utils.cli import run_command +from exercise_utils.gitmastery import create_start_tag + +__resources__ = {} + + +def setup(verbose: bool = False): + # Marks the start of setup (Git-Mastery internal logging) + create_start_tag(verbose) + + # Create initial files and commits + run_command('echo "Scientist" > rick.txt', verbose) + run_command('git add .', verbose) + run_command('git commit -m "Add Rick"', verbose) + + run_command('echo "Boy" > morty.txt', verbose) + run_command('git add .', verbose) + run_command('git commit -m "Add Morty"', verbose) + + # Create and switch to branch 'others' + run_command('git switch -c others', verbose) + run_command('echo "No job" > birdperson.txt', verbose) + run_command('git add .', verbose) + run_command('git commit -m "Add Birdperson"', verbose) + + run_command('echo "Cyborg" >> birdperson.txt', verbose) + run_command('git add .', verbose) + run_command('git commit -m "Add Cyborg to birdperson.txt"', verbose) + + run_command('echo "Spy" > tammy.txt', verbose) + run_command('git add .', verbose) + run_command('git commit -m "Add Tammy"', verbose) + + # Merge back into main + run_command('git switch main', verbose) + run_command('git merge others -m "Introduce others"', verbose) \ No newline at end of file diff --git a/ff_undo/tests/__init__.py b/ff_undo/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ff_undo/tests/test_verify.py b/ff_undo/tests/test_verify.py new file mode 100644 index 00000000..30dc7767 --- /dev/null +++ b/ff_undo/tests/test_verify.py @@ -0,0 +1,42 @@ +from git_autograder import GitAutograderTestLoader, assert_output +from git_autograder.status import GitAutograderStatus +from ..verify import ( + MERGE_NOT_UNDONE, + MAIN_COMMITS_INCORRECT, + OTHERS_COMMITS_INCORRECT, + OTHERS_BRANCH_MISSING, + verify +) + +REPOSITORY_NAME = "ff-undo" + +loader = GitAutograderTestLoader(__file__, REPOSITORY_NAME, verify) + +def test_correct_solution(): + """Main has only Rick + Morty, others still exists with Birdperson, Cyborg, Tammy""" + with loader.load("specs/base.yml") as output: + assert_output(output, GitAutograderStatus.SUCCESSFUL) + + +def test_merge_not_undone(): + """Student did not undo merge (main still contains merge commit)""" + with loader.load("specs/merge_not_undone.yml") as output: + assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MERGE_NOT_UNDONE]) + + +def test_branch_missing(): + """Student deleted 'others' branch""" + with loader.load("specs/branch_missing.yml") as output: + assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [OTHERS_BRANCH_MISSING]) + + +def test_main_commits_incorrect(): + """Student modified or removed main commits""" + with loader.load("specs/main_commits_incorrect.yml") as output: + assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MAIN_COMMITS_INCORRECT]) + + +def test_others_commits_incorrect(): + """Student changed commits on others branch""" + with loader.load("specs/others_commits_incorrect.yml") as output: + assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [OTHERS_COMMITS_INCORRECT]) diff --git a/ff_undo/verify.py b/ff_undo/verify.py new file mode 100644 index 00000000..e11bc8eb --- /dev/null +++ b/ff_undo/verify.py @@ -0,0 +1,59 @@ +from git_autograder import ( + GitAutograderOutput, + GitAutograderExercise, + GitAutograderStatus, +) + +MERGE_NOT_UNDONE = ( + "The merge commit 'Introduce others' is still present on the main branch. " + "You need to undo the merge so that only Rick and Morty remain on main." +) +MAIN_COMMITS_INCORRECT = ( + "The main branch does not contain the expected commits " + "The main branch does not contain both commits 'Add Rick' and 'Add Morty'." +) +OTHERS_COMMITS_INCORRECT = ( + "The others branch does not contain the expected commits " + "'Add Birdperson', 'Add Cyborg to birdperson.txt', and 'Add Tammy'." +) +OTHERS_BRANCH_MISSING = ( + "The branch 'others' no longer exists. You should not delete it, only undo the merge on main." +) + +def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: + + # Check if branch others exists + if not exercise.repo.branches.has_branch("others"): + raise exercise.wrong_answer([OTHERS_BRANCH_MISSING]) + + # Take all commit messages on main + commit_messages_in_main = [c.message.strip() for c in exercise.repo.repo.iter_commits("main")] + + # Take all commit messages on others + commit_messages_in_others = [c.message.strip() for c in exercise.repo.repo.iter_commits("others")] + + # Check that the merge commit is not present on main + if any("Introduce others" in msg for msg in commit_messages_in_main): + raise exercise.wrong_answer([MERGE_NOT_UNDONE]) + + # Check that commits in main are only the initial 2 commits + has_rick = any("Add Rick" in msg for msg in commit_messages_in_main) + has_morty = any("Add Morty" in msg for msg in commit_messages_in_main) + if len(commit_messages_in_main) != 2 or not (has_rick and has_morty): + raise exercise.wrong_answer([MAIN_COMMITS_INCORRECT]) + + # Check that the merge commit is not present on others + if any("Introduce others" in msg for msg in commit_messages_in_others): + raise exercise.wrong_answer([MERGE_NOT_UNDONE]) + + # Check that commits in others are only the initial 3 commits + has_birdperson = any("Add Birdperson" in msg for msg in commit_messages_in_others) + has_cyborg = any("Add Cyborg to birdperson.txt" in msg for msg in commit_messages_in_others) + has_tammy = any("Add Tammy" in msg for msg in commit_messages_in_others) + if len(commit_messages_in_others) != 3 or not (has_birdperson and has_cyborg and has_tammy): + raise exercise.wrong_answer([OTHERS_COMMITS_INCORRECT]) + + return exercise.to_output( + ["You have successfully undone the merge of branch 'others'."], + GitAutograderStatus.SUCCESSFUL, + ) From 966108ebfe445d5d422f219cae7fdfefbdec899a Mon Sep 17 00:00:00 2001 From: vanphuc Date: Sat, 1 Nov 2025 00:40:34 +0800 Subject: [PATCH 02/13] Add yml file for test_verify --- ff_undo/tests/specs/base.yml | 22 ++++++++++++++++ ff_undo/tests/specs/branch_missing.yml | 10 ++++++++ .../tests/specs/main_commits_incorrect.yml | 18 +++++++++++++ ff_undo/tests/specs/merge_not_undone.yml | 25 +++++++++++++++++++ .../tests/specs/others_commits_incorrect.yml | 19 ++++++++++++++ 5 files changed, 94 insertions(+) create mode 100644 ff_undo/tests/specs/base.yml create mode 100644 ff_undo/tests/specs/branch_missing.yml create mode 100644 ff_undo/tests/specs/main_commits_incorrect.yml create mode 100644 ff_undo/tests/specs/merge_not_undone.yml create mode 100644 ff_undo/tests/specs/others_commits_incorrect.yml diff --git a/ff_undo/tests/specs/base.yml b/ff_undo/tests/specs/base.yml new file mode 100644 index 00000000..a73079c4 --- /dev/null +++ b/ff_undo/tests/specs/base.yml @@ -0,0 +1,22 @@ +initialization: + steps: + - type: commit + id: start + empty: true + message: Empty commit + - type: commit + message: "Add Rick" + - type: commit + message: "Add Morty" + - type: branch + branch-name: others + - type: checkout + branch-name: others + - type: commit + message: "Add Birdperson" + - type: commit + message: "Add Cyborg to birdperson.txt" + - type: commit + message: "Add Tammy" + + diff --git a/ff_undo/tests/specs/branch_missing.yml b/ff_undo/tests/specs/branch_missing.yml new file mode 100644 index 00000000..8fe1a43b --- /dev/null +++ b/ff_undo/tests/specs/branch_missing.yml @@ -0,0 +1,10 @@ +initialization: + steps: + - type: commit + id: start + empty: true + message: Empty commit + - type: commit + message: "Add Rick" + - type: commit + message: "Add Morty" diff --git a/ff_undo/tests/specs/main_commits_incorrect.yml b/ff_undo/tests/specs/main_commits_incorrect.yml new file mode 100644 index 00000000..510c4abb --- /dev/null +++ b/ff_undo/tests/specs/main_commits_incorrect.yml @@ -0,0 +1,18 @@ +initialization: + steps: + - type: commit + id: start + empty: true + message: Empty commit + - type: commit + message: "Add Morty" + - type: branch + branch-name: others + - type: checkout + branch-name: others + - type: commit + message: "Add Birdperson" + - type: commit + message: "Add Cyborg to birdperson.txt" + - type: commit + message: "Add Tammy" diff --git a/ff_undo/tests/specs/merge_not_undone.yml b/ff_undo/tests/specs/merge_not_undone.yml new file mode 100644 index 00000000..e812179f --- /dev/null +++ b/ff_undo/tests/specs/merge_not_undone.yml @@ -0,0 +1,25 @@ +initialization: + steps: + - type: commit + id: start + empty: true + message: Empty commit + - type: commit + message: "Add Rick" + - type: commit + message: "Add Morty" + - type: branch + branch-name: others + - type: checkout + branch-name: others + - type: commit + message: "Add Birdperson" + - type: commit + message: "Add Cyborg to birdperson.txt" + - type: commit + message: "Add Tammy" + - type: checkout + branch-name: main + - type: merge + branch-name: others + message: "Introduce others" diff --git a/ff_undo/tests/specs/others_commits_incorrect.yml b/ff_undo/tests/specs/others_commits_incorrect.yml new file mode 100644 index 00000000..b0acc2ac --- /dev/null +++ b/ff_undo/tests/specs/others_commits_incorrect.yml @@ -0,0 +1,19 @@ +initialization: + steps: + - type: commit + id: start + empty: true + message: Empty commit + - type: commit + message: "Add Rick" + - type: commit + message: "Add Morty" + - type: branch + branch-name: others + - type: checkout + branch-name: others + - type: commit + message: "Add Birdperson" + - type: commit + message: "Add Tammy" + From dace21b646955fde5f37fe5cb7b5dff313b113e3 Mon Sep 17 00:00:00 2001 From: vanphuc Date: Sat, 1 Nov 2025 01:27:28 +0800 Subject: [PATCH 03/13] Add README file and also fix the verify to check the mistake --- ff_undo/README.md | 42 ++++++++++++++++++------ ff_undo/tests/specs/base.yml | 3 +- ff_undo/tests/specs/merge_not_undone.yml | 1 + ff_undo/tests/test_verify.py | 5 --- ff_undo/verify.py | 17 +++++----- 5 files changed, 43 insertions(+), 25 deletions(-) diff --git a/ff_undo/README.md b/ff_undo/README.md index 2c23c957..289ff6e2 100644 --- a/ff_undo/README.md +++ b/ff_undo/README.md @@ -1,18 +1,40 @@ # ff-undo - +This exercise focuses on **undoing a merge in Git**. You will practice how to revert unwanted merge commits while keeping branches and commits intact. ## Task - +You have a repository with two branches: + +- `main` branch, which initially contains commits: + - `Add Rick` + - `Add Morty` +- `others` branch, which contains commits: + - `Add Birdperson` + - `Add Cyborg to birdperson.txt` + - `Add Tammy` + +A merge with fast forward from `others` into `main` has been done incorrectly. Your task is: + +1. **Undo the merge on `main`**, so that only `Add Rick` and `Add Morty` remain on `main`. +2. Ensure the `others` branch still exists with all its commits intact. +3. Do not delete any commits; only undo the merge on `main`. ## Hints - - +
+Hint 1: Check your branches + +Use `git branch` to see the current branches and verify `main` and `others` exist. +
+ +
+Hint 2: View commit history + +Use `git log --oneline` on `main` to identify the merge commit that needs to be undone. +
+ +
+Hint 3: Undo the merge + +You can undo a merge using: `git reset --hard ` diff --git a/ff_undo/tests/specs/base.yml b/ff_undo/tests/specs/base.yml index a73079c4..b77c9fe0 100644 --- a/ff_undo/tests/specs/base.yml +++ b/ff_undo/tests/specs/base.yml @@ -18,5 +18,6 @@ initialization: message: "Add Cyborg to birdperson.txt" - type: commit message: "Add Tammy" - + - type: checkout + branch-name: main diff --git a/ff_undo/tests/specs/merge_not_undone.yml b/ff_undo/tests/specs/merge_not_undone.yml index e812179f..0a77d8a1 100644 --- a/ff_undo/tests/specs/merge_not_undone.yml +++ b/ff_undo/tests/specs/merge_not_undone.yml @@ -22,4 +22,5 @@ initialization: branch-name: main - type: merge branch-name: others + no-ff: false message: "Introduce others" diff --git a/ff_undo/tests/test_verify.py b/ff_undo/tests/test_verify.py index 30dc7767..097bd765 100644 --- a/ff_undo/tests/test_verify.py +++ b/ff_undo/tests/test_verify.py @@ -13,30 +13,25 @@ loader = GitAutograderTestLoader(__file__, REPOSITORY_NAME, verify) def test_correct_solution(): - """Main has only Rick + Morty, others still exists with Birdperson, Cyborg, Tammy""" with loader.load("specs/base.yml") as output: assert_output(output, GitAutograderStatus.SUCCESSFUL) def test_merge_not_undone(): - """Student did not undo merge (main still contains merge commit)""" with loader.load("specs/merge_not_undone.yml") as output: assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MERGE_NOT_UNDONE]) def test_branch_missing(): - """Student deleted 'others' branch""" with loader.load("specs/branch_missing.yml") as output: assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [OTHERS_BRANCH_MISSING]) def test_main_commits_incorrect(): - """Student modified or removed main commits""" with loader.load("specs/main_commits_incorrect.yml") as output: assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MAIN_COMMITS_INCORRECT]) def test_others_commits_incorrect(): - """Student changed commits on others branch""" with loader.load("specs/others_commits_incorrect.yml") as output: assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [OTHERS_COMMITS_INCORRECT]) diff --git a/ff_undo/verify.py b/ff_undo/verify.py index e11bc8eb..a5baec91 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -5,8 +5,8 @@ ) MERGE_NOT_UNDONE = ( - "The merge commit 'Introduce others' is still present on the main branch. " - "You need to undo the merge so that only Rick and Morty remain on main." + "The merge commit 'Introduce others' is still present. " + "You need to undo the merge." ) MAIN_COMMITS_INCORRECT = ( "The main branch does not contain the expected commits " @@ -33,24 +33,23 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: commit_messages_in_others = [c.message.strip() for c in exercise.repo.repo.iter_commits("others")] # Check that the merge commit is not present on main - if any("Introduce others" in msg for msg in commit_messages_in_main): + has_birdperson_in_main = any("Add Birdperson" in msg for msg in commit_messages_in_main) + has_cyborg_in_main = any("Add Cyborg to birdperson.txt" in msg for msg in commit_messages_in_main) + has_tammy_in_main = any("Add Tammy" in msg for msg in commit_messages_in_main) + if has_birdperson_in_main or has_birdperson_in_main or has_tammy_in_main: raise exercise.wrong_answer([MERGE_NOT_UNDONE]) # Check that commits in main are only the initial 2 commits has_rick = any("Add Rick" in msg for msg in commit_messages_in_main) has_morty = any("Add Morty" in msg for msg in commit_messages_in_main) - if len(commit_messages_in_main) != 2 or not (has_rick and has_morty): + if len(commit_messages_in_main) != 3 or not (has_rick and has_morty): raise exercise.wrong_answer([MAIN_COMMITS_INCORRECT]) - # Check that the merge commit is not present on others - if any("Introduce others" in msg for msg in commit_messages_in_others): - raise exercise.wrong_answer([MERGE_NOT_UNDONE]) - # Check that commits in others are only the initial 3 commits has_birdperson = any("Add Birdperson" in msg for msg in commit_messages_in_others) has_cyborg = any("Add Cyborg to birdperson.txt" in msg for msg in commit_messages_in_others) has_tammy = any("Add Tammy" in msg for msg in commit_messages_in_others) - if len(commit_messages_in_others) != 3 or not (has_birdperson and has_cyborg and has_tammy): + if len(commit_messages_in_others) != 6 or not (has_birdperson and has_cyborg and has_tammy): raise exercise.wrong_answer([OTHERS_COMMITS_INCORRECT]) return exercise.to_output( From 7abe28c5836d626a6e778d5a89c6a9f9a2d63041 Mon Sep 17 00:00:00 2001 From: vanphuc Date: Sat, 1 Nov 2025 09:28:53 +0800 Subject: [PATCH 04/13] Change the notification for not undo merge --- ff_undo/verify.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ff_undo/verify.py b/ff_undo/verify.py index a5baec91..42faac86 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -5,7 +5,6 @@ ) MERGE_NOT_UNDONE = ( - "The merge commit 'Introduce others' is still present. " "You need to undo the merge." ) MAIN_COMMITS_INCORRECT = ( From fe2f02def987df5d7c07781b0d377d389611a6ac Mon Sep 17 00:00:00 2001 From: vanphuc Date: Wed, 12 Nov 2025 11:29:34 +0800 Subject: [PATCH 05/13] Final ver --- .DS_Store | Bin 0 -> 10244 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7d13c4a0c0d7640007dde7c6e6a8382050b59b58 GIT binary patch literal 10244 zcmeHMU2hvj6uq06dYv?`D}q!B5G(P*Lt>JqRf%|U^YKs#c&HIP05a=(w9MIoO@ZEV8q<(E)Wel4jseGjW56-s7;p?+M+UHFbMaTTb!W$b zW56*mXMpF200-MvZl~JH)Pa+10bnb5ECtut2M8v}Z7a7^Z3T)t_3pvTpPa_IU3l{Vdx)d?hZI~9tx}g1r8GhR0_$|GW0FnzXYp8;|zF;WvEurBX?Eb{%%Vila%VvA(a; zER54=D1f*Z!R6bpoo41pYPn=2zDN9Uu*>D+xI@%+6eAH z*txi<`R{!A@u!bFC&|-Py+A)uynM2yHGMxnGpnV1oVJH)qEhC8vA4k)>*5H^#iFJT zlolb!vFJ^amFcBlfhsENJ)oFtt-tXjAH957sK`qcdtEGiPRImiMiC z>kBn?@a>A#p3um`{=9%a0y;yBtXkG@4|V{2LWzm3d|+X#;Nl40V?kN^;V8Z5g>hAb zFZb!>GR0M1S@k!l4}XQ&n58q|Mu<`&x&iu@Qs0bEM)Hq^7JYc@9*uxS?ks;E!$tqM zQEMOda+FfPw5TM@8S2u{EJkHK7i+1~XY`2n>5#slHXWL6daO3no7I#GD^Qc=&EvM{ zy(Xi!kGN);;#hgcu(ijkEh6jaMGU=Z&5pn%^Vt)2tsaSPi`ZMGSk6s|OdOjri#kno ziufi_x2^XwZL>bh(XVs4$+;{W8KTf4`Ud>C?ItV7j8oKB^t~mSf1PKZ`4u?gyn|sA z&06#71+CR&%&b*!3wdo+_B_EWhklhqaa}TS}sHY(qRsydA3Ytx2tcSQO87HE@=LP*; zjbBi|sIiEzU(tTa{9w%NS7QI`H-zoojo{whUHyizyTdp4|Hd1_m3_3{6smJBOVlc3 zy2$)mzJ9V|I#4RlZKdOi*A9dCccHKlDq*c({!TG_YhgW?D9OVbW7Jy7b$e=#7#Y>Y zxG_3DCt*s~9smFU literal 0 HcmV?d00001 From f627ddc66156ab3beb7a674c3aa656bccc793d11 Mon Sep 17 00:00:00 2001 From: vanphuc Date: Thu, 20 Nov 2025 21:29:42 +0800 Subject: [PATCH 06/13] Use the git cli command instead of run command --- ff_undo/README.md | 1 + ff_undo/download.py | 55 ++++++++++--------- ff_undo/tests/specs/base.yml | 3 +- ff_undo/tests/specs/branch_missing.yml | 2 +- .../tests/specs/main_commits_incorrect.yml | 2 +- ff_undo/tests/specs/merge_not_undone.yml | 2 +- .../tests/specs/others_commits_incorrect.yml | 1 - ff_undo/verify.py | 33 ++++++----- 8 files changed, 53 insertions(+), 46 deletions(-) diff --git a/ff_undo/README.md b/ff_undo/README.md index 289ff6e2..3eabfbc9 100644 --- a/ff_undo/README.md +++ b/ff_undo/README.md @@ -38,3 +38,4 @@ Use `git log --oneline` on `main` to identify the merge commit that needs to be Hint 3: Undo the merge You can undo a merge using: `git reset --hard ` +
\ No newline at end of file diff --git a/ff_undo/download.py b/ff_undo/download.py index 0f4db879..686c15b0 100644 --- a/ff_undo/download.py +++ b/ff_undo/download.py @@ -1,36 +1,39 @@ -from exercise_utils.cli import run_command -from exercise_utils.gitmastery import create_start_tag - -__resources__ = {} - +from exercise_utils.git import ( + add, + commit, + checkout, + merge_with_message, +) +from exercise_utils.file import ( + create_or_update_file, + append_to_file, +) def setup(verbose: bool = False): - # Marks the start of setup (Git-Mastery internal logging) - create_start_tag(verbose) - # Create initial files and commits - run_command('echo "Scientist" > rick.txt', verbose) - run_command('git add .', verbose) - run_command('git commit -m "Add Rick"', verbose) + create_or_update_file("rick.txt", "Scientist\n") + add(["rick.txt"], verbose) + commit("Add Rick", verbose) - run_command('echo "Boy" > morty.txt', verbose) - run_command('git add .', verbose) - run_command('git commit -m "Add Morty"', verbose) + create_or_update_file("morty.txt", "Boy\n") + add(["morty.txt"], verbose) + commit("Add Morty", verbose) # Create and switch to branch 'others' - run_command('git switch -c others', verbose) - run_command('echo "No job" > birdperson.txt', verbose) - run_command('git add .', verbose) - run_command('git commit -m "Add Birdperson"', verbose) + checkout("others", create_branch=True, verbose=verbose) + + create_or_update_file("birdperson.txt", "No job\n") + add(["birdperson.txt"], verbose) + commit("Add Birdperson", verbose) - run_command('echo "Cyborg" >> birdperson.txt', verbose) - run_command('git add .', verbose) - run_command('git commit -m "Add Cyborg to birdperson.txt"', verbose) + append_to_file("birdperson.txt", "Cyborg\n") + add(["birdperson.txt"], verbose) + commit("Add Cyborg to birdperson.txt", verbose) - run_command('echo "Spy" > tammy.txt', verbose) - run_command('git add .', verbose) - run_command('git commit -m "Add Tammy"', verbose) + create_or_update_file("tammy.txt", "Spy\n") + add(["tammy.txt"], verbose) + commit("Add Tammy", verbose) # Merge back into main - run_command('git switch main', verbose) - run_command('git merge others -m "Introduce others"', verbose) \ No newline at end of file + checkout("main", create_branch=False, verbose=verbose) + merge_with_message("others", ff=True, message="Introduce others", verbose=verbose) \ No newline at end of file diff --git a/ff_undo/tests/specs/base.yml b/ff_undo/tests/specs/base.yml index b77c9fe0..afff1b0d 100644 --- a/ff_undo/tests/specs/base.yml +++ b/ff_undo/tests/specs/base.yml @@ -19,5 +19,4 @@ initialization: - type: commit message: "Add Tammy" - type: checkout - branch-name: main - + branch-name: main \ No newline at end of file diff --git a/ff_undo/tests/specs/branch_missing.yml b/ff_undo/tests/specs/branch_missing.yml index 8fe1a43b..4d666dc3 100644 --- a/ff_undo/tests/specs/branch_missing.yml +++ b/ff_undo/tests/specs/branch_missing.yml @@ -7,4 +7,4 @@ initialization: - type: commit message: "Add Rick" - type: commit - message: "Add Morty" + message: "Add Morty" \ No newline at end of file diff --git a/ff_undo/tests/specs/main_commits_incorrect.yml b/ff_undo/tests/specs/main_commits_incorrect.yml index 510c4abb..aedd28c9 100644 --- a/ff_undo/tests/specs/main_commits_incorrect.yml +++ b/ff_undo/tests/specs/main_commits_incorrect.yml @@ -15,4 +15,4 @@ initialization: - type: commit message: "Add Cyborg to birdperson.txt" - type: commit - message: "Add Tammy" + message: "Add Tammy" \ No newline at end of file diff --git a/ff_undo/tests/specs/merge_not_undone.yml b/ff_undo/tests/specs/merge_not_undone.yml index 0a77d8a1..85ee3e3d 100644 --- a/ff_undo/tests/specs/merge_not_undone.yml +++ b/ff_undo/tests/specs/merge_not_undone.yml @@ -23,4 +23,4 @@ initialization: - type: merge branch-name: others no-ff: false - message: "Introduce others" + message: "Introduce others" \ No newline at end of file diff --git a/ff_undo/tests/specs/others_commits_incorrect.yml b/ff_undo/tests/specs/others_commits_incorrect.yml index b0acc2ac..60cd4b98 100644 --- a/ff_undo/tests/specs/others_commits_incorrect.yml +++ b/ff_undo/tests/specs/others_commits_incorrect.yml @@ -16,4 +16,3 @@ initialization: message: "Add Birdperson" - type: commit message: "Add Tammy" - diff --git a/ff_undo/verify.py b/ff_undo/verify.py index 42faac86..fe568a84 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -4,6 +4,12 @@ GitAutograderStatus, ) +ADD_RICK = "Add Rick" +ADD_MORTY = "Add Morty" +ADD_BIRDPERSON = "Add Birdperson" +ADD_CYBORG = "Add Cyborg to birdperson.txt" +ADD_TAMMY = "Add Tammy" + MERGE_NOT_UNDONE = ( "You need to undo the merge." ) @@ -20,35 +26,34 @@ ) def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: + # Get branches + main_branch = exercise.repo.branches.branch("main") + others_branch = exercise.repo.branches.branch_or_none("others") # Check if branch others exists - if not exercise.repo.branches.has_branch("others"): + if others_branch is None: raise exercise.wrong_answer([OTHERS_BRANCH_MISSING]) # Take all commit messages on main - commit_messages_in_main = [c.message.strip() for c in exercise.repo.repo.iter_commits("main")] + commit_messages_in_main = [c.commit.message.strip() for c in main_branch.commits] # Take all commit messages on others - commit_messages_in_others = [c.message.strip() for c in exercise.repo.repo.iter_commits("others")] + commit_messages_in_others = [c.commit.message.strip() for c in others_branch.commits] # Check that the merge commit is not present on main - has_birdperson_in_main = any("Add Birdperson" in msg for msg in commit_messages_in_main) - has_cyborg_in_main = any("Add Cyborg to birdperson.txt" in msg for msg in commit_messages_in_main) - has_tammy_in_main = any("Add Tammy" in msg for msg in commit_messages_in_main) - if has_birdperson_in_main or has_birdperson_in_main or has_tammy_in_main: + if any(msg in commit_messages_in_main for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY]): raise exercise.wrong_answer([MERGE_NOT_UNDONE]) # Check that commits in main are only the initial 2 commits - has_rick = any("Add Rick" in msg for msg in commit_messages_in_main) - has_morty = any("Add Morty" in msg for msg in commit_messages_in_main) - if len(commit_messages_in_main) != 3 or not (has_rick and has_morty): + if len(commit_messages_in_main) != 3 or not all( + msg in commit_messages_in_main for msg in [ADD_RICK, ADD_MORTY] + ): raise exercise.wrong_answer([MAIN_COMMITS_INCORRECT]) # Check that commits in others are only the initial 3 commits - has_birdperson = any("Add Birdperson" in msg for msg in commit_messages_in_others) - has_cyborg = any("Add Cyborg to birdperson.txt" in msg for msg in commit_messages_in_others) - has_tammy = any("Add Tammy" in msg for msg in commit_messages_in_others) - if len(commit_messages_in_others) != 6 or not (has_birdperson and has_cyborg and has_tammy): + if len(commit_messages_in_others) != 6 or not all( + msg in commit_messages_in_others for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY] + ): raise exercise.wrong_answer([OTHERS_COMMITS_INCORRECT]) return exercise.to_output( From 66b21317d3b08b250a9b095f67b6b17276012f37 Mon Sep 17 00:00:00 2001 From: vanphuc Date: Thu, 20 Nov 2025 21:33:41 +0800 Subject: [PATCH 07/13] Fix the test cases --- ff_undo/tests/specs/base.yml | 3 --- ff_undo/tests/specs/branch_missing.yml | 3 --- ff_undo/tests/specs/main_commits_incorrect.yml | 3 --- ff_undo/tests/specs/merge_not_undone.yml | 3 --- ff_undo/tests/specs/others_commits_incorrect.yml | 3 --- ff_undo/verify.py | 4 ++-- 6 files changed, 2 insertions(+), 17 deletions(-) diff --git a/ff_undo/tests/specs/base.yml b/ff_undo/tests/specs/base.yml index afff1b0d..23847dfe 100644 --- a/ff_undo/tests/specs/base.yml +++ b/ff_undo/tests/specs/base.yml @@ -2,9 +2,6 @@ initialization: steps: - type: commit id: start - empty: true - message: Empty commit - - type: commit message: "Add Rick" - type: commit message: "Add Morty" diff --git a/ff_undo/tests/specs/branch_missing.yml b/ff_undo/tests/specs/branch_missing.yml index 4d666dc3..dcc9aaa2 100644 --- a/ff_undo/tests/specs/branch_missing.yml +++ b/ff_undo/tests/specs/branch_missing.yml @@ -2,9 +2,6 @@ initialization: steps: - type: commit id: start - empty: true - message: Empty commit - - type: commit message: "Add Rick" - type: commit message: "Add Morty" \ No newline at end of file diff --git a/ff_undo/tests/specs/main_commits_incorrect.yml b/ff_undo/tests/specs/main_commits_incorrect.yml index aedd28c9..0a6e3993 100644 --- a/ff_undo/tests/specs/main_commits_incorrect.yml +++ b/ff_undo/tests/specs/main_commits_incorrect.yml @@ -2,9 +2,6 @@ initialization: steps: - type: commit id: start - empty: true - message: Empty commit - - type: commit message: "Add Morty" - type: branch branch-name: others diff --git a/ff_undo/tests/specs/merge_not_undone.yml b/ff_undo/tests/specs/merge_not_undone.yml index 85ee3e3d..3778fe42 100644 --- a/ff_undo/tests/specs/merge_not_undone.yml +++ b/ff_undo/tests/specs/merge_not_undone.yml @@ -2,9 +2,6 @@ initialization: steps: - type: commit id: start - empty: true - message: Empty commit - - type: commit message: "Add Rick" - type: commit message: "Add Morty" diff --git a/ff_undo/tests/specs/others_commits_incorrect.yml b/ff_undo/tests/specs/others_commits_incorrect.yml index 60cd4b98..59fa6c66 100644 --- a/ff_undo/tests/specs/others_commits_incorrect.yml +++ b/ff_undo/tests/specs/others_commits_incorrect.yml @@ -2,9 +2,6 @@ initialization: steps: - type: commit id: start - empty: true - message: Empty commit - - type: commit message: "Add Rick" - type: commit message: "Add Morty" diff --git a/ff_undo/verify.py b/ff_undo/verify.py index fe568a84..83c73f8f 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -45,13 +45,13 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: raise exercise.wrong_answer([MERGE_NOT_UNDONE]) # Check that commits in main are only the initial 2 commits - if len(commit_messages_in_main) != 3 or not all( + if len(commit_messages_in_main) != 2 or not all( msg in commit_messages_in_main for msg in [ADD_RICK, ADD_MORTY] ): raise exercise.wrong_answer([MAIN_COMMITS_INCORRECT]) # Check that commits in others are only the initial 3 commits - if len(commit_messages_in_others) != 6 or not all( + if len(commit_messages_in_others) != 5 or not all( msg in commit_messages_in_others for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY] ): raise exercise.wrong_answer([OTHERS_COMMITS_INCORRECT]) From 5504d3f12a0d56a17483ffc93184ba72c29c25ca Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Tue, 16 Dec 2025 10:47:30 +0800 Subject: [PATCH 08/13] [ff-unfo] Update README --- ff_undo/README.md | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/ff_undo/README.md b/ff_undo/README.md index 3eabfbc9..05f96661 100644 --- a/ff_undo/README.md +++ b/ff_undo/README.md @@ -1,41 +1 @@ -# ff-undo - -This exercise focuses on **undoing a merge in Git**. You will practice how to revert unwanted merge commits while keeping branches and commits intact. - -## Task - -You have a repository with two branches: - -- `main` branch, which initially contains commits: - - `Add Rick` - - `Add Morty` -- `others` branch, which contains commits: - - `Add Birdperson` - - `Add Cyborg to birdperson.txt` - - `Add Tammy` - -A merge with fast forward from `others` into `main` has been done incorrectly. Your task is: - -1. **Undo the merge on `main`**, so that only `Add Rick` and `Add Morty` remain on `main`. -2. Ensure the `others` branch still exists with all its commits intact. -3. Do not delete any commits; only undo the merge on `main`. - -## Hints - -
-Hint 1: Check your branches - -Use `git branch` to see the current branches and verify `main` and `others` exist. -
- -
-Hint 2: View commit history - -Use `git log --oneline` on `main` to identify the merge commit that needs to be undone. -
- -
-Hint 3: Undo the merge - -You can undo a merge using: `git reset --hard ` -
\ No newline at end of file +See https://git-mastery.github.io/lessons/merge/exercise-ff-undo.html From f225878e0cc17d2d6083e4f8007d72b33e2ec647 Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Tue, 16 Dec 2025 10:53:56 +0800 Subject: [PATCH 09/13] [ff-unfo] Run ruff format and clean up download.py --- ff_undo/download.py | 55 +++++++++++++++++++++++++----------- ff_undo/tests/test_verify.py | 13 ++++++--- ff_undo/verify.py | 28 ++++++++---------- 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/ff_undo/download.py b/ff_undo/download.py index 686c15b0..2182c0f5 100644 --- a/ff_undo/download.py +++ b/ff_undo/download.py @@ -9,31 +9,54 @@ append_to_file, ) + def setup(verbose: bool = False): - # Create initial files and commits - create_or_update_file("rick.txt", "Scientist\n") - add(["rick.txt"], verbose) + create_or_update_file( + "rick.txt", + """ + Hero + """, + ) + add(["."], verbose) commit("Add Rick", verbose) - create_or_update_file("morty.txt", "Boy\n") - add(["morty.txt"], verbose) + create_or_update_file( + "morty.txt", + """ + Boy + """, + ) + add(["."], verbose) commit("Add Morty", verbose) - # Create and switch to branch 'others' - checkout("others", create_branch=True, verbose=verbose) + checkout("others", True, verbose) - create_or_update_file("birdperson.txt", "No job\n") - add(["birdperson.txt"], verbose) + create_or_update_file( + "birdperson.txt", + """ + No job + """, + ) + add(["."], verbose) commit("Add Birdperson", verbose) - append_to_file("birdperson.txt", "Cyborg\n") - add(["birdperson.txt"], verbose) + append_to_file( + "birdperson.txt", + """ + Cyborg + """, + ) + add(["."], verbose) commit("Add Cyborg to birdperson.txt", verbose) - create_or_update_file("tammy.txt", "Spy\n") - add(["tammy.txt"], verbose) + create_or_update_file( + "tammy.txt", + """ + Spy + """, + ) + add(["."], verbose) commit("Add Tammy", verbose) - # Merge back into main - checkout("main", create_branch=False, verbose=verbose) - merge_with_message("others", ff=True, message="Introduce others", verbose=verbose) \ No newline at end of file + checkout("main", False, verbose) + merge_with_message("others", True, "Introduce others", verbose) diff --git a/ff_undo/tests/test_verify.py b/ff_undo/tests/test_verify.py index 097bd765..ca482f92 100644 --- a/ff_undo/tests/test_verify.py +++ b/ff_undo/tests/test_verify.py @@ -1,17 +1,18 @@ from git_autograder import GitAutograderTestLoader, assert_output from git_autograder.status import GitAutograderStatus -from ..verify import ( +from ..verify import ( MERGE_NOT_UNDONE, MAIN_COMMITS_INCORRECT, OTHERS_COMMITS_INCORRECT, OTHERS_BRANCH_MISSING, - verify + verify, ) REPOSITORY_NAME = "ff-undo" loader = GitAutograderTestLoader(__file__, REPOSITORY_NAME, verify) + def test_correct_solution(): with loader.load("specs/base.yml") as output: assert_output(output, GitAutograderStatus.SUCCESSFUL) @@ -29,9 +30,13 @@ def test_branch_missing(): def test_main_commits_incorrect(): with loader.load("specs/main_commits_incorrect.yml") as output: - assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MAIN_COMMITS_INCORRECT]) + assert_output( + output, GitAutograderStatus.UNSUCCESSFUL, [MAIN_COMMITS_INCORRECT] + ) def test_others_commits_incorrect(): with loader.load("specs/others_commits_incorrect.yml") as output: - assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [OTHERS_COMMITS_INCORRECT]) + assert_output( + output, GitAutograderStatus.UNSUCCESSFUL, [OTHERS_COMMITS_INCORRECT] + ) diff --git a/ff_undo/verify.py b/ff_undo/verify.py index 83c73f8f..3e390f8d 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -10,9 +10,7 @@ ADD_CYBORG = "Add Cyborg to birdperson.txt" ADD_TAMMY = "Add Tammy" -MERGE_NOT_UNDONE = ( - "You need to undo the merge." -) +MERGE_NOT_UNDONE = "You need to undo the merge." MAIN_COMMITS_INCORRECT = ( "The main branch does not contain the expected commits " "The main branch does not contain both commits 'Add Rick' and 'Add Morty'." @@ -21,38 +19,36 @@ "The others branch does not contain the expected commits " "'Add Birdperson', 'Add Cyborg to birdperson.txt', and 'Add Tammy'." ) -OTHERS_BRANCH_MISSING = ( - "The branch 'others' no longer exists. You should not delete it, only undo the merge on main." -) +OTHERS_BRANCH_MISSING = "The branch 'others' no longer exists. You should not delete it, only undo the merge on main." + def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: - # Get branches main_branch = exercise.repo.branches.branch("main") others_branch = exercise.repo.branches.branch_or_none("others") - # Check if branch others exists if others_branch is None: raise exercise.wrong_answer([OTHERS_BRANCH_MISSING]) - # Take all commit messages on main commit_messages_in_main = [c.commit.message.strip() for c in main_branch.commits] - # Take all commit messages on others - commit_messages_in_others = [c.commit.message.strip() for c in others_branch.commits] + commit_messages_in_others = [ + c.commit.message.strip() for c in others_branch.commits + ] - # Check that the merge commit is not present on main - if any(msg in commit_messages_in_main for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY]): + if any( + msg in commit_messages_in_main + for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY] + ): raise exercise.wrong_answer([MERGE_NOT_UNDONE]) - # Check that commits in main are only the initial 2 commits if len(commit_messages_in_main) != 2 or not all( msg in commit_messages_in_main for msg in [ADD_RICK, ADD_MORTY] ): raise exercise.wrong_answer([MAIN_COMMITS_INCORRECT]) - # Check that commits in others are only the initial 3 commits if len(commit_messages_in_others) != 5 or not all( - msg in commit_messages_in_others for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY] + msg in commit_messages_in_others + for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY] ): raise exercise.wrong_answer([OTHERS_COMMITS_INCORRECT]) From 139a3c289550ac51a2d5fa9b03ad2e4f0092cc63 Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Tue, 16 Dec 2025 11:10:35 +0800 Subject: [PATCH 10/13] [ff-undo] Update verify to include initial commit --- ff_undo/download.py | 4 ++-- ff_undo/tests/specs/base.yml | 3 +++ ff_undo/tests/specs/branch_missing.yml | 3 +++ ff_undo/tests/specs/main_commits_incorrect.yml | 3 +++ ff_undo/tests/specs/merge_not_undone.yml | 3 +++ ff_undo/tests/specs/others_commits_incorrect.yml | 3 +++ ff_undo/verify.py | 6 +++--- 7 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ff_undo/download.py b/ff_undo/download.py index 2182c0f5..0ad7ac5d 100644 --- a/ff_undo/download.py +++ b/ff_undo/download.py @@ -2,7 +2,7 @@ add, commit, checkout, - merge_with_message, + merge, ) from exercise_utils.file import ( create_or_update_file, @@ -59,4 +59,4 @@ def setup(verbose: bool = False): commit("Add Tammy", verbose) checkout("main", False, verbose) - merge_with_message("others", True, "Introduce others", verbose) + merge("others", True, verbose) diff --git a/ff_undo/tests/specs/base.yml b/ff_undo/tests/specs/base.yml index 23847dfe..8bcd19b2 100644 --- a/ff_undo/tests/specs/base.yml +++ b/ff_undo/tests/specs/base.yml @@ -1,7 +1,10 @@ initialization: steps: - type: commit + empty: true + message: Set initial state id: start + - type: commit message: "Add Rick" - type: commit message: "Add Morty" diff --git a/ff_undo/tests/specs/branch_missing.yml b/ff_undo/tests/specs/branch_missing.yml index dcc9aaa2..c87c529a 100644 --- a/ff_undo/tests/specs/branch_missing.yml +++ b/ff_undo/tests/specs/branch_missing.yml @@ -1,7 +1,10 @@ initialization: steps: - type: commit + empty: true + message: Set initial state id: start + - type: commit message: "Add Rick" - type: commit message: "Add Morty" \ No newline at end of file diff --git a/ff_undo/tests/specs/main_commits_incorrect.yml b/ff_undo/tests/specs/main_commits_incorrect.yml index 0a6e3993..0e63c2af 100644 --- a/ff_undo/tests/specs/main_commits_incorrect.yml +++ b/ff_undo/tests/specs/main_commits_incorrect.yml @@ -1,7 +1,10 @@ initialization: steps: - type: commit + empty: true + message: Set initial state id: start + - type: commit message: "Add Morty" - type: branch branch-name: others diff --git a/ff_undo/tests/specs/merge_not_undone.yml b/ff_undo/tests/specs/merge_not_undone.yml index 3778fe42..1450b793 100644 --- a/ff_undo/tests/specs/merge_not_undone.yml +++ b/ff_undo/tests/specs/merge_not_undone.yml @@ -1,7 +1,10 @@ initialization: steps: - type: commit + empty: true + message: Set initial state id: start + - type: commit message: "Add Rick" - type: commit message: "Add Morty" diff --git a/ff_undo/tests/specs/others_commits_incorrect.yml b/ff_undo/tests/specs/others_commits_incorrect.yml index 59fa6c66..eefe189a 100644 --- a/ff_undo/tests/specs/others_commits_incorrect.yml +++ b/ff_undo/tests/specs/others_commits_incorrect.yml @@ -1,7 +1,10 @@ initialization: steps: - type: commit + empty: true + message: Set initial state id: start + - type: commit message: "Add Rick" - type: commit message: "Add Morty" diff --git a/ff_undo/verify.py b/ff_undo/verify.py index 3e390f8d..4d282fdc 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -41,14 +41,14 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: ): raise exercise.wrong_answer([MERGE_NOT_UNDONE]) - if len(commit_messages_in_main) != 2 or not all( + if len(commit_messages_in_main) != 3 or not all( msg in commit_messages_in_main for msg in [ADD_RICK, ADD_MORTY] ): raise exercise.wrong_answer([MAIN_COMMITS_INCORRECT]) - if len(commit_messages_in_others) != 5 or not all( + if len(commit_messages_in_others) != 6 or not all( msg in commit_messages_in_others - for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY] + for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY, ADD_RICK, ADD_MORTY] ): raise exercise.wrong_answer([OTHERS_COMMITS_INCORRECT]) From 03f4a4acbb08ec0c54965bb1d052e7daf91caed0 Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Tue, 16 Dec 2025 11:14:58 +0800 Subject: [PATCH 11/13] [ff-undo] Clean up code for verify.py --- ff_undo/verify.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ff_undo/verify.py b/ff_undo/verify.py index 4d282fdc..cb9dfd53 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -29,12 +29,8 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: if others_branch is None: raise exercise.wrong_answer([OTHERS_BRANCH_MISSING]) + # Verify commits in main branch commit_messages_in_main = [c.commit.message.strip() for c in main_branch.commits] - - commit_messages_in_others = [ - c.commit.message.strip() for c in others_branch.commits - ] - if any( msg in commit_messages_in_main for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY] @@ -46,6 +42,10 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: ): raise exercise.wrong_answer([MAIN_COMMITS_INCORRECT]) + # Verify commits in others branch + commit_messages_in_others = [ + c.commit.message.strip() for c in others_branch.commits + ] if len(commit_messages_in_others) != 6 or not all( msg in commit_messages_in_others for msg in [ADD_BIRDPERSON, ADD_CYBORG, ADD_TAMMY, ADD_RICK, ADD_MORTY] From d2a7aa31ed69ac711596ac8e97d8770f600e3a4d Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Tue, 16 Dec 2025 11:17:48 +0800 Subject: [PATCH 12/13] [ff-undo] Remove .DS_Store file --- .DS_Store | Bin 10244 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 7d13c4a0c0d7640007dde7c6e6a8382050b59b58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHMU2hvj6uq06dYv?`D}q!B5G(P*Lt>JqRf%|U^YKs#c&HIP05a=(w9MIoO@ZEV8q<(E)Wel4jseGjW56-s7;p?+M+UHFbMaTTb!W$b zW56*mXMpF200-MvZl~JH)Pa+10bnb5ECtut2M8v}Z7a7^Z3T)t_3pvTpPa_IU3l{Vdx)d?hZI~9tx}g1r8GhR0_$|GW0FnzXYp8;|zF;WvEurBX?Eb{%%Vila%VvA(a; zER54=D1f*Z!R6bpoo41pYPn=2zDN9Uu*>D+xI@%+6eAH z*txi<`R{!A@u!bFC&|-Py+A)uynM2yHGMxnGpnV1oVJH)qEhC8vA4k)>*5H^#iFJT zlolb!vFJ^amFcBlfhsENJ)oFtt-tXjAH957sK`qcdtEGiPRImiMiC z>kBn?@a>A#p3um`{=9%a0y;yBtXkG@4|V{2LWzm3d|+X#;Nl40V?kN^;V8Z5g>hAb zFZb!>GR0M1S@k!l4}XQ&n58q|Mu<`&x&iu@Qs0bEM)Hq^7JYc@9*uxS?ks;E!$tqM zQEMOda+FfPw5TM@8S2u{EJkHK7i+1~XY`2n>5#slHXWL6daO3no7I#GD^Qc=&EvM{ zy(Xi!kGN);;#hgcu(ijkEh6jaMGU=Z&5pn%^Vt)2tsaSPi`ZMGSk6s|OdOjri#kno ziufi_x2^XwZL>bh(XVs4$+;{W8KTf4`Ud>C?ItV7j8oKB^t~mSf1PKZ`4u?gyn|sA z&06#71+CR&%&b*!3wdo+_B_EWhklhqaa}TS}sHY(qRsydA3Ytx2tcSQO87HE@=LP*; zjbBi|sIiEzU(tTa{9w%NS7QI`H-zoojo{whUHyizyTdp4|Hd1_m3_3{6smJBOVlc3 zy2$)mzJ9V|I#4RlZKdOi*A9dCccHKlDq*c({!TG_YhgW?D9OVbW7Jy7b$e=#7#Y>Y zxG_3DCt*s~9smFU From 09d7cd3d1e6d5c30f9b19a021fa27cf2040e3a59 Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Tue, 16 Dec 2025 12:43:20 +0800 Subject: [PATCH 13/13] [ff-undo] Update error messages --- ff_undo/verify.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/ff_undo/verify.py b/ff_undo/verify.py index cb9dfd53..9870dc6a 100644 --- a/ff_undo/verify.py +++ b/ff_undo/verify.py @@ -10,16 +10,10 @@ ADD_CYBORG = "Add Cyborg to birdperson.txt" ADD_TAMMY = "Add Tammy" -MERGE_NOT_UNDONE = "You need to undo the merge." -MAIN_COMMITS_INCORRECT = ( - "The main branch does not contain the expected commits " - "The main branch does not contain both commits 'Add Rick' and 'Add Morty'." -) -OTHERS_COMMITS_INCORRECT = ( - "The others branch does not contain the expected commits " - "'Add Birdperson', 'Add Cyborg to birdperson.txt', and 'Add Tammy'." -) -OTHERS_BRANCH_MISSING = "The branch 'others' no longer exists. You should not delete it, only undo the merge on main." +MERGE_NOT_UNDONE = "The merge has not been undone properly." +MAIN_COMMITS_INCORRECT = "The main branch does not contain the expected commits." +OTHERS_COMMITS_INCORRECT = "The others branch does not contain the expected commits." +OTHERS_BRANCH_MISSING = "Missing branch 'others'." def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: