diff --git a/scripts/git-review-rebase/README.md b/scripts/git-review-rebase/README.md index 1068eee..d72f8c4 100644 --- a/scripts/git-review-rebase/README.md +++ b/scripts/git-review-rebase/README.md @@ -20,10 +20,15 @@ An interactive TUI (Terminal User Interface) tool for reviewing rebased git bran | ---- | ----------------------------------------- | | `=` | Same commit (identical SHA1 | | `~` | Loose match (same title, patchid changed) | + | `✎` | Commit message changed | | `⤶` | Already present in new upstream | | `✗` | Dropped during rebase | | `✚` | Added in rebase | +> A commit message comparison ignores trailing whitespace and surrounding blank lines, so `✎` +> only shows up when the message content itself differs. It is never set on `=` matches, since +> those commits are identical by definition. + > **Patchid** is a checksum of a commit's diff (`git patch-id`). Two commits with different > SHA1 (e.g. after rebase) that introduce the same code changes will have the same patchid. > This allows the tool to match commits across a rebase even when their SHA-1s change. diff --git a/scripts/git-review-rebase/src/git_review_rebase/commit_matching.py b/scripts/git-review-rebase/src/git_review_rebase/commit_matching.py index 3909ff1..5c234a7 100644 --- a/scripts/git-review-rebase/src/git_review_rebase/commit_matching.py +++ b/scripts/git-review-rebase/src/git_review_rebase/commit_matching.py @@ -6,7 +6,7 @@ from .branch_range import BranchRange from .constants import CommitMatchInfoFlag -from .git_utils import abbrev, commit_title +from .git_utils import abbrev, commit_title, message_changed class RebasedCommitMatch: @@ -67,6 +67,13 @@ def init_matches(self) -> None: if right_commit is not None: match_info = CommitMatchInfoFlag.LooseMatch + if ( + right_commit is not None + and right_commit.id != left_commit.id + and message_changed(left_commit, right_commit) + ): + match_info |= CommitMatchInfoFlag.MessageChanged + if ( right_commit is not None and right_commit.id not in self.right_range._rebased_commits diff --git a/scripts/git-review-rebase/src/git_review_rebase/constants.py b/scripts/git-review-rebase/src/git_review_rebase/constants.py index 37630bc..65569f8 100644 --- a/scripts/git-review-rebase/src/git_review_rebase/constants.py +++ b/scripts/git-review-rebase/src/git_review_rebase/constants.py @@ -28,6 +28,7 @@ class SolarizedColors(StrEnum): class CommitMatchInfoFlag(Flag): SameCommit = auto() LooseMatch = auto() + MessageChanged = auto() PresentInRebaseOnto = auto() Dropped = auto() Added = auto() @@ -49,6 +50,11 @@ def __init__(self, flag, character, definition): Text("~", SolarizedColors.Yellow), "Commit patchid has changed", ), + CommitMatchInfoFlag.MessageChanged: CommitMatchInfo( + CommitMatchInfoFlag.MessageChanged, + Text("✎", SolarizedColors.Orange), + "Commit message has changed", + ), CommitMatchInfoFlag.PresentInRebaseOnto: CommitMatchInfo( CommitMatchInfoFlag.PresentInRebaseOnto, Text("⤶", SolarizedColors.Blue), diff --git a/scripts/git-review-rebase/src/git_review_rebase/git_utils.py b/scripts/git-review-rebase/src/git_review_rebase/git_utils.py index 904e4f9..477bb1c 100644 --- a/scripts/git-review-rebase/src/git_review_rebase/git_utils.py +++ b/scripts/git-review-rebase/src/git_review_rebase/git_utils.py @@ -40,6 +40,16 @@ def commit_title(commit: pygit2.Commit) -> str: return (commit.message.splitlines() or [""])[0] +def normalized_message(commit: pygit2.Commit) -> str: + """Commit message without trailing whitespace nor surrounding blank lines.""" + return "\n".join(line.rstrip() for line in commit.message.strip().splitlines()) + + +def message_changed(left_commit: pygit2.Commit, right_commit: pygit2.Commit) -> bool: + """Return True if both commits do not share the same message.""" + return normalized_message(left_commit) != normalized_message(right_commit) + + def cached_patchid_ref(revision: str) -> str: """Poor man's cache in git refs directly using merkle trees.""" return f"refs/patchids/from_revision/" f"{revision[:2]}/{revision[2:4]}/{revision[4:]}"