From d4309ea9a4e420885e9859a2da921f639c18de4b Mon Sep 17 00:00:00 2001 From: desmondwong1215 Date: Sun, 8 Feb 2026 22:31:01 +0800 Subject: [PATCH 1/4] Improve verify logic --- glossary_branch_rename/verify.py | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/glossary_branch_rename/verify.py b/glossary_branch_rename/verify.py index 23f0ac8e..9a4f1985 100644 --- a/glossary_branch_rename/verify.py +++ b/glossary_branch_rename/verify.py @@ -1,3 +1,4 @@ +import re from git_autograder import ( GitAutograderOutput, GitAutograderExercise, @@ -11,6 +12,35 @@ RENAMED_LOCAL_MISSING = f"Local branch {RENAMED_BRANCH} is missing." STU_REMOTE_PRESENT = f"Remote branch {STU_BRANCH} still exists." RENAMED_REMOTE_MISSING = f"Remote branch {RENAMED_BRANCH} is missing." +NO_RENAME_EVIDENCE = f"Local branch '{STU_BRANCH}' was not renamed to '{RENAMED_BRANCH}'!" +RESET_MESSAGE = 'Reset the repository using "gitmastery progress reset" and start again' + + +def branch_has_rename_evidence( + exercise: GitAutograderExercise, new_branch: str, old_branch: str +) -> bool: + """Performs a DFS on the branch renames starting with login till feature/login. + + This is necessary since the renames could be performed in parts: + + login -> feat/login -> feature/login + """ + branch = exercise.repo.branches.branch_or_none(new_branch) + if branch is None: + # If new_branch not present at all + return False + + rename_regex = re.compile("^renamed refs/heads/(.+) to refs/heads/(.+)$") + for entry in branch.reflog[::-1]: + match_group = rename_regex.match(entry.message) + if match_group is None: + continue + original = match_group.group(1) + new = match_group.group(2) + if original == old_branch: + old_branch = new + + return old_branch == new_branch def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: @@ -42,6 +72,9 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: if comments: raise exercise.wrong_answer(comments) + + if not branch_has_rename_evidence(exercise, RENAMED_BRANCH, STU_BRANCH): + raise exercise.wrong_answer([NO_RENAME_EVIDENCE, RESET_MESSAGE]) return exercise.to_output( ["Nice work renaming the branch locally and on the remote!"], From 6f4ee03e47ac89d623bc1452dd25d949ca901433 Mon Sep 17 00:00:00 2001 From: desmondwong1215 Date: Sun, 8 Feb 2026 22:31:34 +0800 Subject: [PATCH 2/4] Update tests --- glossary_branch_rename/test_verify.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/glossary_branch_rename/test_verify.py b/glossary_branch_rename/test_verify.py index 1196d669..bee224f0 100644 --- a/glossary_branch_rename/test_verify.py +++ b/glossary_branch_rename/test_verify.py @@ -10,6 +10,8 @@ from repo_smith.repo_smith import RepoSmith from .verify import ( + NO_RENAME_EVIDENCE, + RESET_MESSAGE, verify, STU_LOCAL_PRESENT, STU_REMOTE_PRESENT, @@ -126,3 +128,20 @@ def test_remote_old_branch_still_exists(): output = test.run() assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [STU_REMOTE_PRESENT]) + +def test_no_rename_evidence(): + with base_setup() as (test, rs): + rs.git.checkout(EXPECTED_NEW_BRANCH_NAME, branch=True) + rs.git.push("origin", EXPECTED_NEW_BRANCH_NAME) + rs.git.branch(BRANCH_TO_RENAME, delete=True) + rs.git.push("origin", f":{BRANCH_TO_RENAME}") + + output = test.run() + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + NO_RENAME_EVIDENCE, + RESET_MESSAGE, + ], + ) \ No newline at end of file From a72bd2193e7d817e4a78fa7baeee8491b8de1365 Mon Sep 17 00:00:00 2001 From: desmondwong1215 Date: Sun, 8 Feb 2026 22:43:04 +0800 Subject: [PATCH 3/4] Improve verify logic --- glossary_branch_rename/verify.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/glossary_branch_rename/verify.py b/glossary_branch_rename/verify.py index 9a4f1985..59d9aa5e 100644 --- a/glossary_branch_rename/verify.py +++ b/glossary_branch_rename/verify.py @@ -25,10 +25,7 @@ def branch_has_rename_evidence( login -> feat/login -> feature/login """ - branch = exercise.repo.branches.branch_or_none(new_branch) - if branch is None: - # If new_branch not present at all - return False + branch = exercise.repo.branches.branch(new_branch) rename_regex = re.compile("^renamed refs/heads/(.+) to refs/heads/(.+)$") for entry in branch.reflog[::-1]: From d87bbcef06c0093d13b4d77f7d95a3badde63da9 Mon Sep 17 00:00:00 2001 From: desmondwong1215 Date: Mon, 9 Feb 2026 09:35:22 +0800 Subject: [PATCH 4/4] Address comments --- glossary_branch_rename/verify.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/glossary_branch_rename/verify.py b/glossary_branch_rename/verify.py index 59d9aa5e..17de47cc 100644 --- a/glossary_branch_rename/verify.py +++ b/glossary_branch_rename/verify.py @@ -13,17 +13,17 @@ STU_REMOTE_PRESENT = f"Remote branch {STU_BRANCH} still exists." RENAMED_REMOTE_MISSING = f"Remote branch {RENAMED_BRANCH} is missing." NO_RENAME_EVIDENCE = f"Local branch '{STU_BRANCH}' was not renamed to '{RENAMED_BRANCH}'!" -RESET_MESSAGE = 'Reset the repository using "gitmastery progress reset" and start again' +RESET_MESSAGE = 'If needed, reset the repository using "gitmastery progress reset" and start again.' def branch_has_rename_evidence( exercise: GitAutograderExercise, new_branch: str, old_branch: str ) -> bool: - """Performs a DFS on the branch renames starting with login till feature/login. + """Performs a DFS on the branch renames starting with STU till S-to-Z. This is necessary since the renames could be performed in parts: - login -> feat/login -> feature/login + STU -> S-to-U -> S-to-Z """ branch = exercise.repo.branches.branch(new_branch)