Skip to content

Add commit message to menu - #625

Merged
hannesa2 merged 3 commits into
masterfrom
AddCommitMessage2PopupMenu
Sep 13, 2026
Merged

hannesa2 merged 3 commits into
masterfrom
AddCommitMessage2PopupMenu

Conversation

@hannesa2

@hannesa2 hannesa2 commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

This avoids some misleading understanding of what is the concerning commit.
Follow up of #406

previous:

image

new:

image

This avoids some misleading understanding of what is the concerning commit
@hannesa2
hannesa2 force-pushed the AddCommitMessage2PopupMenu branch from 26211d6 to f0c7bb3 Compare September 13, 2026 08:29
@hannesa2

Copy link
Copy Markdown
Contributor Author

Screenshot differs: emulatorApi=arm64 with 4 screenshot(s)

setpoint (old) | diff | actual screenshot (new)

00-commit-context-menu.pngscreenshot

01-history-view.pngscreenshot

02-main-window.pngscreenshot

03-staging-view.pngscreenshot

@goneng goneng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice change, the bare "Checkout Commit" has confused me too.
Three things I ran into while reading it:

  1. 13 characters may be too short to disambiguate.
    After the ... indicator only 10 characters of the subject survive.
    This means half of the commits will just show Merge pull...,
    so for the most common commit-type in this repo the new title
    does not narrow anything down.
    At 40 characters the collisions drop to 15 of 400.
    Could we raise the limit?

  2. The cut can split a surrogate pair.
    PBNSStringTruncateModeEnd cuts at a UTF-16 index without looking at
    grapheme boundaries, so a subject like Fix this <emoji> thing that broke
    truncates to a string that cannot be encoded as UTF-8 and shows up as a
    broken glyph in the menu.
    AppKit tolerates it, so it is corruption rather than a crash.
    This is a latent bug in NSString_Truncate from 2010 and not something
    this PR introduced, but grep finds no other caller in the tree, so this is
    the change that first exposes it.
    Backing the cut off to a grapheme boundary should be enough:
    NSUInteger cut = total - indicator.length;
    NSRange seq = [s rangeOfComposedCharacterSequenceAtIndex:cut];
    if (seq.location < cut) cut = seq.location;

  3. Commits with an empty message render as (null).
    subject returns messageSummary, which is nil after
    git commit --allow-empty-message, so the item reads Checkout Commit "(null)".
    Maybe catch that and return an empty-string in this case.

1. Extended to 40 chars: truncateToLength:43 (40 + 3 for ...)
2. Empty message handling: falls back to NSLocalizedString(@"<empty message›", ...) when firstCommit. subject is empty, instead of ever formatting a nil into (null).
3. Grapheme-safe truncation: helpers applied to all three truncation modes (Center, Start, End), so a cut index that would split a surrogate pair or other multi-unit grapheme backs off/pushes forward to drop the whole sequence instead of corrupting it. Verified with an emoji-containing string across a range of lengths — output is always valid UTF-8, and the emoji is either fully kept or fully dropped, never split.
@hannesa2

Copy link
Copy Markdown
Contributor Author

I applied your suggestions and added some tests

@hannesa2
hannesa2 requested a review from goneng September 13, 2026 09:52
@hannesa2

Copy link
Copy Markdown
Contributor Author

Btw, this screenshot shows already the new feature
00-commit-context-menu.pngscreenshot

But this screenshot compare feature is current not perfect....
Currently it's just an info

@hannesa2

Copy link
Copy Markdown
Contributor Author

Screenshot differs: emulatorApi=arm64 with 4 screenshot(s)

setpoint (old) | diff | actual screenshot (new)

00-commit-context-menu.pngscreenshot

01-history-view.pngscreenshot

02-main-window.pngscreenshot

03-staging-view.pngscreenshot

@goneng

goneng commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Thanks, the grapheme helpers are nicer than what I suggested :)

One thing worth fixing: I reverted the fix and re-ran the new tests to check they catch the bug, and saw that testStartModeDoesNotSplitASurrogatePair passes even with the bug present.

I think that raising the loop to targetLength <= 30 gives the test teeth, like n=24 breaks on the old implementation and is clean on yours.

Two minor ones, take or leave:

  • testASubjectOfExactly40CharactersIsNotTruncated names a boundary that isn't one.
    The early return is length <= targetLength with targetLength 43, so 41 through 43 are untruncated too.
    Asserting 43-untruncated and 44-truncated would pin the choice down.
  • Pre-existing and not from this PR: any targetLength below the indicator length underflows NSUInteger
    and crashes all three modes.
    Unreachable at 43, but cheap to guard now that the file has tests.

Rest looks great to me.

@hannesa2
hannesa2 merged commit a31c0c5 into master Sep 13, 2026
5 of 6 checks passed
@hannesa2
hannesa2 deleted the AddCommitMessage2PopupMenu branch September 13, 2026 10:31
@hannesa2

Copy link
Copy Markdown
Contributor Author

Two minor ones, take or leave:

testASubjectOfExactly40CharactersIsNotTruncated names a boundary that isn't one.
The early return is length <= targetLength with targetLength 43, so 41 through 43 are untruncated too.
Asserting 43-untruncated and 44-truncated would pin the choice down.
Pre-existing and not from this PR: any targetLength below the indicator length underflows NSUInteger
and crashes all three modes.
Unreachable at 43, but cheap to guard now that the file has tests.

I'll split it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants