Stashing [Tracking Issue]
See original GitHub issueOriginal issue: #6107
Design notes
Git Commands
git-stash list
> git stash list
stash@{0}: WIP on stashing: 41f7b73 some random commit message
stash@{1}: WIP on stashing: 41f7b73 some random commit message
stash@{2}: On stashing: a message
stash@{3}: On stashing: this is a message
stash@{4}: WIP on stashing: 531bd83 1
stash@{5}: WIP on stashing: 531bd83 1
I’ll be using git log -g refs/stash
to emulate the behaviour of git stash list
since it uses git log
under the hood (docs). Doing it this way will help us avoid doing extra work which is super important on Windows as process creation is very expensive.
git-stash push
> git stash push -m “a message”
Saved working directory and index state On stashing: a message
I’ll be using a specially formatted message to differentiate between stash objects created by the user and Desktop on the user’s behalf. This is not a bullet-proof solution because
- a user can use our message format when they stash something from the CLI and
- they can edit the message stored in a stash object by modifying git/logs/refs/stash
However, we take a similar approach for adding remotes and checking out pull requests, so I think we can safely ignore the risks above.
Message Format
github-desktop: fully qualified branch name
Component | Reasoning |
---|---|
github-desktop | It’s unlikely anyone would use that in their own stash message and it makes is super clear which entries are created by Desktop. |
tip | Having the tip of the branch at the time the stash object is created should prevent issues related to ambiguous branch names. An added benefit is we could deal with branch renaming. |
My thinking is that I can use the tip to make extra sure the stash entry is based on a specific branch. I am making an assumption that if the commit SHA is a branch’s history, then it likely is that branch. I think this means I can get by without using fully-qualified branch names.
git-stash apply
Happy path
> git stash apply stash{1}
On branch stashing
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: aoc-day2.ts
no changes added to commit (use "git add" and/or "git commit -a")
Conflicts
> git stash apply stash{3}
Auto-merging aoc-day2.ts
CONFLICT (content): Merge conflict in aoc-day2.ts
I should be able to lean on the current plumbing in Desktop to respond to the working tree state getting updated and on the conflict resolution flow in the event of conflicts.
Desktop Plumbing
Entry point
The entry point for this feature is the user attempts to checkout a new branch while they have uncommitted changes that would get lost by switching branches. Since we already have a dialog that’s presented when a user tries to switch branches with uncommitted changes, I’ll update that flow for stashing.
Files Overwritten dialog
Responsible error handler
Conflicts
Conflicts that arise as a result of applying a stash differ or not the same as merge conflicts. That detail is important here because Desktop requires a merge conflict to intiate the merge conflict resolution flow. Some thought will have to be put into how to handle stash conflicts, but since these types of conflicts don’t have to be resolved due to them not being merge conflicts, I can punt this issue down the road a bit.
Metrics for Success
Questions:
- What percentage of the time do people bring their changes across to a different branch vs. stashing them in their current branch?
- What percentage of time are people restoring the stash vs. deleting the stash vs. neither of those things? The total of these should equal the number of times users return to a branch that contains a stash.
- What percent of changes viewed are via clicking on the “Stashed changes” row directly vs. clicking on the prompt in the suggested next step? (there’s not a metric for this below yet)
- How many times do users currently stash outside of Desktop, and can we demonstrate that supporting this shows a decline in that overall per-user number? This is intended to understand whether we are improving context-switching and allowing people to do more of their overall workflow in Desktop.
Metric | Description |
---|---|
stash-prompt-displayed |
The number of times the user is prompted to either stash their changes on their current branch or bring them to their new branch. |
stash-created-on-current-branch-count |
The number of times the user selects the option to stash changes on their current branch. |
stash-created-on-new-branch-count |
The number of times the user selects the option to bring their changes to a new branch. |
stash-applied-count |
The number of times the user applies a stash (this count applies only to stash objects not taken to the new branch*). |
stash-discard-count |
The number of times the user removes a stash object from their branch (this count applies only to stash objects not taken to the new branch*). |
stash-view-count |
The number of times the user clicks the Stashed changes button in the Changes tab. |
stashes-outside-desktop * |
The number of times a Desktop user creates a stash outside of GitHub Desktop. |
*This is a derived metric.
Although we are planning to move to an event-based metric approach, I’ll be implementing these metrics as we currently do because we have not switched to the new approach yet.
Questions
- ~When should I perform housekeeping of stash entries?~
- ~When
git stash apply
succeeds? or~ - ~after the user commits the newly applied stash (assuming merge conflicts have been taken care of)?~
- ~When
- ~Should we also allow for discarding changes instead of always stashing them?~
- ~If the option to take changes to the new branch is selected, should I try to apply the stash immediately or stash it and let the user apply it?~
- ~The Stashed changes view doesn’t have a way to close other than applying or clearing the stash, should we allow users to close this?~
- ~If we aren’t going to have an x button to close the view, should selecting an item in the changes list close the view?~
Questions to validate with users
- If a stash is created outside of Desktop on a given branch and a user returns to that branch in Desktop, what is their expectation?
- How do people navigate away from the “View stash” view? Do they find it intuitive to “get out of it” or do they need something more explicit?
Todo
- Implement foundational stash functions - #7182
- Diff view of stashed changes - #7213
- Implement flow that allows the user to stash changes and associate it with the current branch -#7210
- Implement flow that allows the user to take changes with them to new branch - #7219
- Add a confirmation dialog for overwriting stashed changes - #7230
- Update
IDailyMeasures
,StatsStore
, andDispatcher
to record new metrics - #7257
Issue Analytics
- State:
- Created 5 years ago
- Reactions:2
- Comments:11 (10 by maintainers)
Top GitHub Comments
Something that we can consider doing is utilizing the “Suggested Next Steps” pattern that @niik created to guide people to their stashed changes:
Which clicking on “View Stash” will bring up the stashed changes view:
My assumption is that this approach would be quicker to implement than a popover (and all the potential state around whether or not a user has seen it) and more obvious than an animation. I’ve created a simple prototype in Figma if anyone wanted to get a feel of it.
Open to any feedback with this approach! 😃
Verbiage (finalized after discussions) here:
Proposed verbiage for grey explanatory text next to “Restore”
Proposed verbiage for suggested next step if we go with @donokuda’s proposal above
Changes
tab to the left