Skip to content

Fix dragging a file to the Finder taking it out of the repository - #592

Merged
hannesa2 merged 1 commit into
gitx:masterfrom
goneng:finder-drag-behavior
Sep 8, 2026
Merged

hannesa2 merged 1 commit into
gitx:masterfrom
goneng:finder-drag-behavior

Conversation

@goneng

@goneng goneng commented Aug 24, 2026 •

Copy link
Copy Markdown
Collaborator

Offer a copy, rather than any operation the destination likes, once
the drag has left GitX.

  • Restrict the source operation mask outside the application to a copy

This can lose files today

Dragging a changed file from the staged or unstaged list onto a Finder
window does not copy it. The Finder moves it, so the file leaves the
working copy and the list then reports it deleted.
Nothing warns, and nothing about the gesture suggests the file is being taken away, which
makes it easy to do by accident while meaning only to open or share a copy of it.

For a tracked file the damage is recoverable with git checkout.
For an untracked one it is not: the file is gone from the repository with
nothing in git recording that it was ever there.
Both lists show untracked files.

Where it comes from

The mask has allowed every operation since e76d483 (2008), the commit
that added the external drag in the first place, for a purpose that a
copy serves fully:

This allows you to drag a changed file to for example XCode, so you
can edit it.

The comment that commit left in the data source still reads
// External, to drag them to for example XCode or Textmate.
Opening a file elsewhere was the intent; relocating it was not.
A later commit carried the mask over to the current API without revisiting the value.

PBQLOutlineView already restricts itself to a copy, commented
/* Needed to drag outside application */.
This brings the two views into agreement.

Going to a file on disk is unaffected:
Reveal in Finder is in the context menu of both lists and in the main menu.

Test plan:

  • xcodebuild test -only-testing:GitXTests is green, 42/42,
    and the build carries the same warnings as master
  • To be checked by hand, a drag session being beyond a unit test:
    a file dragged from either list to a Finder window is copied and stays
    in the working copy; a file dragged into a text editor still opens;
    dragging between the two lists still stages and unstages

@goneng
goneng force-pushed the finder-drag-behavior branch 2 times, most recently from d32aacd to ec81de3 Compare August 24, 2026 13:05
@goneng
goneng marked this pull request as ready for review August 24, 2026 13:13
@goneng

goneng commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

(rebased on-top of master)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR prevents accidental data loss when dragging changed/untracked files from GitX to Finder by limiting the allowed drag operation outside the app to Copy, so Finder won’t interpret the drag as a move that removes the file from the working copy.

Changes:

  • Restrict sourceOperationMaskForDraggingContext: to NSDragOperationCopy when the drag leaves the application.
  • Keep the in-app drag operation mask unchanged (NSDragOperationEvery) to preserve existing internal drag behaviors.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +28 to 35
// Copying only once the drag leaves GitX: the files being dragged are the
// working copy, and a move takes them out of the repository.
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
{
if (context == NSDraggingContextOutsideApplication)
return NSDragOperationCopy;

return NSDragOperationEvery;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Two assertions added: outside-application returns NSDragOperationCopy, within-application still returns NSDragOperationEvery

@goneng
goneng marked this pull request as draft August 24, 2026 13:40
@goneng
goneng force-pushed the finder-drag-behavior branch from deebbd9 to ef9f2d2 Compare August 24, 2026 14:28
@goneng
goneng marked this pull request as ready for review August 24, 2026 14:33
@goneng
goneng force-pushed the finder-drag-behavior branch from ef9f2d2 to 0fd1c1a Compare August 24, 2026 14:45
Offer a copy, rather than any operation the destination likes,
once the drag has left GitX.

- Restrict the source operation mask outside the application to a copy
- Assert that a drag leaving GitX offers a copy and nothing else
- Assert that a drag staying inside GitX still offers every operation,
  since staging and unstaging by drag depend on the move

The mask has allowed every operation since the external drag was added
in 2008, to let a changed file be opened in another editor.
The Finder reads that as leave to move, so dragging a file to a Finder window
takes it out of the working copy, and the index then reports it deleted.
The tree view already restricts itself the same way.
@goneng
goneng force-pushed the finder-drag-behavior branch from 0fd1c1a to 4ee661d Compare September 7, 2026 20:21
@hannesa2
hannesa2 merged commit 1610e5f into gitx:master Sep 8, 2026
3 checks passed
@goneng
goneng deleted the finder-drag-behavior branch September 8, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants