Skip to content

Conversation

@Danielku15
Copy link

See #2005

Old Behavior: When staging whole files, SourceGit tried to find a next/previous file within the same changed file list which could be selected afterwards. But when users staged/unstaged the individual chunks no selection was done leaving you with an empty view forcing you to select a file manually. This was cumbersome when staging the files chunkwise.

New Behavior: Internally SourceGit remembers the index of the selected file. Whenever the changed file list is updated (due to refresh or staging/unstaging) we use the remembered index to select a new file if the selection is gone. Thanks to this logic, it doesn't matter how the change was done. We select the file at the same spot if the selected item is gone.

Demo:

SourceGit_iPMfXgyfGb.mp4

@Danielku15 Danielku15 changed the base branch from master to develop January 1, 2026 14:56
@love-linger
Copy link
Collaborator

I don't think it's a good idea to determine the selection after refreshing based on the index of the previously selected data. This is particularly evident when users view in the Show as Filesystem Tree mode.

  1. SourceGit supports merging empty directories for display. If a file is not present in the list, it may cause the entire structure of the directory tree to change.
  2. The order of changes in _visibleUnstaged and _visibleStaged (sorted by dictionary order) is inconsistent with the order of changes in the tree structure (sorted by directory priority).

@Danielku15
Copy link
Author

Danielku15 commented Jan 4, 2026

SourceGit supports merging empty directories for display. If a file is not present in the list, it may cause the entire structure of the directory tree to change.

This is indeed a use-case I wasn't considering correctly. I mainly use the flat list where the index approach worked fine.

My main goal was to shift the logic from the UI to the ViewModel layer. Currently a lot of the logic in SourceGit is unfortunately in the UI layer and not handled through pure ViewModel bindings and command approaches.

The order of changes in _visibleUnstaged and _visibleStaged (sorted by dictionary order) is inconsistent with the order of changes in the tree structure (sorted by directory priority).

This is again an unfortunate result of not having a full ViewModel approach where the UI really just presents what is contained in the ViewModels.

Seems too much UI logic interferes with my mental-model of working in ViewModels to solve this problem.


I will close this PR and go back to the scratchpad to find out how I can make the "next file" information available in the diff editor where we stage chunks. I might be forced to introduce some "coupling" between the diff editor and the WorkingCopy component for that.

In best case I can move some more UI things down into the ViewModel level to have the "next file" logic available. 😁


I analyzed the current actual behavior, and my expected behavior as reference for the change.

Overall base rules:
    1. Looking at the whole tree, select the "next" change 
    2. If there are multiple items selected, the "last" selected item is taken to choose the "next"
    3. If there is no "next" chnage. select the "last" change. (new)


List: 
    Stage first: stays on first ✅
    Stage 3rd: stays on 3rd ✅
    Stage last: jumps to first ❌
        should be: stay on last item
    
Grid: 
    Stage first: stays on first ✅
    Stage 3rd: stays on 3rd ✅
    Stage last: jumps to first ❌
        should be: stay on last item

Tree:
    Sub folder with next sibling folder: 
        Stage first file in first folder in tree: stays on first file in same folder ✅
        Stage third file in first folder in tree: stays on third file in same folder ✅
        Stage last file in first folder in tree: jumps to first file in parent folder  ✅
        Stage last remaining file in first folder in tree: jumps to first file in next sibling folder  ✅
    Sub folder with no next sibling folder: 
        Stage first file in first folder in tree: stays on first file in same folder ✅
        Stage third file in first folder in tree: stays on third file in same folder ✅
        Stage last file in first folder in tree: jumps to first file in parent folder ✅
        Stage last remaining file in first folder in tree: jumps to first file in parent folder  ✅
                
    Sub folder with sibling folder: 
        Stage first folder in tree: jumps to first file in next sibling folder  ✅
        Stage third folder in tree: jumps to first file in next sibling folder  ✅
        Stage last folder in tree: jumps to very first change  ❌
            should be: jump to last change 
        Stage last remaining folder in tree: selection cleared ✅
    
        Stage first folder in tree: jumps to first file in next sibling folder  ✅
        Stage third folder in tree: jumps to first file in next sibling folder  ✅
        Stage last folder in tree: jumps to very first change  ❌
            should be: jump to last change 
        Stage last remaining folder in tree: selection cleared ✅       
                
    Stage first sub folder in last folder in tree: jumps to first file in next sibling folder  ✅
    Stage third sub folder in last folder in tree: jumps to first file in next sibling folder  ✅
    Stage last sub folder in last folder in tree: jumps to very first change  ❌
        should be: jump to last change 

Any feedback appreciated. There would be alternative approaches to the current "go next":

  • stay in the current folder before jumping to the next sibling
  • jump to the previous sibling before jumping to the parent

It's mostly a matter of preference regarding the hierarchy. But the "jump to first on staging last" seems a usability flaw worth addressing directly.

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.

2 participants