-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Show specific dialog when we get stashed files git errors #10053
Conversation
app/src/ui/app.tsx
Outdated
const onDismissed = this.getOnPopupDismissedFn(popup.type) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline with @niik, we're creating a memoized version of onPopupDismissed
that passes the popupType
that gets opened, so when dismissing a modal it will only close itself and not other modals that could have got opened afterwards.
For now I've decided to only use this method on the new modal. It would be good to use it for every other modal but that would require extensive testing since it's possible that some modals are relying on the fact that currently onDismissed
closes any other modal.
I plan to wait to test this PR unless you suggest otherwise. Thanks! |
@tierninho Feel free to test to your heart's content! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall the code looks great. I noticed that when I attempt to rebase with local changes I'm presented with a generic dialog
It's not clear to me whether this is something that this PR is intending to solve but from looking at the code it seems like it should. It seems the only reason the dialog isn't shown when rebasing is because we don' have a retry action for rebase. Could/should we add one?
app/src/ui/local-changes-overwritten/local-changes-overwritten-dialog.tsx
Outdated
Show resolved
Hide resolved
Good point! I tried the merge workflow but totally missed that there's a rebase workflow (I thought rebases were only done when pulling based on the |
… submitting When the user chooses to stash changes and retry, the dialog can flicker since hasExistingStash will momentarily be true.
This is to overcome the limitation that jest uses the commonJS version of npm dependencies, which in most cases (like memoize-one, classnames or moment) don't expose a default keyword to make it interoperable with default imports. While this technically is not ES module compliant, it's a quick fix that's been already widely used in this codebase
app/src/ui/app.tsx
Outdated
@@ -123,6 +123,8 @@ import { CreateTag } from './create-tag' | |||
import { DeleteTag } from './delete-tag' | |||
import { ChooseForkSettings } from './choose-fork-settings' | |||
import { DiscardSelection } from './discard-changes/discard-selection-dialog' | |||
import { LocalChangesOverwrittenDialog } from './local-changes-overwritten/local-changes-overwritten-dialog' | |||
import * as memoizeOne from 'memoize-one' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using import * from memoizeOne
here to overcome the limitation that jest uses the commonJS version of npm dependencies, which in most cases (like memoize-one
, classnames
or moment
) don't expose a default attribute to make it interoperable with default imports.
While this technically is not ES module compliant, it's a quick fix that's been already widely used in this codebase (for moment
and classnames
).
I'm going to create a follow-up PR to fix these in a way that makes our codebase compatible with ES6 module syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the star-import trick didn't quite do the trick here (pun intended) 😢
[at-loader] ./app/src/ui/app.tsx:196:35 TS2349: This expression is not callable. Type 'typeof import("/Users/distiller/Desktop/desktop/node_modules/@types/memoize-one/index")' > has no call signatures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn it! It looks like the TypeScript definitions for memoize-one
are stricter than for the other libraries and don't allow this trick.
I'm going to remove the memoization from this module for now and create a follow-up PR to try to fix the madness when importing npm packages that expose both commonJS and ES6 modules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes look great but unfortunately it seems the build is still broken
app/src/ui/app.tsx
Outdated
@@ -123,6 +123,8 @@ import { CreateTag } from './create-tag' | |||
import { DeleteTag } from './delete-tag' | |||
import { ChooseForkSettings } from './choose-fork-settings' | |||
import { DiscardSelection } from './discard-changes/discard-selection-dialog' | |||
import { LocalChangesOverwrittenDialog } from './local-changes-overwritten/local-changes-overwritten-dialog' | |||
import * as memoizeOne from 'memoize-one' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the star-import trick didn't quite do the trick here (pun intended) 😢
[at-loader] ./app/src/ui/app.tsx:196:35 TS2349: This expression is not callable. Type 'typeof import("/Users/distiller/Desktop/desktop/node_modules/@types/memoize-one/index")' > has no call signatures.
Happy to test this in beta as it already has an approval and I can avoid the yarn errors after running
Feel free to merge when ready. |
There's a problem with ts-jest that prevents jest from importing correctly commonJS modules that I'm going to fix in a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we clean up the remaining pieces of the memoized specific popup dismissal in favor of the forthcoming PR?
/** | ||
* Returns a memoized instance of onPopupDismissed() bound to the | ||
* passed popupType, so it can be used in render() without creating | ||
* multiple instances when the component gets re-rendered. | ||
*/ | ||
private getOnPopupDismissedFn = (popupType: PopupType) => { | ||
return () => this.onPopupDismissed(popupType) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we drop this in favor of reintroducing it properly in the memoization PR?
/** | |
* Returns a memoized instance of onPopupDismissed() bound to the | |
* passed popupType, so it can be used in render() without creating | |
* multiple instances when the component gets re-rendered. | |
*/ | |
private getOnPopupDismissedFn = (popupType: PopupType) => { | |
return () => this.onPopupDismissed(popupType) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this check, in some situations the dismissal of this popup will cause other popups to get closed: I've just tested it and when merging the conflicts modal will get automatically closed after stashing the changes.
Anyways, I'm planning to send a PR with the memoization very soon, so in either case we'll fix the bug or the performance issue very soon 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that's great context that I was missing. Sounds great, we can live with the performance issue for a brief period of time I think.
Closes #8197
edit: The info above ☝️ is not relevant anymore, since a new
dugite
version has already been shipped.Description
This PR adds a new error handler for 3 dugite errors (
LocalChangesOverwritten
,MergeWithLocalChanges
andRebaseWithLocalChanges
) that get triggered when a git command cannot be executed due to existing local changes.When this error gets intercepted a generic modal gets displayed with an option to "Stash the Changes and Continue", which internally will stash the local changes and retry the action that caused the error:
Edge cases
retryAction
In order to retry the action, this PR makes use of the retry mechanism that's incorporated in some
git
calls. Since not allgit
calls currently have retry logic, this modal will only get shown whenever the error contains retry logic (in any other case the generic error modal will get shown, as it was done before).Currently, Merge operation don't have retry logic so we can add it to them in order to get this dialog also when merging branches.
Existing stash
If there's already an existing stash, the dialog won't offer the option to stash changes:
I think that we can improve this by showing a clear warning message in this scenario that tells the user that the current stash will get overwritten and allow the user to stash the changes. I initially tried to trigger the standard overwrite stash warning popup when this happens, but turns out that opening a popup within another popup creates a few edges cases.
I'm going to experiment with different ways to show that warning within the modal (cc @ampinsk and @billygriffin if you have any suggestion here).
Release notes
Notes: [Added] Suggest to stash changes when trying to do an operation that requires a clean working directory.