├── .circleci └── config.yml ├── .gitattributes ├── .gitconfig ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── help_or_support.md └── dependabot.yml ├── .gitignore ├── CHANGE-NOTES.md ├── CONTRIBUTING.md ├── DESCRIPTION.html ├── LICENSE ├── README.md ├── _config.yml ├── backend ├── api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── backend │ │ ├── api │ │ ├── GitMacheteException.java │ │ ├── GitMacheteMissingForkPointException.java │ │ ├── IBranchReference.java │ │ ├── ICommitOfManagedBranch.java │ │ ├── IForkPointCommitOfManagedBranch.java │ │ ├── IGitMacheteRepository.java │ │ ├── IGitMacheteRepositoryCache.java │ │ ├── IGitMacheteRepositorySnapshot.java │ │ ├── IGitRebaseParameters.java │ │ ├── ILocalBranchReference.java │ │ ├── IManagedBranchSnapshot.java │ │ ├── INonRootManagedBranchSnapshot.java │ │ ├── IRemoteTrackingBranchReference.java │ │ ├── IRootManagedBranchSnapshot.java │ │ ├── MacheteFileReaderException.java │ │ ├── NullGitMacheteRepositorySnapshot.java │ │ ├── OngoingRepositoryOperationType.java │ │ ├── RelationToRemote.java │ │ ├── SyncToParentStatus.java │ │ └── SyncToRemoteStatus.java │ │ └── hooks │ │ ├── BaseHookExecutor.java │ │ ├── ExecutionResult.java │ │ └── OnExecutionTimeout.java └── impl │ ├── build.gradle.kts │ └── src │ ├── main │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── backend │ │ └── impl │ │ ├── BaseBranchReference.java │ │ ├── BaseManagedBranchSnapshot.java │ │ ├── CommitOfManagedBranch.java │ │ ├── CreatedAndDuplicatedAndSkippedBranches.java │ │ ├── ForkPointCommitOfManagedBranch.java │ │ ├── GitMacheteRepository.java │ │ ├── GitMacheteRepositoryCache.java │ │ ├── GitMacheteRepositorySnapshot.java │ │ ├── GitRebaseParameters.java │ │ ├── LocalBranchReference.java │ │ ├── NonRootManagedBranchSnapshot.java │ │ ├── RemoteTrackingBranchReference.java │ │ ├── RootManagedBranchSnapshot.java │ │ ├── StatusBranchHookExecutor.java │ │ └── aux │ │ ├── Aux.java │ │ ├── CreateGitMacheteRepositoryAux.java │ │ └── DiscoverGitMacheteRepositoryAux.java │ └── test │ ├── java │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── backend │ │ ├── integration │ │ ├── BaseIntegrationTestSuite.java │ │ ├── ParentInferenceIntegrationTestSuite.java │ │ ├── RegenerateCliOutputs.java │ │ └── StatusAndDiscoverIntegrationTestSuite.java │ │ └── unit │ │ ├── BaseGitMacheteRepositoryUnitTestSuite.java │ │ ├── GitMacheteRepository_deriveCreatedAndDuplicatedAndSkippedBranchesUnitTestSuite.java │ │ ├── GitMacheteRepository_deriveParentAwareForkPointUnitTestSuite.java │ │ ├── GitMacheteRepository_deriveRelationToRemoteUnitTestSuite.java │ │ ├── GitMacheteRepository_deriveSyncToParentStatusUnitTestSuite.java │ │ └── UnitTestUtils.java │ └── resources │ ├── setup-for-diverged-and-older-than.sh-discover.txt │ ├── setup-for-diverged-and-older-than.sh-status.txt │ ├── setup-for-overridden-fork-point.sh-discover.txt │ ├── setup-for-overridden-fork-point.sh-status.txt │ ├── setup-for-squash-merge.sh-discover.txt │ ├── setup-for-squash-merge.sh-status.txt │ ├── setup-for-yellow-edges.sh-discover.txt │ ├── setup-for-yellow-edges.sh-status.txt │ ├── setup-with-multiple-remotes.sh-discover.txt │ ├── setup-with-multiple-remotes.sh-status.txt │ ├── setup-with-no-remotes.sh-discover.txt │ ├── setup-with-no-remotes.sh-status.txt │ ├── setup-with-single-remote.sh-discover.txt │ ├── setup-with-single-remote.sh-status.txt │ └── version.txt ├── branchLayout ├── api │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── virtuslab │ │ │ └── branchlayout │ │ │ └── api │ │ │ ├── BranchLayout.java │ │ │ ├── BranchLayoutEntry.java │ │ │ ├── BranchLayoutException.java │ │ │ ├── EntryDoesNotExistException.java │ │ │ ├── EntryIsDescendantOfException.java │ │ │ └── readwrite │ │ │ ├── IBranchLayoutReader.java │ │ │ ├── IBranchLayoutWriter.java │ │ │ └── IndentSpec.java │ │ └── test │ │ └── java │ │ └── com │ │ └── virtuslab │ │ └── branchlayout │ │ └── api │ │ └── BranchLayoutTestSuite.java └── impl │ ├── build.gradle.kts │ └── src │ ├── main │ └── java │ │ └── com │ │ └── virtuslab │ │ └── branchlayout │ │ └── impl │ │ └── readwrite │ │ ├── BranchLayoutFileUtils.java │ │ ├── BranchLayoutReader.java │ │ └── BranchLayoutWriter.java │ └── test │ └── java │ └── com │ └── virtuslab │ └── branchlayout │ └── impl │ └── readwrite │ └── BranchLayoutFileReaderTestSuite.java ├── build.gradle.kts ├── buildSrc ├── build.gradle.kts ├── gradle │ └── libs.versions.toml └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── buildsrc │ │ ├── CheckerFramework.kt │ │ ├── Checkstyle.kt │ │ ├── Dependencies.kt │ │ ├── IntellijVersionHelper.kt │ │ ├── IntellijVersions.kt │ │ ├── PropertiesHelper.kt │ │ ├── Spotless.kt │ │ ├── UiTests.kt │ │ ├── UpdateIntellijVersions.kt │ │ └── VersionFromGit.kt │ └── test │ └── kotlin │ └── com │ └── virtuslab │ └── gitmachete │ └── buildsrc │ ├── IntellijVersionHelperTest.kt │ └── IntellijVersionsTest.kt ├── config ├── checker │ ├── com.intellij.astub │ ├── git4idea.astub │ ├── io.vavr.astub │ ├── java.lang.astub │ ├── java.util.astub │ ├── javax.swing.astub │ ├── org.apache.commons.astub │ └── org.eclipse.jgit.astub ├── checkstyle │ └── checkstyle.xml └── spotless │ └── formatting-rules.xml ├── docs ├── checkout.gif ├── debug_configuration.png ├── discover.gif ├── fast_forward.gif ├── features.md ├── left_bar_actions │ ├── discover.png │ ├── edit.png │ ├── fastForward.png │ ├── fetch.png │ ├── ffmerge.png │ ├── help.png │ ├── incomingChangesOn.png │ ├── macheteLogoIcon.png │ ├── merge.png │ ├── overrideForkPoint.png │ ├── pull.png │ ├── push.png │ ├── rebase.png │ ├── reset.png │ ├── slideIn.png │ ├── slideOut.png │ ├── squash.png │ ├── toggleListingCommits.png │ └── traverse.png ├── logo-dark.svg ├── logo.svg ├── machete_file_editor.gif ├── medium-blog-post │ ├── actions-after_dark.png │ ├── actions-before_dark.png │ ├── actions_dark.png │ ├── blog.md │ ├── gmt_dark.png │ ├── logo.svg │ ├── machete-file_dark.png │ ├── rebase-gm_dark-4x3.gif │ └── rebase-idea_dark-4x3.gif ├── merge.gif ├── multi_repo.gif ├── open_git_machete.gif ├── override_forkpoint.gif ├── plugins.jetbrains.com │ ├── getting_started.html │ ├── sample_status.png │ ├── scenario-1-review.gif │ ├── scenario-2-branch-update.gif │ ├── scenario-3-stacked-prs.gif │ └── scenario-4-ff-merge.gif ├── pull.gif ├── push.gif ├── rebase.gif ├── rename.png ├── reset.gif ├── sample_graph.png ├── show_in_git_log.gif ├── slide_in_existing_branch.gif ├── slide_in_new_branch.gif ├── slide_in_reattach_with_children.gif ├── slide_in_reattach_without_children.gif ├── slide_in_use_cases.md ├── slide_out_leaf_node.gif ├── slide_out_non_leaf_node.gif ├── squash.gif └── toggle_listing_commits.gif ├── frontend ├── actions │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── virtuslab │ │ │ └── gitmachete │ │ │ └── frontend │ │ │ └── actions │ │ │ ├── backgroundables │ │ │ ├── BaseSlideInBackgroundable.java │ │ │ ├── FetchBackgroundable.java │ │ │ ├── GitCommandUpdatingCurrentBranchBackgroundable.java │ │ │ ├── MergeCurrentBranchFastForwardOnlyBackgroundable.java │ │ │ ├── OverrideForkPointBackgroundable.java │ │ │ ├── RebaseOnParentBackgroundable.java │ │ │ ├── RenameBackgroundable.java │ │ │ ├── ResetCurrentToRemoteBackgroundable.java │ │ │ ├── SideEffectingBackgroundable.java │ │ │ ├── SlideInNonRootBackgroundable.java │ │ │ └── SlideInRootBackgroundable.java │ │ │ ├── base │ │ │ ├── BaseCheckoutAction.java │ │ │ ├── BaseCompareWithParentAction.java │ │ │ ├── BaseFastForwardMergeToParentAction.java │ │ │ ├── BaseGitMacheteRepositoryReadyAction.java │ │ │ ├── BaseOverrideForkPointAction.java │ │ │ ├── BaseProjectDependentAction.java │ │ │ ├── BasePullAction.java │ │ │ ├── BasePushAction.java │ │ │ ├── BaseRenameAction.java │ │ │ ├── BaseResetToRemoteAction.java │ │ │ ├── BaseSlideInBelowAction.java │ │ │ ├── BaseSlideOutAction.java │ │ │ ├── BaseSquashAction.java │ │ │ ├── BaseSyncToParentByMergeAction.java │ │ │ ├── BaseSyncToParentByRebaseAction.java │ │ │ ├── IBranchNameProvider.java │ │ │ ├── ISyncToParentStatusDependentAction.java │ │ │ ├── ISyncToRemoteStatusDependentAction.java │ │ │ └── IWithLogger.java │ │ │ ├── common │ │ │ ├── ActionUtils.java │ │ │ ├── BranchCreationUtils.java │ │ │ ├── BranchNamesCompletion.java │ │ │ ├── FastForwardMerge.java │ │ │ ├── FetchUpToDateTimeoutStatus.java │ │ │ ├── MergeProps.java │ │ │ ├── Pull.java │ │ │ ├── SideEffectingActionTrackingService.java │ │ │ ├── SlideInOptions.java │ │ │ ├── SlideInUnmanagedBelowAction.java │ │ │ ├── SlideOut.java │ │ │ ├── UiThreadUnsafeRunnable.java │ │ │ └── VcsCommitMetadataAdapterForSquash.java │ │ │ ├── contextmenu │ │ │ ├── CheckoutSelectedAction.java │ │ │ ├── CompareSelectedWithParentAction.java │ │ │ ├── FastForwardMergeSelectedToParentAction.java │ │ │ ├── OverrideForkPointOfSelectedAction.java │ │ │ ├── PullSelectedAction.java │ │ │ ├── PushSelectedAction.java │ │ │ ├── RenameSelectedAction.java │ │ │ ├── ResetSelectedToRemoteAction.java │ │ │ ├── ShowSelectedInGitLogAction.java │ │ │ ├── SlideInBelowSelectedAction.java │ │ │ ├── SlideOutSelectedAction.java │ │ │ ├── SquashSelectedAction.java │ │ │ ├── SyncSelectedToParentByMergeAction.java │ │ │ ├── SyncSelectedToParentByRebaseAction.java │ │ │ └── TraverseFromSelectedAction.java │ │ │ ├── dialogs │ │ │ ├── GitPushDialog.java │ │ │ └── TraverseStepConfirmationDialog.java │ │ │ ├── expectedkeys │ │ │ ├── IExpectsKeyGitMacheteRepository.java │ │ │ ├── IExpectsKeySelectedBranchName.java │ │ │ └── IExpectsKeyUnmanagedBranchName.java │ │ │ ├── hooks │ │ │ ├── BaseGit4IdeaHookExecutor.java │ │ │ ├── PostSlideOutHookExecutor.java │ │ │ └── PreRebaseHookExecutor.java │ │ │ ├── navigation │ │ │ ├── CheckoutFirstChildAction.java │ │ │ ├── CheckoutNextAction.java │ │ │ ├── CheckoutParentAction.java │ │ │ └── CheckoutPreviousAction.java │ │ │ ├── toolbar │ │ │ ├── DiscoverAction.java │ │ │ ├── FastForwardMergeCurrentToParentAction.java │ │ │ ├── FetchAllRemotesAction.java │ │ │ ├── HelpAction.java │ │ │ ├── OpenMacheteFileAction.java │ │ │ ├── OverrideForkPointOfCurrentAction.java │ │ │ ├── PullCurrentAction.java │ │ │ ├── PushCurrentAction.java │ │ │ ├── ResetCurrentToRemoteAction.java │ │ │ ├── SlideInBelowCurrentAction.java │ │ │ ├── SlideOutCurrentAction.java │ │ │ ├── SquashCurrentAction.java │ │ │ ├── SyncCurrentToParentByRebaseAction.java │ │ │ ├── ToggleListingCommitsAction.java │ │ │ └── TraverseFromFirstAction.java │ │ │ ├── traverse │ │ │ ├── BaseTraverseAction.java │ │ │ ├── CheckoutAndExecute.java │ │ │ ├── TraverseSyncToParent.java │ │ │ └── TraverseSyncToRemote.java │ │ │ └── vcsmenu │ │ │ └── OpenMacheteTabAction.java │ │ └── kotlin │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── frontend │ │ └── actions │ │ └── dialogs │ │ ├── DeleteBranchOnSlideOutSuggestionDialog.kt │ │ ├── DoNotAskOption.kt │ │ ├── GitNewBranchDialogCompat.kt │ │ ├── GitNewCommitMessageActionDialog.kt │ │ ├── GraphTableDialog.kt │ │ ├── MyGitNewBranchDialog.kt │ │ ├── OverrideForkPointDialog.kt │ │ ├── SlideInDialog.kt │ │ └── TraverseInfoComponent.kt ├── base │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── virtuslab │ │ │ │ └── gitmachete │ │ │ │ └── frontend │ │ │ │ ├── common │ │ │ │ └── WriteActionUtils.java │ │ │ │ ├── datakeys │ │ │ │ └── DataKeys.java │ │ │ │ ├── defs │ │ │ │ ├── ActionGroupIds.java │ │ │ │ ├── ActionIds.java │ │ │ │ ├── ActionPlaces.java │ │ │ │ ├── Colors.java │ │ │ │ ├── FileTypeIds.java │ │ │ │ ├── GitConfigKeys.java │ │ │ │ └── PropertiesComponentKeys.java │ │ │ │ ├── errorreport │ │ │ │ ├── GitMacheteErrorReportSubmitter.java │ │ │ │ └── PlatformInfoProvider.java │ │ │ │ ├── icons │ │ │ │ └── MacheteIcons.java │ │ │ │ └── vfsutils │ │ │ │ └── GitVfsUtils.java │ │ └── resources │ │ │ ├── bug_report.md │ │ │ └── icons │ │ │ ├── edit.svg │ │ │ ├── edit_dark.svg │ │ │ ├── fastForward.svg │ │ │ ├── fastForward_dark.svg │ │ │ ├── fetch.svg │ │ │ ├── fetch_dark.svg │ │ │ ├── help.svg │ │ │ ├── help_dark.svg │ │ │ ├── incomingChangesOn.svg │ │ │ ├── incomingChangesOn_dark.svg │ │ │ ├── macheteLogoIcon.svg │ │ │ ├── macheteLogoIcon32.svg │ │ │ ├── macheteLogoIcon32_dark.svg │ │ │ ├── macheteLogoIcon_dark.svg │ │ │ ├── merge.svg │ │ │ ├── merge_dark.svg │ │ │ ├── overrideForkPoint.svg │ │ │ ├── overrideForkPoint_dark.svg │ │ │ ├── pull.svg │ │ │ ├── pull_dark.svg │ │ │ ├── push.svg │ │ │ ├── push_dark.svg │ │ │ ├── rebase.svg │ │ │ ├── rebase_dark.svg │ │ │ ├── rename.svg │ │ │ ├── rename_dark.svg │ │ │ ├── reset.svg │ │ │ ├── reset_dark.svg │ │ │ ├── slideIn.svg │ │ │ ├── slideIn_dark.svg │ │ │ ├── slideOut.svg │ │ │ ├── slideOut_dark.svg │ │ │ ├── squash.svg │ │ │ ├── squash_dark.svg │ │ │ ├── toggleListingCommits.svg │ │ │ ├── toggleListingCommits_dark.svg │ │ │ ├── traverse.svg │ │ │ └── traverse_dark.svg │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── virtuslab │ │ │ └── gitmachete │ │ │ └── frontend │ │ │ └── errorreport │ │ │ ├── DummyPlatformInfoProvider.java │ │ │ └── GitMacheteErrorReportSubmitterTest.java │ │ └── resources │ │ └── expected-error-report-uris │ │ ├── for_multiple_events.txt │ │ ├── long_uri.txt │ │ ├── with_stack_trace.txt │ │ ├── with_suppressed_exceptions.txt │ │ ├── with_wrapped_exceptions.txt │ │ └── without_stack_trace.txt ├── file │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── grammar │ │ ├── Machete.bnf │ │ └── Machete.flex │ │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── frontend │ │ └── file │ │ ├── MacheteCompletionContributor.java │ │ ├── MacheteFileReader.java │ │ ├── MacheteFileType.java │ │ ├── MacheteFileUtils.java │ │ ├── MacheteFileViewProviderFactory.java │ │ ├── MacheteFileWriter.java │ │ ├── ReparseMacheteFileOnGitRepositoryChange.java │ │ ├── codestyle │ │ ├── MacheteCodeStyleSettingsProvider.java │ │ └── MacheteLanguageCodeStyleSettingsProvider.java │ │ ├── grammar │ │ ├── MacheteElementType.java │ │ ├── MacheteFile.java │ │ ├── MacheteLanguage.java │ │ ├── MacheteLexerAdapter.java │ │ ├── MacheteParserDefinition.java │ │ └── MacheteTokenType.java │ │ ├── highlighting │ │ ├── MacheteAnnotator.java │ │ ├── MacheteColorSettingsPane.java │ │ ├── MacheteSyntaxHighlighter.java │ │ └── MacheteSyntaxHighlighterFactory.java │ │ └── quickfix │ │ └── CreateBranchQuickFix.java ├── graph │ ├── api │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── virtuslab │ │ │ └── gitmachete │ │ │ └── frontend │ │ │ └── graph │ │ │ └── api │ │ │ ├── elements │ │ │ ├── GraphEdge.java │ │ │ ├── GraphNode.java │ │ │ └── IGraphElement.java │ │ │ ├── items │ │ │ ├── GraphItemColor.java │ │ │ ├── IBranchItem.java │ │ │ ├── ICommitItem.java │ │ │ └── IGraphItem.java │ │ │ ├── paint │ │ │ ├── IGraphCellPainter.java │ │ │ ├── IGraphCellPainterFactory.java │ │ │ └── PaintParameters.java │ │ │ ├── render │ │ │ ├── IRenderPartGenerator.java │ │ │ └── parts │ │ │ │ ├── IEdgeRenderPart.java │ │ │ │ ├── INodeRenderPart.java │ │ │ │ └── IRenderPart.java │ │ │ └── repository │ │ │ ├── IBranchGetCommitsStrategy.java │ │ │ ├── IRepositoryGraph.java │ │ │ ├── IRepositoryGraphCache.java │ │ │ └── NullRepositoryGraph.java │ └── impl │ │ ├── build.gradle.kts │ │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── frontend │ │ └── graph │ │ └── impl │ │ ├── items │ │ ├── BaseGraphItem.java │ │ ├── BranchItem.java │ │ └── CommitItem.java │ │ ├── paint │ │ ├── GraphCellPainter.java │ │ └── GraphCellPainterFactory.java │ │ ├── render │ │ ├── GraphItemColorForGraphElementProvider.java │ │ ├── RenderPartGenerator.java │ │ └── parts │ │ │ ├── BaseRenderPart.java │ │ │ ├── EdgeRenderPart.java │ │ │ └── NodeRenderPart.java │ │ └── repository │ │ ├── RepositoryGraph.java │ │ ├── RepositoryGraphBuilder.java │ │ └── RepositoryGraphCache.java ├── resourcebundles │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── virtuslab │ │ │ │ └── gitmachete │ │ │ │ └── frontend │ │ │ │ └── resourcebundles │ │ │ │ └── GitMacheteBundle.java │ │ └── resources │ │ │ └── GitMacheteBundle.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── resourcebundles │ │ └── junit │ │ └── GitMacheteBundlePropertiesTestSuite.java └── ui │ ├── api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── frontend │ │ └── ui │ │ └── api │ │ ├── gitrepositoryselection │ │ ├── IGitRepositorySelectionChangeObserver.java │ │ └── IGitRepositorySelectionProvider.java │ │ └── table │ │ ├── BaseEnhancedGraphTable.java │ │ ├── BaseGraphTable.java │ │ └── ISimpleGraphTableProvider.java │ └── impl │ ├── build.gradle.kts │ └── src │ └── main │ └── java │ └── com │ └── virtuslab │ └── gitmachete │ └── frontend │ └── ui │ └── impl │ ├── RediscoverSuggester.java │ ├── backgroundables │ ├── AutodiscoverBackgroundable.java │ ├── GitMacheteRepositoryUpdateBackgroundable.java │ └── InferParentForUnmanagedBranchBackgroundable.java │ ├── cell │ ├── BranchOrCommitCell.java │ ├── BranchOrCommitCellRenderer.java │ └── BranchOrCommitCellRendererComponent.java │ ├── gitrepositoryselection │ └── GitRepositoryComboBox.java │ ├── root │ ├── GitMacheteContentProvider.java │ ├── GitMachetePanel.java │ └── GitMacheteVisibilityPredicate.java │ └── table │ ├── DemoGitMacheteRepositorySnapshot.java │ ├── EnhancedGraphTable.java │ ├── EnhancedGraphTableMouseAdapter.java │ ├── EnhancedGraphTablePopupMenuListener.java │ ├── GraphTableModel.java │ ├── SimpleGraphTable.java │ ├── SimpleGraphTableProvider.java │ ├── UnmanagedBranchNotification.java │ └── UnmanagedBranchNotificationFactory.java ├── gitCore ├── api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitcore │ │ └── api │ │ ├── GitCoreCannotAccessGitDirectoryException.java │ │ ├── GitCoreException.java │ │ ├── GitCoreNoSuchRevisionException.java │ │ ├── GitCoreRelativeCommitCount.java │ │ ├── GitCoreRepositoryState.java │ │ ├── IGitCoreBranchSnapshot.java │ │ ├── IGitCoreCheckoutEntry.java │ │ ├── IGitCoreCommit.java │ │ ├── IGitCoreCommitHash.java │ │ ├── IGitCoreHeadSnapshot.java │ │ ├── IGitCoreLocalBranchSnapshot.java │ │ ├── IGitCoreObjectHash.java │ │ ├── IGitCoreReflogEntry.java │ │ ├── IGitCoreRemoteBranchSnapshot.java │ │ ├── IGitCoreRepository.java │ │ ├── IGitCoreRepositoryFactory.java │ │ └── IGitCoreTreeHash.java └── jGit │ ├── build.gradle.kts │ └── src │ ├── main │ └── java │ │ └── com │ │ └── virtuslab │ │ └── gitcore │ │ └── impl │ │ └── jgit │ │ ├── BaseGitCoreBranchSnapshot.java │ │ ├── BranchFullNameUtils.java │ │ ├── GitCoreCheckoutEntry.java │ │ ├── GitCoreCommit.java │ │ ├── GitCoreCommitHash.java │ │ ├── GitCoreHeadSnapshot.java │ │ ├── GitCoreLocalBranchSnapshot.java │ │ ├── GitCoreObjectHash.java │ │ ├── GitCoreReflogEntry.java │ │ ├── GitCoreRemoteBranchSnapshot.java │ │ ├── GitCoreRepository.java │ │ ├── GitCoreRepositoryFactory.java │ │ └── GitCoreTreeHash.java │ └── test │ └── java │ └── com │ └── virtuslab │ └── gitcore │ └── impl │ └── jgit │ ├── GitCoreCommitUnitTest.java │ └── GitCoreRepositoryIntegrationTest.java ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── intellij-versions.properties ├── lombok.config ├── qual ├── build.gradle.kts └── src │ └── main │ └── java │ └── com │ └── virtuslab │ └── qual │ ├── async │ ├── BackgroundableQueuedElsewhere.java │ ├── ContinuesInBackground.java │ └── DoesNotContinueInBackground.java │ ├── guieffect │ ├── IgnoreUIThreadUnsafeCalls.java │ └── UIThreadUnsafe.java │ └── subtyping │ ├── gitmachete │ ├── backend │ │ └── api │ │ │ ├── ConfirmedLocal.java │ │ │ ├── ConfirmedNonRoot.java │ │ │ ├── ConfirmedRemote.java │ │ │ └── ConfirmedRoot.java │ └── frontend │ │ └── graph │ │ └── api │ │ ├── elements │ │ ├── ConfirmedGraphEdge.java │ │ └── ConfirmedGraphNode.java │ │ └── items │ │ ├── ConfirmedBranchItem.java │ │ └── ConfirmedCommitItem.java │ ├── internal │ ├── SubtypingBottom.java │ ├── SubtypingTop.java │ └── package-info.java │ └── package-info.java ├── scalafmt.conf ├── scripts ├── close-github-milestone ├── enforce-astub-explicit-annotation-import ├── enforce-change-notes-updated-on-pr-to-master ├── enforce-indent-two-spaces-outside-java ├── enforce-indent-two-spaces-outside-java.awk ├── enforce-issue-number-for-todos ├── enforce-newline-at-eof ├── enforce-properties-keys-with-valid-class-names ├── enforce-settings-gradle-match-directories ├── enforce-shell-scripts-pass-shellcheck ├── enforce-version-bump ├── git-hooks │ ├── machete-status-branch │ └── post-commit ├── prohibit-direct-merges-to-master ├── prohibit-java-class-name-hardcode-in-strings ├── prohibit-java-code-commented-out ├── prohibit-java-lines-split-needlessly ├── prohibit-java-lines-split-needlessly.awk ├── prohibit-java-unused-custom-log ├── prohibit-javascript-unbounded-while-loops ├── prohibit-kotlin-undefined-property-keys ├── prohibit-kotlin-unsafe-cast ├── prohibit-non-ascii-characters ├── prohibit-properties-unused-keys ├── prohibit-tab-character ├── prohibit-trailing-whitespace ├── run-pre-build-checks ├── sandbox-setup-utils.sh ├── setup-multiroot-sandbox ├── utils.sh ├── validate-icons ├── validate-markdown-links └── validate-markdown-values ├── settings.gradle.kts ├── src ├── main │ └── resources │ │ └── META-INF │ │ ├── plugin.xml │ │ ├── pluginIcon.svg │ │ └── pluginIcon_dark.svg ├── test │ ├── java │ │ └── com │ │ │ └── virtuslab │ │ │ └── archunit │ │ │ ├── BackgroundTaskEnqueuingTestSuite.java │ │ │ ├── BaseArchUnitTestSuite.java │ │ │ ├── ClassStructureTestSuite.java │ │ │ ├── ForbiddenClassesTestSuite.java │ │ │ ├── ForbiddenFieldsTestSuite.java │ │ │ ├── ForbiddenMethodsTestSuite.java │ │ │ ├── MethodCallsTestSuite.java │ │ │ ├── NamingTestSuite.java │ │ │ └── UIThreadUnsafeMethodInvocationsTestSuite.java │ └── kotlin │ │ └── KPropertyTestSuite.kt └── uiTest │ ├── resources │ ├── common.rhino.js │ ├── ide.rhino.js │ ├── ideprobe-common.conf │ ├── ideprobe-linux.conf │ ├── ideprobe-macos.conf │ └── project.rhino.js │ └── scala │ └── com │ └── virtuslab │ └── gitmachete │ └── uitest │ ├── RunningIntelliJFixtureExtension.scala │ ├── UIScenarioSuite.scala │ ├── UISuite.scala │ └── UITestSuite.scala ├── testCommon ├── build.gradle.kts └── src │ └── testFixtures │ ├── java │ └── com │ │ └── virtuslab │ │ └── gitmachete │ │ └── testcommon │ │ ├── SetupScripts.java │ │ ├── TestFileUtils.java │ │ ├── TestGitRepository.java │ │ └── TestProcessUtils.java │ └── resources │ ├── common.sh │ ├── setup-for-diverged-and-older-than.sh │ ├── setup-for-overridden-fork-point.sh │ ├── setup-for-squash-merge.sh │ ├── setup-for-yellow-edges.sh │ ├── setup-readme-scenarios.sh │ ├── setup-with-multiple-remotes.sh │ ├── setup-with-no-remotes.sh │ └── setup-with-single-remote.sh └── version.gradle.kts /.gitattributes: -------------------------------------------------------------------------------- 1 | version.gradle.kts merge=version.gradle.kts 2 | -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | [core] 2 | autocrlf = input 3 | [diff] 4 | renameLimit = 999 5 | renames = copies 6 | [merge "version.gradle.kts"] 7 | name = version.gradle.kts merge driver 8 | driver = cp %B %A 9 | [status] 10 | relativePaths = false 11 | showUntrackedFiles = all 12 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Note that the rules in CODEOWNERS are NOT additive - 2 | # for any given file, only the LAST matching rule (and not all matching rules) applies. 3 | 4 | * @PawelLipski 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Request a new feature to the plugin 4 | title: '' 5 | labels: ["externally requested", "feature"] 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Feature description 11 | 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/help_or_support.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Help/Support 3 | about: Ask a question or request support about the plugin 4 | title: '' 5 | labels: ["externally requested", "question"] 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Question or problem description 11 | 12 | 13 | ## (optional) Screenshots 14 | 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.class 3 | *.crt 4 | .DS_Store/ 5 | **/.gradle/ 6 | /gradlew.bat 7 | /*.hprof 8 | /*.hprof.*/ 9 | /.idea/ 10 | /.intellijPlatform/ 11 | *.log 12 | *.pem 13 | .sdkmanrc 14 | -------------------------------------------------------------------------------- /DESCRIPTION.html: -------------------------------------------------------------------------------- 1 | Probably the sharpest git repository organizer and rebase/merge workflow automation tool you've ever seen!

2 | 3 | This plugin adds an extra tab in the Git tool window that gives an instant answer to the questions: 4 |
8 | 9 | The bird's eye view provided by Git Machete makes rebases/push/pulls hassle-free 10 | even when multiple branches are present in the repository: 11 | master/develop, your topic branches, teammate's branches checked out for review etc.

12 | 13 | Along these lines, Git Machete helps create and maintain small, focused, easy-to-review PRs.

14 | 15 | You can read more at the plugin's GitHub repository, 16 | as well as at the git-machete CLI GitHub repository. 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Virtus Lab sp. z o.o. (Ltd.) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Needed for GitHub Pages 2 | theme: jekyll-theme-midnight 3 | -------------------------------------------------------------------------------- /backend/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | api(project(":qual")) 5 | api(project(":branchLayout:api")) 6 | } 7 | 8 | commonsIO() 9 | lombok() 10 | vavr() 11 | slf4jLambdaApi() 12 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/GitMacheteException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class GitMacheteException extends Exception { 8 | public static GitMacheteException getOrWrap(Throwable e) { 9 | return e instanceof GitMacheteException gme ? gme : new GitMacheteException(e); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/GitMacheteMissingForkPointException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class GitMacheteMissingForkPointException extends GitMacheteException {} 8 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/ICommitOfManagedBranch.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import java.time.Instant; 4 | 5 | import org.checkerframework.checker.interning.qual.FindDistinct; 6 | import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; 7 | import org.checkerframework.checker.nullness.qual.Nullable; 8 | import org.checkerframework.common.value.qual.ArrayLen; 9 | 10 | /** 11 | * The only criterion for equality of any instances of any class implementing this interface is equality of {@link #getHash} 12 | */ 13 | public interface ICommitOfManagedBranch { 14 | String getShortMessage(); 15 | 16 | String getFullMessage(); 17 | 18 | @ArrayLen(40) 19 | String getHash(); 20 | 21 | @ArrayLen(7) 22 | String getShortHash(); 23 | 24 | Instant getCommitTime(); 25 | 26 | @EnsuresNonNullIf(expression = "#2", result = true) 27 | static boolean defaultEquals(@FindDistinct ICommitOfManagedBranch self, @Nullable Object other) { 28 | if (self == other) { 29 | return true; 30 | } else if (!(other instanceof ICommitOfManagedBranch)) { 31 | return false; 32 | } else { 33 | return self.getHash().equals(((ICommitOfManagedBranch) other).getHash()); 34 | } 35 | } 36 | 37 | static int defaultHashCode(ICommitOfManagedBranch self) { 38 | return self.getHash().hashCode(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/IForkPointCommitOfManagedBranch.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import io.vavr.collection.List; 4 | 5 | public interface IForkPointCommitOfManagedBranch extends ICommitOfManagedBranch { 6 | List getBranchesContainingInReflog(); 7 | 8 | /** 9 | * @return a subset of {@link #getBranchesContainingInReflog} that skips a reference to each remote tracking branch 10 | * such that a reference to its tracked local branch is also included. 11 | * For instance, if {@code getBranchesContainingInReflog} 12 | * returns {@code [develop, origin/develop, origin/master, fix]}, 13 | * then this method will return {@code [develop, origin/master, fix]}. 14 | */ 15 | List getUniqueBranchesContainingInReflog(); 16 | 17 | boolean isOverridden(); 18 | } 19 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/IGitMacheteRepository.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import io.vavr.collection.Set; 4 | import org.checkerframework.checker.nullness.qual.Nullable; 5 | 6 | import com.virtuslab.branchlayout.api.BranchLayout; 7 | import com.virtuslab.qual.guieffect.UIThreadUnsafe; 8 | 9 | public interface IGitMacheteRepository { 10 | @UIThreadUnsafe 11 | IGitMacheteRepositorySnapshot createSnapshotForLayout(BranchLayout branchLayout) throws GitMacheteException; 12 | 13 | @UIThreadUnsafe 14 | @Nullable 15 | ILocalBranchReference inferParentForLocalBranch( 16 | Set eligibleLocalBranchNames, 17 | String localBranchName) throws GitMacheteException; 18 | 19 | @UIThreadUnsafe 20 | IGitMacheteRepositorySnapshot discoverLayoutAndCreateSnapshot() throws GitMacheteException; 21 | } 22 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/IGitMacheteRepositoryCache.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import java.nio.file.Path; 4 | 5 | import com.virtuslab.qual.guieffect.UIThreadUnsafe; 6 | 7 | /** Each implementing class must have a public parameterless constructor. */ 8 | public interface IGitMacheteRepositoryCache { 9 | @FunctionalInterface 10 | public interface Injector { 11 | T inject(Class clazz); 12 | } 13 | 14 | @UIThreadUnsafe 15 | IGitMacheteRepository getInstance(Path rootDirectoryPath, Path mainGitDirectoryPath, Path worktreeGitDirectoryPath, 16 | Injector injector) 17 | throws GitMacheteException; 18 | } 19 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/IGitRebaseParameters.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | public interface IGitRebaseParameters { 4 | IManagedBranchSnapshot getCurrentBranch(); 5 | 6 | IManagedBranchSnapshot getNewBaseBranch(); 7 | 8 | ICommitOfManagedBranch getForkPointCommit(); 9 | } 10 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/ILocalBranchReference.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import io.vavr.NotImplementedError; 4 | 5 | public interface ILocalBranchReference extends IBranchReference { 6 | 7 | @Override 8 | default boolean isLocal() { 9 | return true; 10 | } 11 | 12 | @Override 13 | default ILocalBranchReference asLocal() { 14 | return this; 15 | } 16 | 17 | @Override 18 | default IRemoteTrackingBranchReference asRemote() { 19 | throw new NotImplementedError(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/INonRootManagedBranchSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import io.vavr.NotImplementedError; 4 | import io.vavr.collection.List; 5 | import org.checkerframework.checker.nullness.qual.Nullable; 6 | 7 | public interface INonRootManagedBranchSnapshot extends IManagedBranchSnapshot { 8 | 9 | @Override 10 | default boolean isRoot() { 11 | return false; 12 | } 13 | 14 | @Override 15 | default IRootManagedBranchSnapshot asRoot() { 16 | throw new NotImplementedError(); 17 | } 18 | 19 | @Override 20 | default INonRootManagedBranchSnapshot asNonRoot() { 21 | return this; 22 | } 23 | 24 | List getUniqueCommits(); 25 | 26 | List getCommitsUntilParent(); 27 | 28 | IManagedBranchSnapshot getParent(); 29 | 30 | SyncToParentStatus getSyncToParentStatus(); 31 | 32 | @Nullable 33 | IForkPointCommitOfManagedBranch getForkPoint(); 34 | 35 | IGitRebaseParameters getParametersForRebaseOntoParent() throws GitMacheteMissingForkPointException; 36 | } 37 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/IRemoteTrackingBranchReference.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import io.vavr.NotImplementedError; 4 | 5 | public interface IRemoteTrackingBranchReference extends IBranchReference { 6 | 7 | @Override 8 | default boolean isLocal() { 9 | return false; 10 | } 11 | 12 | @Override 13 | default ILocalBranchReference asLocal() { 14 | throw new NotImplementedError(); 15 | } 16 | 17 | @Override 18 | default IRemoteTrackingBranchReference asRemote() { 19 | return this; 20 | } 21 | 22 | String getRemoteName(); 23 | 24 | ILocalBranchReference getTrackedLocalBranch(); 25 | } 26 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/IRootManagedBranchSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import io.vavr.NotImplementedError; 4 | 5 | public interface IRootManagedBranchSnapshot extends IManagedBranchSnapshot { 6 | @Override 7 | default boolean isRoot() { 8 | return true; 9 | } 10 | 11 | @Override 12 | default IRootManagedBranchSnapshot asRoot() { 13 | return this; 14 | } 15 | 16 | @Override 17 | default INonRootManagedBranchSnapshot asNonRoot() { 18 | throw new NotImplementedError(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/MacheteFileReaderException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class MacheteFileReaderException extends GitMacheteException {} 8 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/OngoingRepositoryOperationType.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | public enum OngoingRepositoryOperationType { 4 | NO_OPERATION, APPLYING, BISECTING, CHERRY_PICKING, MERGING, REBASING, REVERTING 5 | } 6 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/RelationToRemote.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | import lombok.Data; 4 | import org.checkerframework.checker.nullness.qual.Nullable; 5 | 6 | @Data(staticConstructor = "of") 7 | // So that Interning Checker doesn't complain about enum comparison (by `equals` and not by `==`) in Lombok-generated `equals` 8 | @SuppressWarnings("interning:unnecessary.equals") 9 | public class RelationToRemote { 10 | 11 | public static RelationToRemote noRemotes() { 12 | return of(SyncToRemoteStatus.NoRemotes, null); 13 | } 14 | 15 | public static RelationToRemote untracked() { 16 | return of(SyncToRemoteStatus.Untracked, null); 17 | } 18 | 19 | private final SyncToRemoteStatus syncToRemoteStatus; 20 | private final @Nullable String remoteName; 21 | } 22 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/SyncToParentStatus.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | public enum SyncToParentStatus { 4 | InSync, MergedToParent, InSyncButForkPointOff, OutOfSync 5 | } 6 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/api/SyncToRemoteStatus.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.api; 2 | 3 | public enum SyncToRemoteStatus { 4 | NoRemotes, Untracked, InSyncToRemote, AheadOfRemote, BehindRemote, DivergedFromAndNewerThanRemote, DivergedFromAndOlderThanRemote 5 | } 6 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/hooks/ExecutionResult.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.hooks; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class ExecutionResult { 7 | private final int exitCode; 8 | private final String stdout; 9 | private final String stderr; 10 | } 11 | -------------------------------------------------------------------------------- /backend/api/src/main/java/com/virtuslab/gitmachete/backend/hooks/OnExecutionTimeout.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.hooks; 2 | 3 | public enum OnExecutionTimeout { 4 | RETURN_NULL, THROW_EXCEPTION 5 | } 6 | -------------------------------------------------------------------------------- /backend/impl/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | implementation(project(":gitCore:api")) 5 | 6 | api(project(":backend:api")) 7 | api(project(":branchLayout:api")) 8 | 9 | testImplementation(testFixtures(project(":testCommon"))) 10 | testImplementation(project(":branchLayout:impl")) 11 | testImplementation(project(":gitCore:jGit")) 12 | } 13 | 14 | commonsIO() 15 | junit() 16 | junitParams() 17 | lombok() 18 | mockito() 19 | slf4jLambdaApi() 20 | vavr() 21 | 22 | applySubtypingChecker() 23 | 24 | tasks.register("regenerateCliOutputs") { 25 | group = "Execution" 26 | description = "Regenerate CLI outputs used for comparison in tests" 27 | classpath = sourceSets["test"].runtimeClasspath 28 | mainClass.set("com.virtuslab.gitmachete.backend.integration.RegenerateCliOutputs") 29 | args = sourceSets["test"].resources.srcDirs.map { it.absolutePath }.toList() 30 | } 31 | -------------------------------------------------------------------------------- /backend/impl/src/main/java/com/virtuslab/gitmachete/backend/impl/BaseBranchReference.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.impl; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.ToString; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.backend.api.IBranchReference; 9 | 10 | @Getter 11 | @RequiredArgsConstructor 12 | @ToString 13 | public abstract class BaseBranchReference implements IBranchReference { 14 | private final String name; 15 | private final String fullName; 16 | 17 | @Override 18 | public final boolean equals(@Nullable Object other) { 19 | return IBranchReference.defaultEquals(this, other); 20 | } 21 | 22 | @Override 23 | public final int hashCode() { 24 | return IBranchReference.defaultHashCode(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /backend/impl/src/main/java/com/virtuslab/gitmachete/backend/impl/GitRebaseParameters.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.impl; 2 | 3 | import lombok.Data; 4 | import lombok.ToString; 5 | 6 | import com.virtuslab.gitmachete.backend.api.ICommitOfManagedBranch; 7 | import com.virtuslab.gitmachete.backend.api.IGitRebaseParameters; 8 | import com.virtuslab.gitmachete.backend.api.IManagedBranchSnapshot; 9 | 10 | @Data 11 | public class GitRebaseParameters implements IGitRebaseParameters { 12 | private final IManagedBranchSnapshot currentBranch; 13 | private final IManagedBranchSnapshot newBaseBranch; 14 | private final ICommitOfManagedBranch forkPointCommit; 15 | 16 | @ToString.Include(name = "currentBranch") 17 | private String getCurrentBranchName() { 18 | return currentBranch.getName(); 19 | } 20 | 21 | @ToString.Include(name = "newBaseBranch") 22 | private String getNewBaseBranchName() { 23 | return newBaseBranch.getName(); 24 | } 25 | 26 | @ToString.Include(name = "forkPointCommit") 27 | private String getForkPointCommitShortHash() { 28 | return forkPointCommit.getShortHash(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /backend/impl/src/main/java/com/virtuslab/gitmachete/backend/impl/LocalBranchReference.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.backend.impl; 2 | 3 | import lombok.Getter; 4 | import lombok.ToString; 5 | 6 | import com.virtuslab.gitcore.api.IGitCoreLocalBranchSnapshot; 7 | import com.virtuslab.gitmachete.backend.api.ILocalBranchReference; 8 | 9 | @Getter 10 | @ToString 11 | public final class LocalBranchReference extends BaseBranchReference implements ILocalBranchReference { 12 | private LocalBranchReference(String name, String fullName) { 13 | super(name, fullName); 14 | } 15 | 16 | public static LocalBranchReference toLocalBranchReference(IGitCoreLocalBranchSnapshot coreLocalBranch) { 17 | return new LocalBranchReference( 18 | coreLocalBranch.getName(), 19 | coreLocalBranch.getFullName()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-diverged-and-older-than.sh-discover.txt: -------------------------------------------------------------------------------- 1 | master (behind origin) 2 | | 3 | | HOTFIX Add the trigger (amended) 4 | o-hotfix/add-trigger * (diverged from origin) <3 files> 5 | 6 | develop (ahead of origin) <6 files> 7 | | 8 | | Allow ownership links 9 | | 1st round of fixes 10 | x-allow-ownership-link (diverged from & older than origin) <4 files> 11 | | 12 | | Build arbitrarily long chains 13 | x-build-chain (untracked) <4 files> 14 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-diverged-and-older-than.sh-status.txt: -------------------------------------------------------------------------------- 1 | develop (ahead of origin) <6 files> 2 | | 3 | | Allow ownership links 4 | | 1st round of fixes 5 | x-allow-ownership-link PR #123 (diverged from & older than origin) <4 files> 6 | | | 7 | | | Build arbitrarily long chains 8 | | x-build-chain (untracked) <4 files> 9 | | 10 | m-call-ws PR #124 (ahead of origin) <6 files> 11 | 12 | master (behind origin) 13 | | 14 | | HOTFIX Add the trigger (amended) 15 | o-hotfix/add-trigger * (diverged from origin) <3 files> 16 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-overridden-fork-point.sh-discover.txt: -------------------------------------------------------------------------------- 1 | develop <2 files> 2 | | 3 | | Allow ownership links 4 | o-allow-ownership-link (untracked) <3 files> 5 | | 6 | | Build arbitrarily long chains 7 | o-build-chain * <4 files> 8 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-overridden-fork-point.sh-status.txt: -------------------------------------------------------------------------------- 1 | develop <2 files> 2 | | 3 | | Build arbitrarily long chains 4 | o-build-chain * <4 files> 5 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-squash-merge.sh-discover.txt: -------------------------------------------------------------------------------- 1 | master 2 | | 3 | | Build arbitrarily long chains 4 | x-build-chain * <6 files> 5 | 6 | develop (untracked) <3 files> 7 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-squash-merge.sh-status.txt: -------------------------------------------------------------------------------- 1 | develop (untracked) <3 files> 2 | | 3 | m-allow-ownership-link PR #123 (untracked) <3 files> 4 | | 5 | | Build arbitrarily long chains 6 | x-build-chain * <6 files> 7 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-yellow-edges.sh-discover.txt: -------------------------------------------------------------------------------- 1 | master 2 | | 3 | o-behind/hotfix/add-trigger (untracked) <2 files> 4 | | 5 | | HOTFIX Add the trigger (amended) 6 | o-hotfix/add-trigger * (diverged from origin) <3 files> 7 | 8 | develop (untracked) <2 files> 9 | | 10 | | Allow ownership links 11 | o-allow-ownership-link <3 files> 12 | | 13 | | Build arbitrarily long chains 14 | o-build-chain (untracked) <4 files> 15 | | 16 | | Call web service 17 | | 1st round of fixes 18 | | 2nd round of fixes 19 | o-call-ws (ahead of origin) <7 files> 20 | | 21 | | Drop unneeded SQL constraints 22 | x-drop-constraint (untracked) <7 files> 23 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-for-yellow-edges.sh-status.txt: -------------------------------------------------------------------------------- 1 | develop (untracked) <2 files> 2 | | 3 | | Allow ownership links -> fork point ??? commit 8ca0987 seems to be a part of the unique history of allow-ownership-link 4 | | Build arbitrarily long chains 5 | ?-build-chain (untracked) <4 files> 6 | | 7 | | Allow ownership links 8 | | Build arbitrarily long chains -> fork point ??? commit a8d7750 seems to be a part of the unique history of build-chain 9 | | Call web service 10 | | 1st round of fixes 11 | | 2nd round of fixes 12 | ?-call-ws PR #124 (ahead of origin) <7 files> 13 | 14 | master 15 | | 16 | | HOTFIX Add the trigger (amended) 17 | o-hotfix/add-trigger * (diverged from origin) <3 files> 18 | | 19 | x-behind/hotfix/add-trigger (untracked) <2 files> 20 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-with-multiple-remotes.sh-discover.txt: -------------------------------------------------------------------------------- 1 | master 2 | 3 | develop <3 files> 4 | 5 | allow-ownership-link (ahead of remote1) <4 files> 6 | 7 | build-chain (untracked) <4 files> 8 | 9 | call-ws (ahead of remote1) <6 files> 10 | 11 | drop-constraint (untracked) <6 files> 12 | 13 | hotfix/add-trigger * (diverged from remote2) <3 files> 14 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-with-multiple-remotes.sh-status.txt: -------------------------------------------------------------------------------- 1 | develop <3 files> 2 | | 3 | | Allow ownership links 4 | | 1st round of fixes 5 | x-allow-ownership-link PR #123 (ahead of remote1) <4 files> 6 | | | 7 | | | Build arbitrarily long chains 8 | | x-build-chain (untracked) <4 files> 9 | | 10 | | Call web service 11 | | 1st round of fixes 12 | | 2nd round of fixes 13 | o-call-ws PR #124 (ahead of remote1) <6 files> 14 | 15 | master 16 | | 17 | | HOTFIX Add the trigger (amended) 18 | o-hotfix/add-trigger * (diverged from remote2) <3 files> 19 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-with-no-remotes.sh-discover.txt: -------------------------------------------------------------------------------- 1 | develop * <3 files> 2 | | 3 | | Allow ownership links 4 | | 1st round of fixes 5 | x-allow-ownership-link <4 files> 6 | | 7 | | Allow ownership links 8 | | Build arbitrarily long chains 9 | x-build-chain <4 files> 10 | | 11 | | Call web service 12 | | 1st round of fixes 13 | | 2nd round of fixes 14 | o-call-ws <6 files> 15 | | | 16 | | | Drop unneeded SQL constraints 17 | | x-drop-constraint <6 files> 18 | | | 19 | | | Evict conflicting dependencies 20 | | o-evict-deps <7 files> 21 | | | 22 | | | Fix component labels 23 | | o-fix/component-labels <8 files> 24 | | | 25 | | | Introduce global context 26 | | o-global-context <9 files> 27 | | | 28 | | | Enable Scala/Python interoperability 29 | | o-interop-scala-python <10 files> 30 | | | 31 | | | Enforce the use of Java 11 32 | | o-java-11-enforce <11 files> 33 | | 34 | | Allow ownership links 35 | | 1st round of fixes 36 | | Kill the process after 10 seconds 37 | x-kill-process <5 files> 38 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-with-no-remotes.sh-status.txt: -------------------------------------------------------------------------------- 1 | develop * <3 files> 2 | | 3 | | Allow ownership links 4 | | 1st round of fixes 5 | x-allow-ownership-link PR #123 <4 files> 6 | | | 7 | | | Build arbitrarily long chains 8 | | x-build-chain <4 files> 9 | | 10 | | Call web service 11 | | 1st round of fixes 12 | | 2nd round of fixes 13 | o-call-ws PR #124 <6 files> 14 | | 15 | | Drop unneeded SQL constraints 16 | x-drop-constraint <6 files> 17 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-with-single-remote.sh-discover.txt: -------------------------------------------------------------------------------- 1 | master 2 | | 3 | | HOTFIX Add the trigger 4 | | HOTFIX Add the trigger - fixes 5 | o-hotfix/add-trigger (diverged from & older than origin) <4 files> 6 | 7 | develop <3 files> 8 | | 9 | | Allow ownership links 10 | x-allow-ownership-link (behind origin) <3 files> 11 | | | 12 | | | 1st round of fixes -> fork point ??? commit 9d422de seems to be a part of the unique history of allow-ownership-link 13 | | | Use new icons 14 | | ?-update-icons (behind origin) <5 files> 15 | | | 16 | | | Build arbitrarily long chains 17 | | o-build-chain (untracked) <6 files> 18 | | 19 | | Call web service 20 | | 1st round of fixes 21 | | 2nd round of fixes 22 | o-call-ws (ahead of origin) <6 files> 23 | | 24 | | Drop unneeded SQL constraints 25 | x-drop-constraint (untracked) <6 files> 26 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/setup-with-single-remote.sh-status.txt: -------------------------------------------------------------------------------- 1 | develop <3 files> 2 | | 3 | | Allow ownership links 4 | x-allow-ownership-link PR #123 (behind origin) <3 files> 5 | | | 6 | | | 1st round of fixes -> fork point ??? commit 9d422de seems to be a part of the unique history of allow-ownership-link 7 | | | Use new icons 8 | | ?-update-icons (behind origin) <5 files> 9 | | | 10 | | | 1st round of fixes 11 | | | Use new icons -> fork point ??? commit 89fd9a5 seems to be a part of the unique history of update-icons 12 | | | Build arbitrarily long chains 13 | | ?-build-chain (untracked) <6 files> 14 | | 15 | | Call web service 16 | | 1st round of fixes 17 | | 2nd round of fixes 18 | o-call-ws PR #124 (ahead of origin) <6 files> 19 | 20 | master 21 | | 22 | | HOTFIX Add the trigger 23 | | HOTFIX Add the trigger - fixes 24 | o-hotfix/add-trigger (diverged from & older than origin) <4 files> 25 | -------------------------------------------------------------------------------- /backend/impl/src/test/resources/version.txt: -------------------------------------------------------------------------------- 1 | git-machete version 3.23.2 2 | -------------------------------------------------------------------------------- /branchLayout/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { api(project(":qual")) } 4 | 5 | lombok() 6 | junit() 7 | vavr() 8 | -------------------------------------------------------------------------------- /branchLayout/api/src/main/java/com/virtuslab/branchlayout/api/BranchLayoutException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.branchlayout.api; 2 | 3 | import lombok.Getter; 4 | import org.checkerframework.checker.index.qual.Positive; 5 | import org.checkerframework.checker.nullness.qual.Nullable; 6 | 7 | public class BranchLayoutException extends Exception { 8 | 9 | @Getter 10 | private final @Nullable @Positive Integer errorLine; 11 | 12 | public BranchLayoutException(@Nullable @Positive Integer errorLine, String message) { 13 | super(message + (errorLine != null ? ". Problematic line number: " + errorLine : "")); 14 | this.errorLine = errorLine; 15 | } 16 | 17 | public BranchLayoutException(String message) { 18 | this(null, message); 19 | } 20 | 21 | public BranchLayoutException(@Nullable @Positive Integer errorLine, String message, Throwable e) { 22 | super(message, e); 23 | this.errorLine = errorLine; 24 | } 25 | 26 | public BranchLayoutException(String message, Throwable e) { 27 | this(null, message, e); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /branchLayout/api/src/main/java/com/virtuslab/branchlayout/api/EntryDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.branchlayout.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class EntryDoesNotExistException extends BranchLayoutException {} 8 | -------------------------------------------------------------------------------- /branchLayout/api/src/main/java/com/virtuslab/branchlayout/api/EntryIsDescendantOfException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.branchlayout.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class EntryIsDescendantOfException extends BranchLayoutException {} 8 | -------------------------------------------------------------------------------- /branchLayout/api/src/main/java/com/virtuslab/branchlayout/api/readwrite/IBranchLayoutReader.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.branchlayout.api.readwrite; 2 | 3 | import java.io.InputStream; 4 | 5 | import com.virtuslab.branchlayout.api.BranchLayout; 6 | import com.virtuslab.branchlayout.api.BranchLayoutException; 7 | 8 | public interface IBranchLayoutReader { 9 | BranchLayout read(InputStream inputStream) throws BranchLayoutException; 10 | } 11 | -------------------------------------------------------------------------------- /branchLayout/api/src/main/java/com/virtuslab/branchlayout/api/readwrite/IBranchLayoutWriter.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.branchlayout.api.readwrite; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | import io.vavr.collection.List; 7 | 8 | import com.virtuslab.branchlayout.api.BranchLayout; 9 | 10 | public interface IBranchLayoutWriter { 11 | void write(OutputStream outputStream, BranchLayout branchLayout, IndentSpec indentSpec) throws IOException; 12 | 13 | IndentSpec deriveIndentSpec(List lines); 14 | } 15 | -------------------------------------------------------------------------------- /branchLayout/api/src/main/java/com/virtuslab/branchlayout/api/readwrite/IndentSpec.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.branchlayout.api.readwrite; 2 | 3 | import lombok.Data; 4 | import org.checkerframework.checker.index.qual.Positive; 5 | 6 | @Data 7 | public class IndentSpec { 8 | public static final char TAB = '\t'; 9 | public static final char SPACE = ' '; 10 | 11 | private final char indentCharacter; 12 | 13 | private final @Positive int indentWidth; 14 | } 15 | -------------------------------------------------------------------------------- /branchLayout/impl/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | api(project(":qual")) 5 | api(project(":branchLayout:api")) 6 | } 7 | 8 | junit() 9 | lombok() 10 | slf4jLambdaApi() 11 | slf4jSimple("test") 12 | vavr() 13 | -------------------------------------------------------------------------------- /buildSrc/gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [libraries] 2 | jsoup = "org.jsoup:jsoup:1.20.1" 3 | junit-api = "org.junit.jupiter:junit-jupiter-api:5.13.1" 4 | # Plugin packages 5 | # This way of applying the plugins is needed for the build-related code in buildSrc/src/main/, 6 | # see https://docs.gradle.org/current/samples/sample_convention_plugins.html#things_to_note. 7 | pluginPackages-checkerFramework = "org.checkerframework:checkerframework-gradle-plugin:0.6.55" 8 | pluginPackages-grgit = "org.ajoberstar.grgit:grgit-gradle:5.3.0" 9 | pluginPackages-jetbrains-kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22" 10 | pluginPackages-spotless = "com.diffplug.spotless:spotless-plugin-gradle:7.0.4" 11 | 12 | [plugins] 13 | taskTree = "com.dorongold.task-tree:4.0.1" 14 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/com/virtuslab/gitmachete/buildsrc/Checkstyle.kt: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.buildsrc 2 | 3 | import org.gradle.api.Project 4 | import org.gradle.api.plugins.quality.Checkstyle 5 | import org.gradle.api.plugins.quality.CheckstyleExtension 6 | import org.gradle.api.plugins.quality.CheckstylePlugin 7 | import org.gradle.kotlin.dsl.apply 8 | import org.gradle.kotlin.dsl.configure 9 | import org.gradle.kotlin.dsl.named 10 | 11 | fun Project.configureCheckstyle() { 12 | apply() 13 | configure { 14 | tasks.named("checkstyleTest") { enabled = false } 15 | 16 | configProperties = mapOf("rootCheckstyleConfigDir" to "$rootDir/config/checkstyle") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/com/virtuslab/gitmachete/buildsrc/IntellijVersionHelper.kt: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.buildsrc 2 | 3 | object IntellijVersionHelper { 4 | fun buildNumberToMajorVersion(buildNumber: String): String = "20${buildNumber.substring(0, 2)}.${buildNumber.substring(2, 3)}" 5 | 6 | fun versionToBuildNumber(version: String): String = version.substring(2, 6).filter { it != '.' } 7 | 8 | fun versionToMajorVersion(version: String): String = version.substring(0, 6) 9 | 10 | infix fun String.versionIsNewerThan(rhsVersion: String): Boolean { 11 | val lhsSplit = this.split('.') 12 | val rhsSplit = rhsVersion.split('.') 13 | 14 | val firstDiff = lhsSplit.zip(rhsSplit).find { it.first != it.second } 15 | 16 | // 8.0.6 is older than 8.0.6.0, but zipped they will look like this: [(8,8), (0,0), (6,6)] 17 | if (firstDiff == null) { 18 | return lhsSplit.size > rhsSplit.size 19 | } 20 | 21 | return Integer.parseInt(firstDiff.first) > Integer.parseInt(firstDiff.second) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/com/virtuslab/gitmachete/buildsrc/PropertiesHelper.kt: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.buildsrc 2 | 3 | import org.gradle.internal.util.PropertiesUtils 4 | import java.io.File 5 | import java.util.* 6 | 7 | object PropertiesHelper { 8 | fun Properties.getPropertyOrNullIfEmpty(key: String): String? { 9 | val value = getProperty(key) 10 | return if (value == "") null else value 11 | } 12 | 13 | fun getProperties(file: File): Properties { 14 | val properties = Properties() 15 | properties.load(file.inputStream()) 16 | return properties 17 | } 18 | 19 | fun storeProperties(properties: Properties, file: File) { 20 | PropertiesUtils.store(properties, file) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /buildSrc/src/test/kotlin/com/virtuslab/gitmachete/buildsrc/IntellijVersionHelperTest.kt: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.buildsrc 2 | 3 | import com.virtuslab.gitmachete.buildsrc.IntellijVersionHelper.versionIsNewerThan 4 | import org.junit.jupiter.api.Assertions.assertFalse 5 | import org.junit.jupiter.api.Assertions.assertTrue 6 | import org.junit.jupiter.api.Test 7 | 8 | class IntellijVersionHelperTest { 9 | @Test 10 | fun shouldRecognizeEqualVersions() { 11 | val version1 = "123.1234.56789" 12 | val version2 = "0.0.0" 13 | assertFalse(version1 versionIsNewerThan version1) 14 | assertFalse(version2 versionIsNewerThan version2) 15 | } 16 | 17 | @Test 18 | fun shouldRecognizeNotEqualVersions() { 19 | val olderVersion = "1111.11.111" 20 | val newerVersions = listOf("1112.11.111", "1111.12.111", "1111.11.112", "1111.11.111.0") 21 | 22 | for (newerVersion in newerVersions) assertTrue(newerVersion versionIsNewerThan olderVersion) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /buildSrc/src/test/kotlin/com/virtuslab/gitmachete/buildsrc/IntellijVersionsTest.kt: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.buildsrc 2 | 3 | import org.junit.jupiter.api.Assertions.assertEquals 4 | import org.junit.jupiter.api.Test 5 | 6 | class IntellijVersionsTest { 7 | @Test 8 | fun shouldResolveIntelliJVersions() { 9 | val iv = IntellijVersions( 10 | latestMinorsOfOldSupportedMajors = listOf("2020.3.4", "2021.1.3", "2021.2.4", "2021.3.3", "2022.1.4"), 11 | eapOfLatestSupportedMajor = null, 12 | earliestSupportedMajor = "2020.3", 13 | latestStable = "2022.2.2", 14 | buildTarget = "2022.2.2", 15 | latestSupportedMajor = "2022.2", 16 | ) 17 | 18 | assertEquals(listOf("2020.3.4", "2021.1.3", "2021.2.4", "2021.3.3", "2022.1.4"), iv.resolveIntelliJVersions("latestMinorsOfOldSupportedMajors")) 19 | assertEquals(listOf(), iv.resolveIntelliJVersions("eapOfLatestSupportedMajor")) 20 | assertEquals(listOf("2020.3"), iv.resolveIntelliJVersions("earliestSupportedMajor")) 21 | assertEquals(listOf("2022.2.2"), iv.resolveIntelliJVersions("latestStable")) 22 | assertEquals(listOf("2022.2.2"), iv.resolveIntelliJVersions("buildTarget")) 23 | assertEquals(listOf("2022.2"), iv.resolveIntelliJVersions("latestSupportedMajor")) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /config/checker/java.lang.astub: -------------------------------------------------------------------------------- 1 | import org.checkerframework.checker.nullness.qual.NonNull; 2 | import org.checkerframework.checker.nullness.qual.Nullable; 3 | 4 | package java.lang.reflect; 5 | 6 | class Constructor { 7 | @NonNull T newInstance(@Nullable Object... initargs); 8 | } 9 | 10 | class Method { 11 | // The first param may be null in case of static method calls. 12 | Object invoke(@Nullable Object obj, Object... args); 13 | } 14 | -------------------------------------------------------------------------------- /config/checker/org.apache.commons.astub: -------------------------------------------------------------------------------- 1 | import org.checkerframework.checker.nullness.qual.Nullable; 2 | import org.checkerframework.checker.nullness.qual.PolyNull; 3 | 4 | package org.apache.commons.lang3.exception; 5 | 6 | class ExceptionUtils { 7 | static @Nullable String getRootCauseMessage(Throwable th); 8 | } 9 | 10 | 11 | package org.apache.commons.text; 12 | 13 | class StringEscapeUtils { 14 | static @PolyNull String escapeHtml4(@PolyNull String input); 15 | } 16 | -------------------------------------------------------------------------------- /docs/checkout.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/checkout.gif -------------------------------------------------------------------------------- /docs/debug_configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/debug_configuration.png -------------------------------------------------------------------------------- /docs/discover.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/discover.gif -------------------------------------------------------------------------------- /docs/fast_forward.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/fast_forward.gif -------------------------------------------------------------------------------- /docs/left_bar_actions/discover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/discover.png -------------------------------------------------------------------------------- /docs/left_bar_actions/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/edit.png -------------------------------------------------------------------------------- /docs/left_bar_actions/fastForward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/fastForward.png -------------------------------------------------------------------------------- /docs/left_bar_actions/fetch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/fetch.png -------------------------------------------------------------------------------- /docs/left_bar_actions/ffmerge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/ffmerge.png -------------------------------------------------------------------------------- /docs/left_bar_actions/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/help.png -------------------------------------------------------------------------------- /docs/left_bar_actions/incomingChangesOn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/incomingChangesOn.png -------------------------------------------------------------------------------- /docs/left_bar_actions/macheteLogoIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/macheteLogoIcon.png -------------------------------------------------------------------------------- /docs/left_bar_actions/merge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/merge.png -------------------------------------------------------------------------------- /docs/left_bar_actions/overrideForkPoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/overrideForkPoint.png -------------------------------------------------------------------------------- /docs/left_bar_actions/pull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/pull.png -------------------------------------------------------------------------------- /docs/left_bar_actions/push.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/push.png -------------------------------------------------------------------------------- /docs/left_bar_actions/rebase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/rebase.png -------------------------------------------------------------------------------- /docs/left_bar_actions/reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/reset.png -------------------------------------------------------------------------------- /docs/left_bar_actions/slideIn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/slideIn.png -------------------------------------------------------------------------------- /docs/left_bar_actions/slideOut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/slideOut.png -------------------------------------------------------------------------------- /docs/left_bar_actions/squash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/squash.png -------------------------------------------------------------------------------- /docs/left_bar_actions/toggleListingCommits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/toggleListingCommits.png -------------------------------------------------------------------------------- /docs/left_bar_actions/traverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/left_bar_actions/traverse.png -------------------------------------------------------------------------------- /docs/machete_file_editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/machete_file_editor.gif -------------------------------------------------------------------------------- /docs/medium-blog-post/actions-after_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/medium-blog-post/actions-after_dark.png -------------------------------------------------------------------------------- /docs/medium-blog-post/actions-before_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/medium-blog-post/actions-before_dark.png -------------------------------------------------------------------------------- /docs/medium-blog-post/actions_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/medium-blog-post/actions_dark.png -------------------------------------------------------------------------------- /docs/medium-blog-post/gmt_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/medium-blog-post/gmt_dark.png -------------------------------------------------------------------------------- /docs/medium-blog-post/machete-file_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/medium-blog-post/machete-file_dark.png -------------------------------------------------------------------------------- /docs/medium-blog-post/rebase-gm_dark-4x3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/medium-blog-post/rebase-gm_dark-4x3.gif -------------------------------------------------------------------------------- /docs/medium-blog-post/rebase-idea_dark-4x3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/medium-blog-post/rebase-idea_dark-4x3.gif -------------------------------------------------------------------------------- /docs/merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/merge.gif -------------------------------------------------------------------------------- /docs/multi_repo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/multi_repo.gif -------------------------------------------------------------------------------- /docs/open_git_machete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/open_git_machete.gif -------------------------------------------------------------------------------- /docs/override_forkpoint.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/override_forkpoint.gif -------------------------------------------------------------------------------- /docs/plugins.jetbrains.com/getting_started.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 |
  1. Install the plugin from Marketplace
  2. 5 |
  3. 6 | Open Git Machete tab: 7 |
      8 |
    • Navigate Git (tool window) -> Git Machete (tab)
    • 9 |
    • Or use key shortcut: Ctrl + Alt + Shift + M (Command + Option + Shift + M on macOS)
    • 10 |
    11 | Branch layout will be automatically discovered and a tree-shaped graph of branches will show up. 12 |
  4. 13 |
  5. From the left side plugin's toolbar select Open Machete File
  6. 14 |
  7. Edit the file (.git/machete) if needed to reflect the actual branch layout; the completion (Ctrl + Space) may be useful
  8. 15 |
  9. 16 | Start to use it! :) Try Sync to Parent by Rebase... and the other toolbar actions.
    17 | There is also a bunch of actions available from the context menu, once you right-click a branch from the graph. 18 |
  10. 19 |
20 | -------------------------------------------------------------------------------- /docs/plugins.jetbrains.com/sample_status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/plugins.jetbrains.com/sample_status.png -------------------------------------------------------------------------------- /docs/plugins.jetbrains.com/scenario-1-review.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/plugins.jetbrains.com/scenario-1-review.gif -------------------------------------------------------------------------------- /docs/plugins.jetbrains.com/scenario-2-branch-update.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/plugins.jetbrains.com/scenario-2-branch-update.gif -------------------------------------------------------------------------------- /docs/plugins.jetbrains.com/scenario-3-stacked-prs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/plugins.jetbrains.com/scenario-3-stacked-prs.gif -------------------------------------------------------------------------------- /docs/plugins.jetbrains.com/scenario-4-ff-merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/plugins.jetbrains.com/scenario-4-ff-merge.gif -------------------------------------------------------------------------------- /docs/pull.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/pull.gif -------------------------------------------------------------------------------- /docs/push.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/push.gif -------------------------------------------------------------------------------- /docs/rebase.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/rebase.gif -------------------------------------------------------------------------------- /docs/rename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/rename.png -------------------------------------------------------------------------------- /docs/reset.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/reset.gif -------------------------------------------------------------------------------- /docs/sample_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/sample_graph.png -------------------------------------------------------------------------------- /docs/show_in_git_log.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/show_in_git_log.gif -------------------------------------------------------------------------------- /docs/slide_in_existing_branch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/slide_in_existing_branch.gif -------------------------------------------------------------------------------- /docs/slide_in_new_branch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/slide_in_new_branch.gif -------------------------------------------------------------------------------- /docs/slide_in_reattach_with_children.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/slide_in_reattach_with_children.gif -------------------------------------------------------------------------------- /docs/slide_in_reattach_without_children.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/slide_in_reattach_without_children.gif -------------------------------------------------------------------------------- /docs/slide_in_use_cases.md: -------------------------------------------------------------------------------- 1 | # Overview through Slide In use cases 2 | 3 | This document is an overview through the use cases. 4 | It should help to implement and understand the feature. 5 | 6 | ## Use cases 7 | 8 | | UC ID | Local branch exists | Branch entry exists | Estimated frequency | 9 | | :---: | :---: | :---: | :---: | 10 | | 1 | false | false | ~ 75% | 11 | | 2 | false | true | < 1% | 12 | | 3 | true | false | ~ 25% | 13 | | 4 | true | true | < 1% | 14 | 15 | ## Slide In - Logic 16 | 17 | This specification covers all the cases. 18 | 19 | - When the **entry does not exist**, it must be added under the given branch. 20 | - When the **entry exists under the given parent**, branch layout must not be affected. 21 | - When the **entry exists under other parent or is root**, it must be reattached under the given parent. 22 | 23 | **IMPORTANT NOTE:** 24 | Sliding in an entry under itself or any of its descendants in the branch layout must not be allowed. 25 | -------------------------------------------------------------------------------- /docs/slide_out_leaf_node.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/slide_out_leaf_node.gif -------------------------------------------------------------------------------- /docs/slide_out_non_leaf_node.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/slide_out_non_leaf_node.gif -------------------------------------------------------------------------------- /docs/squash.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/squash.gif -------------------------------------------------------------------------------- /docs/toggle_listing_commits.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/docs/toggle_listing_commits.gif -------------------------------------------------------------------------------- /frontend/actions/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | implementation(project(":backend:api")) 5 | implementation(project(":branchLayout:api")) 6 | implementation(project(":frontend:base")) 7 | implementation(project(":frontend:file")) 8 | implementation(project(":frontend:resourcebundles")) 9 | implementation(project(":frontend:ui:api")) 10 | } 11 | 12 | apacheCommonsText() 13 | applyKotlinConfig() 14 | lombok() 15 | slf4jLambdaApi() 16 | vavr() 17 | 18 | applyI18nFormatterAndTaintingCheckers() 19 | applySubtypingChecker() 20 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/base/IBranchNameProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.base; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import org.checkerframework.checker.nullness.qual.Nullable; 5 | 6 | public interface IBranchNameProvider { 7 | @Nullable 8 | String getNameOfBranchUnderAction(AnActionEvent anActionEvent); 9 | } 10 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/base/IWithLogger.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.base; 2 | 3 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 4 | 5 | public interface IWithLogger { 6 | LambdaLogger log(); 7 | 8 | /** 9 | * @return {@code false} if the execution on the current thread is in a context where logging should be avoided 10 | * (because e.g. it would lead to a massive spam in the logs); 11 | * {@code true} otherwise 12 | */ 13 | boolean isLoggingAcceptable(); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/common/ActionUtils.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.common; 2 | 3 | import org.checkerframework.checker.nullness.qual.Nullable; 4 | 5 | public final class ActionUtils { 6 | private ActionUtils() {} 7 | 8 | public static String createRefspec(String sourceBranchFullName, String targetBranchFullName, boolean allowNonFastForward) { 9 | return (allowNonFastForward ? "+" : "") + sourceBranchFullName + ":" + targetBranchFullName; 10 | } 11 | 12 | public static String getQuotedStringOrCurrent(@Nullable String string) { 13 | return string != null ? "'${string}'" : "current"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/common/FetchUpToDateTimeoutStatus.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.common; 2 | 3 | import git4idea.repo.GitRepository; 4 | 5 | public final class FetchUpToDateTimeoutStatus { 6 | private FetchUpToDateTimeoutStatus() {} 7 | 8 | public static final long FETCH_ALL_UP_TO_DATE_TIMEOUT_MILLIS = 60 * 1000; 9 | public static final String FETCH_ALL_UP_TO_DATE_TIMEOUT_AS_STRING = "a minute"; 10 | 11 | @SuppressWarnings("ConstantName") 12 | private static final java.util.concurrent.ConcurrentMap lastFetchTimeMillisByRepositoryName = new java.util.concurrent.ConcurrentHashMap<>(); 13 | 14 | public static boolean isUpToDate(GitRepository gitRepository) { 15 | String repoName = gitRepository.getRoot().getName(); 16 | long lftm = lastFetchTimeMillisByRepositoryName.getOrDefault(repoName, 0L); 17 | return System.currentTimeMillis() < lftm + FETCH_ALL_UP_TO_DATE_TIMEOUT_MILLIS; 18 | } 19 | 20 | public static void update(String repoName) { 21 | lastFetchTimeMillisByRepositoryName.put(repoName, System.currentTimeMillis()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/common/MergeProps.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.common; 2 | 3 | import lombok.Value; 4 | 5 | import com.virtuslab.gitmachete.backend.api.IBranchReference; 6 | import com.virtuslab.gitmachete.backend.api.ILocalBranchReference; 7 | 8 | @Value 9 | public class MergeProps { 10 | ILocalBranchReference movingBranch; 11 | IBranchReference stayingBranch; 12 | } 13 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/common/SlideInOptions.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.common; 2 | 3 | import lombok.Getter; 4 | import lombok.experimental.Accessors; 5 | 6 | @Getter 7 | public class SlideInOptions { 8 | private final String name; 9 | @Accessors(fluent = true) 10 | private final Boolean shouldReattach; 11 | private final String customAnnotation; 12 | 13 | public SlideInOptions(String name, boolean shouldReattach, String customAnnotation) { 14 | this.name = name; 15 | this.shouldReattach = shouldReattach; 16 | this.customAnnotation = customAnnotation; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/common/UiThreadUnsafeRunnable.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.common; 2 | 3 | import com.virtuslab.qual.guieffect.UIThreadUnsafe; 4 | 5 | public interface UiThreadUnsafeRunnable { 6 | @UIThreadUnsafe 7 | void run(); 8 | } 9 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/CompareSelectedWithParentAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseCompareWithParentAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class CompareSelectedWithParentAction extends BaseCompareWithParentAction implements IExpectsKeySelectedBranchName { 13 | @Override 14 | protected boolean isSideEffecting() { 15 | return false; 16 | } 17 | 18 | @Override 19 | public LambdaLogger log() { 20 | return LOG; 21 | } 22 | 23 | @Override 24 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 25 | return getSelectedBranchName(anActionEvent); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/FastForwardMergeSelectedToParentAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseFastForwardMergeToParentAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class FastForwardMergeSelectedToParentAction extends BaseFastForwardMergeToParentAction 13 | implements 14 | IExpectsKeySelectedBranchName { 15 | @Override 16 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 17 | return getSelectedBranchName(anActionEvent); 18 | } 19 | 20 | @Override 21 | public LambdaLogger log() { 22 | return LOG; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/OverrideForkPointOfSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import io.vavr.collection.List; 5 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 6 | import lombok.CustomLog; 7 | import org.checkerframework.checker.nullness.qual.Nullable; 8 | 9 | import com.virtuslab.gitmachete.backend.api.SyncToParentStatus; 10 | import com.virtuslab.gitmachete.frontend.actions.base.BaseOverrideForkPointAction; 11 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 12 | 13 | @CustomLog 14 | public class OverrideForkPointOfSelectedAction extends BaseOverrideForkPointAction 15 | implements 16 | IExpectsKeySelectedBranchName { 17 | @Override 18 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 19 | return getSelectedBranchName(anActionEvent); 20 | } 21 | 22 | @Override 23 | public List getEligibleStatuses() { 24 | return List.of(SyncToParentStatus.InSyncButForkPointOff, SyncToParentStatus.OutOfSync); 25 | } 26 | 27 | @Override 28 | public LambdaLogger log() { 29 | return LOG; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/PullSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BasePullAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class PullSelectedAction extends BasePullAction 13 | implements 14 | IExpectsKeySelectedBranchName { 15 | @Override 16 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 17 | return getSelectedBranchName(anActionEvent); 18 | } 19 | 20 | @Override 21 | public LambdaLogger log() { 22 | return LOG; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/PushSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BasePushAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class PushSelectedAction extends BasePushAction implements IExpectsKeySelectedBranchName { 13 | @Override 14 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 15 | return getSelectedBranchName(anActionEvent); 16 | } 17 | 18 | @Override 19 | public LambdaLogger log() { 20 | return LOG; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/RenameSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseRenameAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class RenameSelectedAction extends BaseRenameAction 13 | implements 14 | IExpectsKeySelectedBranchName { 15 | @Override 16 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 17 | return getSelectedBranchName(anActionEvent); 18 | } 19 | 20 | @Override 21 | public LambdaLogger log() { 22 | return LOG; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/ResetSelectedToRemoteAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseResetToRemoteAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class ResetSelectedToRemoteAction extends BaseResetToRemoteAction implements IExpectsKeySelectedBranchName { 13 | @Override 14 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 15 | return getSelectedBranchName(anActionEvent); 16 | } 17 | 18 | @Override 19 | public LambdaLogger log() { 20 | return LOG; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/SlideInBelowSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseSlideInBelowAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class SlideInBelowSelectedAction extends BaseSlideInBelowAction 13 | implements 14 | IExpectsKeySelectedBranchName { 15 | @Override 16 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 17 | return getSelectedBranchName(anActionEvent); 18 | } 19 | 20 | @Override 21 | public LambdaLogger log() { 22 | return LOG; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/SlideOutSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseSlideOutAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class SlideOutSelectedAction extends BaseSlideOutAction implements IExpectsKeySelectedBranchName { 13 | @Override 14 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 15 | return getSelectedBranchName(anActionEvent); 16 | } 17 | 18 | @Override 19 | public LambdaLogger log() { 20 | return LOG; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/SquashSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseSquashAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class SquashSelectedAction extends BaseSquashAction implements IExpectsKeySelectedBranchName { 13 | @Override 14 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 15 | return getSelectedBranchName(anActionEvent); 16 | } 17 | 18 | @Override 19 | public LambdaLogger log() { 20 | return LOG; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/SyncSelectedToParentByRebaseAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseSyncToParentByRebaseAction; 9 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 10 | 11 | @CustomLog 12 | public class SyncSelectedToParentByRebaseAction extends BaseSyncToParentByRebaseAction 13 | implements 14 | IExpectsKeySelectedBranchName { 15 | @Override 16 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 17 | return getSelectedBranchName(anActionEvent); 18 | } 19 | 20 | @Override 21 | public LambdaLogger log() { 22 | return LOG; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/contextmenu/TraverseFromSelectedAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.contextmenu; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.expectedkeys.IExpectsKeySelectedBranchName; 9 | import com.virtuslab.gitmachete.frontend.actions.traverse.BaseTraverseAction; 10 | 11 | @CustomLog 12 | public class TraverseFromSelectedAction extends BaseTraverseAction 13 | implements 14 | IExpectsKeySelectedBranchName { 15 | @Override 16 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 17 | return getSelectedBranchName(anActionEvent); 18 | } 19 | 20 | @Override 21 | public LambdaLogger log() { 22 | return LOG; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/expectedkeys/IExpectsKeySelectedBranchName.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.expectedkeys; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import lombok.val; 5 | import org.checkerframework.checker.nullness.qual.Nullable; 6 | 7 | import com.virtuslab.gitmachete.frontend.actions.base.IWithLogger; 8 | import com.virtuslab.gitmachete.frontend.datakeys.DataKeys; 9 | 10 | public interface IExpectsKeySelectedBranchName extends IWithLogger { 11 | default @Nullable String getSelectedBranchName(AnActionEvent anActionEvent) { 12 | val selectedBranchName = anActionEvent.getData(DataKeys.SELECTED_BRANCH_NAME); 13 | if (isLoggingAcceptable() && selectedBranchName == null) { 14 | log().warn("Selected branch is undefined"); 15 | } 16 | return selectedBranchName; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/expectedkeys/IExpectsKeyUnmanagedBranchName.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.expectedkeys; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import lombok.val; 5 | import org.checkerframework.checker.nullness.qual.Nullable; 6 | 7 | import com.virtuslab.gitmachete.frontend.actions.base.IWithLogger; 8 | import com.virtuslab.gitmachete.frontend.datakeys.DataKeys; 9 | 10 | public interface IExpectsKeyUnmanagedBranchName extends IWithLogger { 11 | default @Nullable String getNameOfUnmanagedBranch(AnActionEvent anActionEvent) { 12 | val unmanagedBranchName = anActionEvent.getData(DataKeys.UNMANAGED_BRANCH_NAME); 13 | if (isLoggingAcceptable() && unmanagedBranchName == null) { 14 | log().warn("Unmanaged branch is undefined"); 15 | } 16 | return unmanagedBranchName; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/hooks/PreRebaseHookExecutor.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.hooks; 2 | 3 | import static com.virtuslab.gitmachete.frontend.resourcebundles.GitMacheteBundle.getString; 4 | 5 | import git4idea.repo.GitRepository; 6 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 7 | import lombok.CustomLog; 8 | 9 | import com.virtuslab.gitmachete.backend.api.IGitRebaseParameters; 10 | import com.virtuslab.qual.guieffect.UIThreadUnsafe; 11 | 12 | @CustomLog 13 | public final class PreRebaseHookExecutor extends BaseGit4IdeaHookExecutor { 14 | private static final int EXECUTION_TIMEOUT_SECONDS = 10; 15 | 16 | @UIThreadUnsafe 17 | public PreRebaseHookExecutor(GitRepository gitRepository) { 18 | super("machete-pre-rebase", gitRepository); 19 | } 20 | 21 | @UIThreadUnsafe 22 | public boolean executeHookFor(IGitRebaseParameters gitRebaseParameters) { 23 | String failureNotificationTitle = getString( 24 | "action.GitMachete.PreRebaseHookExecutor.notification.title.abort"); 25 | 26 | return executeGit4IdeaHook(failureNotificationTitle, EXECUTION_TIMEOUT_SECONDS, 27 | gitRebaseParameters.getNewBaseBranch().getFullName(), 28 | gitRebaseParameters.getForkPointCommit().getHash(), 29 | gitRebaseParameters.getCurrentBranch().getName()); 30 | } 31 | 32 | @Override 33 | protected LambdaLogger log() { 34 | return LOG; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/toolbar/HelpAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.toolbar; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import com.intellij.openapi.project.DumbAwareAction; 5 | import org.checkerframework.checker.guieffect.qual.UIEffect; 6 | 7 | import com.virtuslab.gitmachete.frontend.actions.dialogs.GraphTableDialog; 8 | 9 | public class HelpAction extends DumbAwareAction { 10 | 11 | @Override 12 | @UIEffect 13 | public void actionPerformed(AnActionEvent anActionEvent) { 14 | GraphTableDialog.Companion.ofDemoRepository().show(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/toolbar/SlideInBelowCurrentAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.toolbar; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitmachete.frontend.actions.base.BaseSlideInBelowAction; 9 | 10 | @CustomLog 11 | public class SlideInBelowCurrentAction extends BaseSlideInBelowAction { 12 | @Override 13 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 14 | return getCurrentBranchNameIfManaged(anActionEvent); 15 | } 16 | 17 | @Override 18 | public LambdaLogger log() { 19 | return LOG; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /frontend/actions/src/main/java/com/virtuslab/gitmachete/frontend/actions/toolbar/TraverseFromFirstAction.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.toolbar; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import kr.pe.kwonnam.slf4jlambda.LambdaLogger; 5 | import lombok.CustomLog; 6 | import lombok.val; 7 | import org.checkerframework.checker.nullness.qual.Nullable; 8 | 9 | import com.virtuslab.branchlayout.api.BranchLayoutEntry; 10 | import com.virtuslab.gitmachete.frontend.actions.traverse.BaseTraverseAction; 11 | 12 | @CustomLog 13 | public class TraverseFromFirstAction extends BaseTraverseAction { 14 | @Override 15 | public @Nullable String getNameOfBranchUnderAction(AnActionEvent anActionEvent) { 16 | val branchLayout = getBranchLayout(anActionEvent); 17 | 18 | if (branchLayout == null) { 19 | return null; 20 | } 21 | 22 | return branchLayout.getRootEntries().headOption().map(BranchLayoutEntry::getName).getOrNull(); 23 | } 24 | 25 | @Override 26 | public LambdaLogger log() { 27 | return LOG; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /frontend/actions/src/main/kotlin/com/virtuslab/gitmachete/frontend/actions/dialogs/DoNotAskOption.kt: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.dialogs 2 | 3 | import com.intellij.ide.util.PropertiesComponent 4 | import com.intellij.openapi.project.Project 5 | import com.intellij.openapi.ui.DoNotAskOption 6 | import com.intellij.openapi.ui.Messages 7 | 8 | class DoNotAskOption(val project: Project, val keyName: String) : DoNotAskOption.Adapter() { 9 | 10 | override fun rememberChoice(isSelected: Boolean, exitCode: Int) { 11 | if (exitCode == Messages.OK && isSelected) { 12 | PropertiesComponent.getInstance(project).setValue(keyName, false, /* defaultValue */ true) 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /frontend/actions/src/main/kotlin/com/virtuslab/gitmachete/frontend/actions/dialogs/TraverseInfoComponent.kt: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.actions.dialogs 2 | 3 | import com.intellij.openapi.ui.messages.MessageDialog 4 | import com.intellij.util.ui.JBUI 5 | import com.virtuslab.gitmachete.frontend.icons.MacheteIcons 6 | import javax.swing.border.EmptyBorder 7 | 8 | fun pushInfo(text: String) = MessageDialog( 9 | /* message */ text, 10 | /* title */ "ignore", 11 | /* options */ emptyArray(), 12 | /* defaultOptionIndex */ -1, 13 | /* icon */ MacheteIcons.LOGO, 14 | ).contentPanel.apply { 15 | border = JBUI.Borders.compound( 16 | JBUI.Borders.emptyTop(12), 17 | JBUI.Borders.customLineBottom(JBUI.CurrentTheme.CustomFrameDecorations.separatorForeground()), 18 | EmptyBorder(JBUI.CurrentTheme.ActionsList.cellPadding()), 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /frontend/base/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | api(project(":qual")) 5 | api(project(":backend:api")) 6 | implementation(project(":frontend:resourcebundles")) 7 | } 8 | 9 | jetbrainsAnnotations() 10 | junit() 11 | lombok() 12 | slf4jLambdaApi() 13 | vavr() 14 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/common/WriteActionUtils.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.common; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.application.WriteAction; 5 | import com.intellij.util.ThrowableRunnable; 6 | import lombok.SneakyThrows; 7 | import org.checkerframework.checker.guieffect.qual.UI; 8 | 9 | public final class WriteActionUtils { 10 | 11 | private WriteActionUtils() {} 12 | 13 | // We don't provide asynchronous (non-blocking) variant since it turned out prone to race conditions. 14 | public static void blockingRunWriteActionOnUIThread(@UI ThrowableRunnable action) { 15 | ApplicationManager.getApplication().invokeAndWait(getWriteActionRunnable(action)); 16 | } 17 | 18 | private static @UI Runnable getWriteActionRunnable(@UI ThrowableRunnable action) { 19 | return new Runnable() { 20 | @Override 21 | @SneakyThrows 22 | public void run() { 23 | WriteAction.run(action); 24 | } 25 | }; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/datakeys/DataKeys.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.datakeys; 2 | 3 | import static io.vavr.API.$; 4 | import static io.vavr.API.Case; 5 | import static io.vavr.API.Match; 6 | 7 | import com.intellij.openapi.actionSystem.DataKey; 8 | import org.checkerframework.checker.nullness.qual.Nullable; 9 | 10 | import com.virtuslab.gitmachete.backend.api.IGitMacheteRepositorySnapshot; 11 | 12 | public final class DataKeys { 13 | private DataKeys() {} 14 | 15 | public static final DataKey<@Nullable IGitMacheteRepositorySnapshot> GIT_MACHETE_REPOSITORY_SNAPSHOT = DataKey 16 | .create("GIT_MACHETE_REPOSITORY_SNAPSHOT"); 17 | public static final DataKey<@Nullable String> SELECTED_BRANCH_NAME = DataKey.create("SELECTED_BRANCH_NAME"); 18 | public static final DataKey<@Nullable String> UNMANAGED_BRANCH_NAME = DataKey.create("UNMANAGED_BRANCH_NAME"); 19 | 20 | // Note: this method isn't currently fully null-safe, it's possible to pass {@code null} as {@code value} 21 | // even if {@code T} is marked as {@code @NonNull}. 22 | // See https://github.com/typetools/checker-framework/issues/3289 23 | // and generally https://github.com/typetools/checker-framework/issues/979. 24 | public static Match.Case typeSafeCase(DataKey key, T value) { 25 | return Case($(key.getName()), value); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/defs/ActionGroupIds.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.defs; 2 | 3 | public final class ActionGroupIds { 4 | private ActionGroupIds() {} 5 | 6 | public static final String CONTEXT_MENU = "GitMachete.ContextMenu"; 7 | public static final String TOOLBAR = "GitMachete.Toolbar"; 8 | } 9 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/defs/ActionIds.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.defs; 2 | 3 | public final class ActionIds { 4 | private ActionIds() {} 5 | 6 | public static final String CHECK_OUT_SELECTED = "GitMachete.CheckoutSelectedAction"; 7 | public static final String OPEN_MACHETE_FILE = "GitMachete.OpenMacheteFileAction"; 8 | public static final String SLIDE_IN_UNMANAGED_BELOW = "GitMachete.SlideInUnmanagedBelowAction"; 9 | } 10 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/defs/ActionPlaces.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.defs; 2 | 3 | public final class ActionPlaces { 4 | private ActionPlaces() {} 5 | 6 | public static final String CONTEXT_MENU = "GitMacheteContextMenu"; 7 | public static final String TOOLBAR = "GitMacheteToolbar"; 8 | public static final String VCS_NOTIFICATION = "Vcs.Notification"; 9 | } 10 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/defs/FileTypeIds.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.defs; 2 | 3 | public final class FileTypeIds { 4 | private FileTypeIds() {} 5 | 6 | // Extracted so that frontend:ui doesn't need to depend on frontend:file. 7 | public static final String NAME = "Machete File"; 8 | } 9 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/defs/GitConfigKeys.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.defs; 2 | 3 | public final class GitConfigKeys { 4 | private GitConfigKeys() {} 5 | public static final String DELETE_LOCAL_BRANCH_ON_SLIDE_OUT = "machete.slideOut.deleteLocalBranch"; 6 | public static String overrideForkPointToKey(String branchName) { 7 | return "machete.overrideForkPoint.${branchName}.to"; 8 | } 9 | public static String overrideForkPointWhileDescendantOf(String branchName) { 10 | return "machete.overrideForkPoint.${branchName}.whileDescendantOf"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/defs/PropertiesComponentKeys.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.defs; 2 | 3 | public final class PropertiesComponentKeys { 4 | private PropertiesComponentKeys() {} 5 | public static final String SHOW_MERGE_WARNING = "git-machete.merge.warning.show"; 6 | public static final String SHOW_RESET_INFO = "git-machete.reset.info.show"; 7 | public static final String SHOW_TRAVERSE_INFO = "git-machete.traverse.approval.show"; 8 | public static final String SHOW_UNMANAGED_BRANCH_NOTIFICATION = "git-machete.unmanaged.notification.show"; 9 | } 10 | -------------------------------------------------------------------------------- /frontend/base/src/main/java/com/virtuslab/gitmachete/frontend/errorreport/PlatformInfoProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.errorreport; 2 | 3 | import com.intellij.ide.plugins.IdeaPluginDescriptor; 4 | import com.intellij.ide.plugins.PluginManagerCore; 5 | import com.intellij.openapi.application.ApplicationInfo; 6 | import com.intellij.openapi.extensions.PluginId; 7 | import org.apache.commons.lang3.SystemUtils; 8 | import org.checkerframework.checker.nullness.qual.Nullable; 9 | 10 | class PlatformInfoProvider { 11 | @Nullable 12 | String getOSName() { 13 | return SystemUtils.OS_NAME; 14 | } 15 | 16 | @Nullable 17 | String getOSVersion() { 18 | return SystemUtils.OS_VERSION; 19 | } 20 | 21 | String getIdeApplicationName() { 22 | return ApplicationInfo.getInstance().getFullApplicationName(); 23 | } 24 | 25 | @Nullable 26 | String getPluginVersion() { 27 | IdeaPluginDescriptor pluginDescriptor = PluginManagerCore.getPlugin(PluginId.getId("com.virtuslab.git-machete")); 28 | return pluginDescriptor != null ? pluginDescriptor.getVersion() : null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/bug_report.md: -------------------------------------------------------------------------------- 1 | ## Running environment 2 | - Git Machete plugin version - %macheteVersion% 3 | - IDE - %ide% 4 | - Operating system - %os% 5 | 6 | ## Bug description 7 | **Please include steps to reproduce (like `go to...`/`click on...` etc.) + expected and actual behaviour**. 8 | 9 | ## (optional) Screenshots 10 | If applicable, add screenshots (or screen recordings, see [Peek](https://github.com/phw/peek#peek---an-animated-gif-recorder) on Linux) 11 | to help explain your problem. 12 | 13 | ## IDEA - additional info 14 | %additionalInfo% 15 | 16 | ## IDEA - stack trace 17 | %stacktraces% 18 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/edit_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/fastForward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/fastForward_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/fetch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/fetch_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/help.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/help_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/incomingChangesOn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/incomingChangesOn_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/merge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/merge_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/overrideForkPoint.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/overrideForkPoint_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 11 | 13 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/pull.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/pull_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/push.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/push_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/rename.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/rename_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/reset.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/reset_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/slideOut.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/slideOut_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/squash.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 8 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/squash_dark.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 8 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/toggleListingCommits.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/toggleListingCommits_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/traverse.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/base/src/main/resources/icons/traverse_dark.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/base/src/test/java/com/virtuslab/gitmachete/frontend/errorreport/DummyPlatformInfoProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.errorreport; 2 | 3 | class DummyPlatformInfoProvider extends PlatformInfoProvider { 4 | @Override 5 | String getOSName() { 6 | return "Mock OS X"; 7 | } 8 | 9 | @Override 10 | String getOSVersion() { 11 | return "Hehe"; 12 | } 13 | 14 | @Override 15 | String getIdeApplicationName() { 16 | return "mocked IntelliJ idea"; 17 | } 18 | 19 | @Override 20 | String getPluginVersion() { 21 | return "mock plugin version"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /frontend/base/src/test/resources/expected-error-report-uris/without_stack_trace.txt: -------------------------------------------------------------------------------- 1 | https://github.com/VirtusLab/git-machete-intellij-plugin/issues/new 2 | ?title=java.lang.RuntimeException%3A+exception+message 3 | &labels=bug 4 | &body=%23%23+Running+environment%0A 5 | -+Git+Machete+plugin+version+-+mock+plugin+version%0A 6 | -+IDE+-+mocked+IntelliJ+idea%0A 7 | -+Operating+system+-+Mock+OS+X+Hehe%0A 8 | %0A 9 | %23%23+Bug+description%0A 10 | **Please+include+steps+to+reproduce+%28like+%60go+to...%60%2F%60click+on...%60+etc.%29+%2B+expected+and+actual+behaviour**.%0A 11 | %0A 12 | %23%23+%28optional%29+Screenshots%0A 13 | If+applicable%2C+add+screenshots+%28or+screen+recordings%2C+see+%5BPeek%5D%28https%3A%2F%2Fgithub.com%2Fphw%2Fpeek%23peek---an-animated-gif-recorder%29+on+Linux%29%0A 14 | to+help+explain+your+problem.%0A 15 | %0A 16 | %23%23+IDEA+-+additional+info%0A 17 | N%2FA%0A 18 | %0A 19 | %23%23+IDEA+-+stack+trace%0A 20 | %60%60%60%0A 21 | some+message%0A 22 | %0A 23 | java.lang.RuntimeException%3A+exception+message%0A 24 | %60%60%60 25 | -------------------------------------------------------------------------------- /frontend/file/src/main/grammar/Machete.bnf: -------------------------------------------------------------------------------- 1 | { 2 | parserClass="com.virtuslab.gitmachete.frontend.file.grammar.MacheteGeneratedParser" 3 | 4 | extends="com.intellij.extapi.psi.ASTWrapperPsiElement" 5 | 6 | psiClassPrefix="MacheteGenerated" 7 | psiImplClassSuffix="Impl" 8 | psiPackage="com.virtuslab.gitmachete.frontend.file.grammar" 9 | psiImplPackage="com.virtuslab.gitmachete.frontend.file.grammar.impl" 10 | 11 | elementTypeHolderClass="com.virtuslab.gitmachete.frontend.file.grammar.MacheteGeneratedElementTypes" 12 | elementTypeClass="com.virtuslab.gitmachete.frontend.file.grammar.MacheteElementType" 13 | tokenTypeClass="com.virtuslab.gitmachete.frontend.file.grammar.MacheteTokenType" 14 | } 15 | 16 | simpleFile ::= item_* 17 | 18 | // Even if we don't have comments in our machete file, the COMMENT element must be here - language parser definition 19 | // (in file MacheteParserDefinition) enforces us to define element that represent comments 20 | private item_ ::= (entry|COMMENT|(INDENTATION? EOL)|INDENTATION) 21 | 22 | entry ::= INDENTATION? branch CUSTOM_ANNOTATION? 23 | 24 | branch ::= PREFIX? NAME 25 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/MacheteFileType.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file; 2 | 3 | import javax.swing.Icon; 4 | 5 | import com.intellij.openapi.fileTypes.LanguageFileType; 6 | 7 | import com.virtuslab.gitmachete.frontend.defs.FileTypeIds; 8 | import com.virtuslab.gitmachete.frontend.file.grammar.MacheteLanguage; 9 | import com.virtuslab.gitmachete.frontend.icons.MacheteIcons; 10 | 11 | public final class MacheteFileType extends LanguageFileType { 12 | public static final MacheteFileType instance = new MacheteFileType(); 13 | 14 | private MacheteFileType() { 15 | super(MacheteLanguage.instance); 16 | } 17 | 18 | @Override 19 | public boolean isReadOnly() { 20 | return false; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return FileTypeIds.NAME; 26 | } 27 | 28 | @Override 29 | public String getDescription() { 30 | return "Branch layout file for Git Machete"; 31 | } 32 | 33 | @Override 34 | public String getDefaultExtension() { 35 | return "machete"; 36 | } 37 | 38 | @Override 39 | public Icon getIcon() { 40 | return MacheteIcons.MACHETE_FILE; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/MacheteFileViewProviderFactory.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file; 2 | 3 | import com.intellij.lang.Language; 4 | import com.intellij.openapi.vfs.VirtualFile; 5 | import com.intellij.psi.FileViewProvider; 6 | import com.intellij.psi.FileViewProviderFactory; 7 | import com.intellij.psi.PsiManager; 8 | import com.intellij.psi.SingleRootFileViewProvider; 9 | 10 | public class MacheteFileViewProviderFactory implements FileViewProviderFactory { 11 | @Override 12 | public FileViewProvider createFileViewProvider(VirtualFile file, 13 | Language language, 14 | PsiManager manager, 15 | boolean eventSystemEnabled) { 16 | return new SingleRootFileViewProvider(manager, file, eventSystemEnabled, language) { 17 | @Override 18 | protected boolean shouldCreatePsi() { 19 | return true; 20 | } 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/grammar/MacheteElementType.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file.grammar; 2 | 3 | import com.intellij.psi.tree.IElementType; 4 | 5 | public class MacheteElementType extends IElementType { 6 | public MacheteElementType(String debugName) { 7 | super(debugName, MacheteLanguage.instance); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/grammar/MacheteFile.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file.grammar; 2 | 3 | import com.intellij.extapi.psi.PsiFileBase; 4 | import com.intellij.openapi.fileTypes.FileType; 5 | import com.intellij.psi.FileViewProvider; 6 | 7 | import com.virtuslab.gitmachete.frontend.defs.FileTypeIds; 8 | import com.virtuslab.gitmachete.frontend.file.MacheteFileType; 9 | 10 | public class MacheteFile extends PsiFileBase { 11 | public MacheteFile(FileViewProvider viewProvider) { 12 | super(viewProvider, MacheteLanguage.instance); 13 | } 14 | 15 | @Override 16 | public FileType getFileType() { 17 | return MacheteFileType.instance; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return FileTypeIds.NAME; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/grammar/MacheteLanguage.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file.grammar; 2 | 3 | import com.intellij.lang.Language; 4 | 5 | public final class MacheteLanguage extends Language { 6 | public static final MacheteLanguage instance = new MacheteLanguage(); 7 | 8 | private MacheteLanguage() { 9 | super("Git Machete"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/grammar/MacheteLexerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file.grammar; 2 | 3 | import com.intellij.lexer.FlexAdapter; 4 | 5 | public class MacheteLexerAdapter extends FlexAdapter { 6 | @SuppressWarnings("nullness:argument") 7 | public MacheteLexerAdapter() { 8 | super(new MacheteGeneratedLexer(/* in */ null)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/grammar/MacheteTokenType.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file.grammar; 2 | 3 | import com.intellij.psi.tree.IElementType; 4 | import lombok.ToString; 5 | import org.jetbrains.annotations.NonNls; 6 | 7 | @ToString 8 | public class MacheteTokenType extends IElementType { 9 | public MacheteTokenType(@NonNls String debugName) { 10 | super(debugName, MacheteLanguage.instance); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/file/src/main/java/com/virtuslab/gitmachete/frontend/file/highlighting/MacheteSyntaxHighlighterFactory.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.file.highlighting; 2 | 3 | import com.intellij.openapi.fileTypes.SyntaxHighlighter; 4 | import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.openapi.vfs.VirtualFile; 7 | import org.checkerframework.checker.nullness.qual.Nullable; 8 | 9 | public class MacheteSyntaxHighlighterFactory extends SyntaxHighlighterFactory { 10 | @Override 11 | public SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile) { 12 | return new MacheteSyntaxHighlighter(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /frontend/graph/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | api(project(":qual")) 5 | api(project(":backend:api")) 6 | } 7 | 8 | lombok() 9 | vavr() 10 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/elements/GraphEdge.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.elements; 2 | 3 | import io.vavr.NotImplementedError; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import org.checkerframework.checker.index.qual.NonNegative; 7 | 8 | @Getter 9 | @RequiredArgsConstructor 10 | public final class GraphEdge implements IGraphElement { 11 | 12 | public static GraphEdge createEdge(@NonNegative int nodeIndex1, @NonNegative int nodeIndex2) { 13 | return new GraphEdge(Math.min(nodeIndex1, nodeIndex2), Math.max(nodeIndex1, nodeIndex2)); 14 | } 15 | 16 | private final @NonNegative int upNodeIndex; 17 | 18 | private final @NonNegative int downNodeIndex; 19 | 20 | @Override 21 | public boolean isNode() { 22 | return false; 23 | } 24 | 25 | @Override 26 | public GraphNode asNode() { 27 | throw new NotImplementedError(); 28 | } 29 | 30 | @Override 31 | public GraphEdge asEdge() { 32 | return this; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/elements/GraphNode.java: -------------------------------------------------------------------------------- 1 | 2 | package com.virtuslab.gitmachete.frontend.graph.api.elements; 3 | 4 | import io.vavr.NotImplementedError; 5 | import lombok.Getter; 6 | import lombok.RequiredArgsConstructor; 7 | import org.checkerframework.checker.index.qual.NonNegative; 8 | 9 | @RequiredArgsConstructor 10 | public final class GraphNode implements IGraphElement { 11 | 12 | @Getter 13 | private final @NonNegative int nodeIndex; 14 | 15 | @Override 16 | public boolean isNode() { 17 | return true; 18 | } 19 | 20 | @Override 21 | public GraphNode asNode() { 22 | return this; 23 | } 24 | 25 | @Override 26 | public GraphEdge asEdge() { 27 | throw new NotImplementedError(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/items/GraphItemColor.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.items; 2 | 3 | public enum GraphItemColor { 4 | TRANSPARENT, GRAY, YELLOW, RED, GREEN 5 | } 6 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/items/IBranchItem.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.items; 2 | 3 | import io.vavr.NotImplementedError; 4 | 5 | import com.virtuslab.gitmachete.backend.api.IManagedBranchSnapshot; 6 | import com.virtuslab.gitmachete.backend.api.RelationToRemote; 7 | 8 | public interface IBranchItem extends IGraphItem { 9 | 10 | IManagedBranchSnapshot getBranch(); 11 | 12 | RelationToRemote getRelationToRemote(); 13 | 14 | boolean isCurrentBranch(); 15 | 16 | // These methods need to be implemented in frontendGraphApi to avoid problems with Subtyping Checker. 17 | @Override 18 | default boolean isBranchItem() { 19 | return true; 20 | } 21 | 22 | @Override 23 | default IBranchItem asBranchItem() { 24 | return this; 25 | } 26 | 27 | @Override 28 | default ICommitItem asCommitItem() { 29 | throw new NotImplementedError(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/paint/IGraphCellPainter.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.paint; 2 | 3 | import java.awt.Graphics2D; 4 | 5 | import io.vavr.collection.List; 6 | import org.checkerframework.checker.guieffect.qual.UIEffect; 7 | 8 | import com.virtuslab.gitmachete.frontend.graph.api.render.parts.IRenderPart; 9 | 10 | public interface IGraphCellPainter { 11 | 12 | @UIEffect 13 | void draw(Graphics2D g2, List renderParts); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/paint/IGraphCellPainterFactory.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.paint; 2 | 3 | import javax.swing.JTable; 4 | 5 | public interface IGraphCellPainterFactory { 6 | IGraphCellPainter create(JTable table); 7 | } 8 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/paint/PaintParameters.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.paint; 2 | 3 | public final class PaintParameters { 4 | 5 | private PaintParameters() {} 6 | 7 | private static final int CIRCLE_RADIUS = 4; 8 | private static final float THICK_LINE = 1.5f; 9 | private static final int WIDTH_NODE = 15; 10 | 11 | public static final int ROW_HEIGHT = 22; 12 | 13 | public static int getNodeWidth(int rowHeight) { 14 | return WIDTH_NODE * rowHeight / ROW_HEIGHT; 15 | } 16 | 17 | public static float getLineThickness(int rowHeight) { 18 | return THICK_LINE * rowHeight / ROW_HEIGHT; 19 | } 20 | 21 | public static int getCircleRadius(int rowHeight) { 22 | return CIRCLE_RADIUS * rowHeight / ROW_HEIGHT; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/render/IRenderPartGenerator.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.render; 2 | 3 | import io.vavr.collection.List; 4 | import org.checkerframework.checker.index.qual.NonNegative; 5 | 6 | import com.virtuslab.gitmachete.frontend.graph.api.render.parts.IRenderPart; 7 | 8 | public interface IRenderPartGenerator { 9 | List getRenderParts(@NonNegative int rowIndex); 10 | } 11 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/render/parts/IEdgeRenderPart.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.render.parts; 2 | 3 | public interface IEdgeRenderPart extends IRenderPart { 4 | 5 | Type getType(); 6 | 7 | enum Type { 8 | UP, DOWN, RIGHT 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/render/parts/INodeRenderPart.java: -------------------------------------------------------------------------------- 1 | 2 | package com.virtuslab.gitmachete.frontend.graph.api.render.parts; 3 | 4 | public interface INodeRenderPart extends IRenderPart {} 5 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/render/parts/IRenderPart.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.render.parts; 2 | 3 | import org.checkerframework.checker.index.qual.NonNegative; 4 | 5 | import com.virtuslab.gitmachete.frontend.graph.api.elements.IGraphElement; 6 | import com.virtuslab.gitmachete.frontend.graph.api.items.GraphItemColor; 7 | 8 | /** 9 | * Render parts ({@link IRenderPart}, {@link IEdgeRenderPart}, {@link INodeRenderPart}) represent RENDERED graph. 10 | * The position of unit parts (row of and position within graph table), orientation of edges are important here. 11 | * In this context the connections between graph elements does not matter (unlike {@link IGraphElement}s). 12 | * */ 13 | public interface IRenderPart { 14 | 15 | @NonNegative 16 | int getRowIndex(); 17 | 18 | @NonNegative 19 | int getPositionInRow(); 20 | 21 | GraphItemColor getGraphItemColor(); 22 | 23 | boolean isNode(); 24 | 25 | INodeRenderPart asNode(); 26 | 27 | IEdgeRenderPart asEdge(); 28 | } 29 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/repository/IBranchGetCommitsStrategy.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.repository; 2 | 3 | import io.vavr.collection.List; 4 | 5 | import com.virtuslab.gitmachete.backend.api.ICommitOfManagedBranch; 6 | import com.virtuslab.gitmachete.backend.api.INonRootManagedBranchSnapshot; 7 | 8 | public interface IBranchGetCommitsStrategy { 9 | List getCommitsOf(INonRootManagedBranchSnapshot branch); 10 | } 11 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/repository/IRepositoryGraph.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.repository; 2 | 3 | import io.vavr.Tuple2; 4 | import io.vavr.collection.List; 5 | import org.checkerframework.checker.index.qual.NonNegative; 6 | 7 | import com.virtuslab.gitmachete.frontend.graph.api.elements.GraphEdge; 8 | import com.virtuslab.gitmachete.frontend.graph.api.items.IGraphItem; 9 | import com.virtuslab.gitmachete.frontend.graph.api.render.parts.IRenderPart; 10 | 11 | public interface IRepositoryGraph { 12 | 13 | List getAdjacentEdges(@NonNegative int itemIndex); 14 | 15 | IGraphItem getGraphItem(@NonNegative int itemIndex); 16 | 17 | @NonNegative 18 | int getNodesCount(); 19 | 20 | List getRenderParts(@NonNegative int itemIndex); 21 | 22 | List> getVisibleEdgesWithPositions(@NonNegative int itemIndex); 23 | } 24 | -------------------------------------------------------------------------------- /frontend/graph/api/src/main/java/com/virtuslab/gitmachete/frontend/graph/api/repository/IRepositoryGraphCache.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.api.repository; 2 | 3 | import org.checkerframework.checker.guieffect.qual.UIEffect; 4 | 5 | import com.virtuslab.gitmachete.backend.api.IGitMacheteRepositorySnapshot; 6 | 7 | public interface IRepositoryGraphCache { 8 | @UIEffect 9 | IRepositoryGraph getRepositoryGraph(IGitMacheteRepositorySnapshot givenRepositorySnapshot, boolean isListingCommits); 10 | } 11 | -------------------------------------------------------------------------------- /frontend/graph/impl/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | api(project(":frontend:graph:api")) 5 | 6 | implementation(project(":backend:api")) 7 | implementation(project(":frontend:base")) 8 | } 9 | 10 | lombok() 11 | slf4jLambdaApi() 12 | vavr() 13 | 14 | applySubtypingChecker() 15 | -------------------------------------------------------------------------------- /frontend/graph/impl/src/main/java/com/virtuslab/gitmachete/frontend/graph/impl/paint/GraphCellPainterFactory.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.impl.paint; 2 | 3 | import javax.swing.JTable; 4 | 5 | import com.virtuslab.gitmachete.frontend.graph.api.paint.IGraphCellPainterFactory; 6 | 7 | public class GraphCellPainterFactory implements IGraphCellPainterFactory { 8 | @Override 9 | public GraphCellPainter create(JTable table) { 10 | return new GraphCellPainter(table); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/graph/impl/src/main/java/com/virtuslab/gitmachete/frontend/graph/impl/render/GraphItemColorForGraphElementProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.impl.render; 2 | 3 | import org.checkerframework.checker.initialization.qual.NotOnlyInitialized; 4 | import org.checkerframework.checker.initialization.qual.UnderInitialization; 5 | 6 | import com.virtuslab.gitmachete.frontend.graph.api.elements.IGraphElement; 7 | import com.virtuslab.gitmachete.frontend.graph.api.items.GraphItemColor; 8 | import com.virtuslab.gitmachete.frontend.graph.api.repository.IRepositoryGraph; 9 | 10 | public class GraphItemColorForGraphElementProvider { 11 | @NotOnlyInitialized 12 | private final IRepositoryGraph repositoryGraph; 13 | 14 | public GraphItemColorForGraphElementProvider(@UnderInitialization IRepositoryGraph repositoryGraph) { 15 | this.repositoryGraph = repositoryGraph; 16 | } 17 | 18 | public GraphItemColor getGraphItemColor(IGraphElement element) { 19 | int nodeIndex; 20 | if (element.isNode()) { 21 | nodeIndex = element.asNode().getNodeIndex(); 22 | } else { // isEdge 23 | nodeIndex = element.asEdge().getDownNodeIndex(); 24 | } 25 | 26 | return repositoryGraph.getGraphItem(nodeIndex).getColor(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /frontend/graph/impl/src/main/java/com/virtuslab/gitmachete/frontend/graph/impl/render/parts/BaseRenderPart.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.graph.impl.render.parts; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | import org.checkerframework.checker.index.qual.NonNegative; 6 | 7 | import com.virtuslab.gitmachete.frontend.graph.api.elements.IGraphElement; 8 | import com.virtuslab.gitmachete.frontend.graph.api.items.GraphItemColor; 9 | import com.virtuslab.gitmachete.frontend.graph.api.render.parts.IRenderPart; 10 | import com.virtuslab.gitmachete.frontend.graph.impl.render.GraphItemColorForGraphElementProvider; 11 | 12 | @RequiredArgsConstructor 13 | public abstract class BaseRenderPart implements IRenderPart { 14 | @Getter 15 | protected final @NonNegative int rowIndex; 16 | 17 | @Getter 18 | protected final @NonNegative int positionInRow; 19 | 20 | protected final IGraphElement graphElement; 21 | 22 | private final GraphItemColorForGraphElementProvider renderPartColorIdProvider; 23 | 24 | @Override 25 | public GraphItemColor getGraphItemColor() { 26 | return renderPartColorIdProvider.getGraphItemColor(graphElement); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /frontend/graph/impl/src/main/java/com/virtuslab/gitmachete/frontend/graph/impl/render/parts/NodeRenderPart.java: -------------------------------------------------------------------------------- 1 | 2 | package com.virtuslab.gitmachete.frontend.graph.impl.render.parts; 3 | 4 | import io.vavr.NotImplementedError; 5 | import org.checkerframework.checker.index.qual.NonNegative; 6 | 7 | import com.virtuslab.gitmachete.frontend.graph.api.elements.GraphNode; 8 | import com.virtuslab.gitmachete.frontend.graph.api.render.parts.IEdgeRenderPart; 9 | import com.virtuslab.gitmachete.frontend.graph.api.render.parts.INodeRenderPart; 10 | import com.virtuslab.gitmachete.frontend.graph.impl.render.GraphItemColorForGraphElementProvider; 11 | 12 | public final class NodeRenderPart extends BaseRenderPart implements INodeRenderPart { 13 | 14 | public NodeRenderPart( 15 | @NonNegative int rowIndex, 16 | @NonNegative int positionInRow, 17 | GraphNode graphNode, 18 | GraphItemColorForGraphElementProvider renderPartColorIdProvider) { 19 | super(rowIndex, positionInRow, graphNode, renderPartColorIdProvider); 20 | } 21 | 22 | @Override 23 | public boolean isNode() { 24 | return true; 25 | } 26 | 27 | @Override 28 | public INodeRenderPart asNode() { 29 | return this; 30 | } 31 | 32 | @Override 33 | public IEdgeRenderPart asEdge() { 34 | throw new NotImplementedError(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /frontend/resourcebundles/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | jetbrainsAnnotations() 4 | junit() 5 | lombok() 6 | -------------------------------------------------------------------------------- /frontend/ui/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | api(project(":branchLayout:api")) 5 | api(project(":backend:api")) 6 | } 7 | 8 | lombok() 9 | slf4jLambdaApi() 10 | vavr() 11 | -------------------------------------------------------------------------------- /frontend/ui/api/src/main/java/com/virtuslab/gitmachete/frontend/ui/api/gitrepositoryselection/IGitRepositorySelectionChangeObserver.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.api.gitrepositoryselection; 2 | 3 | @FunctionalInterface 4 | public interface IGitRepositorySelectionChangeObserver { 5 | void onSelectionChanged(); 6 | } 7 | -------------------------------------------------------------------------------- /frontend/ui/api/src/main/java/com/virtuslab/gitmachete/frontend/ui/api/gitrepositoryselection/IGitRepositorySelectionProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.api.gitrepositoryselection; 2 | 3 | import javax.swing.JComponent; 4 | 5 | import git4idea.repo.GitRepository; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | public interface IGitRepositorySelectionProvider { 9 | @Nullable 10 | GitRepository getSelectedGitRepository(); 11 | 12 | void addSelectionChangeObserver(IGitRepositorySelectionChangeObserver observer); 13 | 14 | JComponent getSelectionComponent(); 15 | } 16 | -------------------------------------------------------------------------------- /frontend/ui/api/src/main/java/com/virtuslab/gitmachete/frontend/ui/api/table/ISimpleGraphTableProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.api.table; 2 | 3 | import org.checkerframework.checker.guieffect.qual.UIEffect; 4 | 5 | import com.virtuslab.gitmachete.backend.api.IGitMacheteRepositorySnapshot; 6 | 7 | public interface ISimpleGraphTableProvider { 8 | @UIEffect 9 | BaseGraphTable deriveInstance(IGitMacheteRepositorySnapshot macheteRepositorySnapshot, boolean isListingCommitsEnabled, 10 | boolean shouldDisplayActionToolTips); 11 | 12 | @UIEffect 13 | BaseGraphTable deriveDemoInstance(); 14 | } 15 | -------------------------------------------------------------------------------- /frontend/ui/impl/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | implementation(project(":branchLayout:api")) 5 | implementation(project(":backend:api")) 6 | implementation(project(":frontend:base")) 7 | implementation(project(":frontend:file")) 8 | implementation(project(":frontend:graph:api")) 9 | implementation(project(":frontend:resourcebundles")) 10 | implementation(project(":frontend:ui:api")) 11 | } 12 | 13 | apacheCommonsText() 14 | lombok() 15 | slf4jLambdaApi() 16 | vavr() 17 | 18 | applyI18nFormatterAndTaintingCheckers() 19 | applySubtypingChecker() 20 | -------------------------------------------------------------------------------- /frontend/ui/impl/src/main/java/com/virtuslab/gitmachete/frontend/ui/impl/cell/BranchOrCommitCell.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.impl.cell; 2 | 3 | import io.vavr.collection.List; 4 | import lombok.Data; 5 | 6 | import com.virtuslab.gitmachete.frontend.graph.api.items.IGraphItem; 7 | import com.virtuslab.gitmachete.frontend.graph.api.render.parts.IRenderPart; 8 | 9 | @Data 10 | public final class BranchOrCommitCell { 11 | private final IGraphItem graphItem; 12 | private final String text; 13 | private final List renderParts; 14 | 15 | public BranchOrCommitCell( 16 | IGraphItem graphItem, 17 | List renderParts) { 18 | this.text = graphItem.getValue(); 19 | this.renderParts = renderParts; 20 | this.graphItem = graphItem; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/ui/impl/src/main/java/com/virtuslab/gitmachete/frontend/ui/impl/cell/BranchOrCommitCellRenderer.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.impl.cell; 2 | 3 | import java.awt.Component; 4 | 5 | import javax.swing.JTable; 6 | import javax.swing.table.TableCellRenderer; 7 | 8 | import lombok.RequiredArgsConstructor; 9 | import org.checkerframework.checker.guieffect.qual.UIEffect; 10 | 11 | @RequiredArgsConstructor 12 | public class BranchOrCommitCellRenderer implements TableCellRenderer { 13 | private final boolean shouldDisplayActionToolTips; 14 | 15 | @Override 16 | @UIEffect 17 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, 18 | int column) { 19 | return new BranchOrCommitCellRendererComponent(table, value, isSelected, hasFocus, row, column, 20 | shouldDisplayActionToolTips); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend/ui/impl/src/main/java/com/virtuslab/gitmachete/frontend/ui/impl/root/GitMacheteContentProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.impl.root; 2 | 3 | import javax.swing.JComponent; 4 | 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.openapi.vcs.changes.ui.ChangesViewContentProvider; 7 | import org.checkerframework.checker.guieffect.qual.UIEffect; 8 | 9 | public class GitMacheteContentProvider implements ChangesViewContentProvider { 10 | private final Project project; 11 | 12 | public GitMacheteContentProvider(Project project) { 13 | this.project = project; 14 | } 15 | 16 | @Override 17 | @UIEffect 18 | public JComponent initContent() { 19 | return new GitMachetePanel(project); 20 | } 21 | 22 | @Override 23 | public void disposeContent() {} 24 | 25 | } 26 | -------------------------------------------------------------------------------- /frontend/ui/impl/src/main/java/com/virtuslab/gitmachete/frontend/ui/impl/root/GitMacheteVisibilityPredicate.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.impl.root; 2 | 3 | import java.util.function.Predicate; 4 | 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.vcs.log.impl.VcsProjectLog; 7 | import lombok.CustomLog; 8 | 9 | @CustomLog 10 | public class GitMacheteVisibilityPredicate implements Predicate { 11 | 12 | @Override 13 | public boolean test(Project project) { 14 | boolean predicateResult = !VcsProjectLog.getLogProviders(project).isEmpty(); 15 | LOG.debug(() -> "Visibility predicate returned ${predicateResult}"); 16 | return predicateResult; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /frontend/ui/impl/src/main/java/com/virtuslab/gitmachete/frontend/ui/impl/table/SimpleGraphTableProvider.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.impl.table; 2 | 3 | import org.checkerframework.checker.guieffect.qual.UIEffect; 4 | 5 | import com.virtuslab.gitmachete.backend.api.IGitMacheteRepositorySnapshot; 6 | import com.virtuslab.gitmachete.frontend.ui.api.table.BaseGraphTable; 7 | import com.virtuslab.gitmachete.frontend.ui.api.table.ISimpleGraphTableProvider; 8 | 9 | public class SimpleGraphTableProvider implements ISimpleGraphTableProvider { 10 | @Override 11 | @UIEffect 12 | public BaseGraphTable deriveInstance(IGitMacheteRepositorySnapshot macheteRepositorySnapshot, 13 | boolean isListingCommitsEnabled, boolean shouldDisplayActionToolTips) { 14 | // The reinstantiation is needed every time because without it 15 | // the table keeps the first IDE theme despite the theme changes. 16 | return SimpleGraphTable.deriveInstance(macheteRepositorySnapshot, isListingCommitsEnabled, shouldDisplayActionToolTips); 17 | } 18 | 19 | @Override 20 | @UIEffect 21 | public BaseGraphTable deriveDemoInstance() { 22 | return deriveInstance(new DemoGitMacheteRepositorySnapshot(), /* isListingCommitsEnabled */ true, 23 | /* shouldDisplayActionToolTips */ false); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /frontend/ui/impl/src/main/java/com/virtuslab/gitmachete/frontend/ui/impl/table/UnmanagedBranchNotification.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitmachete.frontend.ui.impl.table; 2 | 3 | import static com.virtuslab.gitmachete.frontend.resourcebundles.GitMacheteBundle.getString; 4 | 5 | import com.intellij.notification.Notification; 6 | import com.intellij.notification.NotificationType; 7 | import com.intellij.openapi.vcs.VcsNotifier; 8 | import lombok.Getter; 9 | import lombok.experimental.ExtensionMethod; 10 | 11 | import com.virtuslab.gitmachete.frontend.resourcebundles.GitMacheteBundle; 12 | 13 | @ExtensionMethod(GitMacheteBundle.class) 14 | public class UnmanagedBranchNotification extends Notification { 15 | 16 | @Getter 17 | private final String branchName; 18 | 19 | UnmanagedBranchNotification(String branchName) { 20 | super(VcsNotifier.STANDARD_NOTIFICATION.getDisplayId(), 21 | getString("action.GitMachete.EnhancedGraphTable.unmanaged-branch-notification.text").fmt(branchName), 22 | NotificationType.INFORMATION); 23 | this.branchName = branchName; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gitCore/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { api(project(":qual")) } 4 | 5 | lombok() 6 | vavr() 7 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/GitCoreCannotAccessGitDirectoryException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class GitCoreCannotAccessGitDirectoryException extends GitCoreException {} 8 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/GitCoreException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class GitCoreException extends Exception { 8 | public static GitCoreException getOrWrap(Throwable e) { 9 | return e instanceof GitCoreException ? (GitCoreException) e : new GitCoreException(e); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/GitCoreNoSuchRevisionException.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import lombok.experimental.StandardException; 4 | 5 | @StandardException 6 | @SuppressWarnings("nullness:argument") 7 | public class GitCoreNoSuchRevisionException extends GitCoreException {} 8 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/GitCoreRelativeCommitCount.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import lombok.Data; 4 | import lombok.ToString; 5 | 6 | @Data(staticConstructor = "of") 7 | @ToString 8 | public class GitCoreRelativeCommitCount { 9 | private final int ahead; 10 | private final int behind; 11 | } 12 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/GitCoreRepositoryState.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | public enum GitCoreRepositoryState { 4 | NO_OPERATION, APPLYING, BISECTING, CHERRY_PICKING, MERGING, REBASING, REVERTING 5 | } 6 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreCheckoutEntry.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | public interface IGitCoreCheckoutEntry { 4 | String getFromBranchName(); 5 | 6 | String getToBranchName(); 7 | } 8 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreCommit.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import java.time.Instant; 4 | 5 | import org.checkerframework.checker.interning.qual.FindDistinct; 6 | import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; 7 | import org.checkerframework.checker.nullness.qual.Nullable; 8 | 9 | /** 10 | * The only criterion for equality of any instances of any class implementing this interface is equality of {@link #getHash} 11 | */ 12 | public interface IGitCoreCommit { 13 | String getShortMessage(); 14 | 15 | String getFullMessage(); 16 | 17 | Instant getCommitTime(); 18 | 19 | IGitCoreCommitHash getHash(); 20 | 21 | IGitCoreTreeHash getTreeHash(); 22 | 23 | @EnsuresNonNullIf(expression = "#2", result = true) 24 | static boolean defaultEquals(@FindDistinct IGitCoreCommit self, @Nullable Object other) { 25 | if (self == other) { 26 | return true; 27 | } else if (!(other instanceof IGitCoreCommit)) { 28 | return false; 29 | } else { 30 | return self.getHash().equals(((IGitCoreCommit) other).getHash()); 31 | } 32 | } 33 | 34 | static int defaultHashCode(IGitCoreCommit self) { 35 | return self.getHash().hashCode(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreCommitHash.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | public interface IGitCoreCommitHash extends IGitCoreObjectHash {} 4 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreHeadSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import io.vavr.collection.List; 4 | import org.checkerframework.checker.nullness.qual.Nullable; 5 | 6 | /** 7 | * An immutable snapshot of git repository's HEAD for some specific moment in time. 8 | * Each {@code get...} method is guaranteed to return the same value each time it's called on a given object. 9 | */ 10 | public interface IGitCoreHeadSnapshot { 11 | /** 12 | * @return a branch pointed by HEAD, or null in case of detached HEAD 13 | */ 14 | @Nullable 15 | IGitCoreLocalBranchSnapshot getTargetBranch(); 16 | 17 | List getReflogFromMostRecent(); 18 | } 19 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreLocalBranchSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import org.checkerframework.checker.nullness.qual.Nullable; 4 | 5 | public interface IGitCoreLocalBranchSnapshot extends IGitCoreBranchSnapshot { 6 | 7 | @Override 8 | default boolean isLocal() { 9 | return true; 10 | } 11 | 12 | @Nullable 13 | IGitCoreRemoteBranchSnapshot getRemoteTrackingBranch(); 14 | } 15 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreReflogEntry.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import java.time.Instant; 4 | 5 | import org.checkerframework.checker.nullness.qual.Nullable; 6 | import org.checkerframework.dataflow.qual.Pure; 7 | 8 | public interface IGitCoreReflogEntry { 9 | @Pure 10 | String getComment(); 11 | 12 | @Pure 13 | Instant getTimestamp(); 14 | 15 | @Pure 16 | @Nullable 17 | IGitCoreCommitHash getOldCommitHash(); 18 | 19 | @Pure 20 | IGitCoreCommitHash getNewCommitHash(); 21 | 22 | /** 23 | * @return a {@link IGitCoreCheckoutEntry} if this reflog entry corresponds to a checkout; 24 | * otherwise, null 25 | */ 26 | @Nullable 27 | IGitCoreCheckoutEntry parseCheckout(); 28 | } 29 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreRemoteBranchSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | public interface IGitCoreRemoteBranchSnapshot extends IGitCoreBranchSnapshot { 4 | @Override 5 | default boolean isLocal() { 6 | return false; 7 | } 8 | 9 | String getRemoteName(); 10 | } 11 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | import java.nio.file.Path; 4 | 5 | import com.virtuslab.qual.guieffect.UIThreadUnsafe; 6 | 7 | public interface IGitCoreRepositoryFactory { 8 | @UIThreadUnsafe 9 | IGitCoreRepository create(Path rootDirectoryPath, Path mainGitDirectoryPath, Path worktreeGitDirectoryPath) 10 | throws GitCoreException; 11 | } 12 | -------------------------------------------------------------------------------- /gitCore/api/src/main/java/com/virtuslab/gitcore/api/IGitCoreTreeHash.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.api; 2 | 3 | public interface IGitCoreTreeHash extends IGitCoreObjectHash {} 4 | -------------------------------------------------------------------------------- /gitCore/jGit/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.virtuslab.gitmachete.buildsrc.* 2 | 3 | dependencies { 4 | api(project(":gitCore:api")) 5 | 6 | testImplementation(testFixtures(project(":testCommon"))) 7 | } 8 | 9 | jgit() 10 | junit() 11 | lombok() 12 | slf4jLambdaApi() 13 | slf4jMock() 14 | vavr() 15 | 16 | applyAliasingChecker() 17 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/BaseGitCoreBranchSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import io.vavr.collection.List; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | 8 | import com.virtuslab.gitcore.api.IGitCoreBranchSnapshot; 9 | import com.virtuslab.gitcore.api.IGitCoreReflogEntry; 10 | 11 | @RequiredArgsConstructor 12 | public abstract class BaseGitCoreBranchSnapshot implements IGitCoreBranchSnapshot { 13 | 14 | /** 15 | * {@code X} part of {@code refs/heads/X} or {@code refs/heads/[remote-name]/X} 16 | */ 17 | protected final String shortName; 18 | 19 | @Getter 20 | private final GitCoreCommit pointedCommit; 21 | 22 | @Getter 23 | private final List reflogFromMostRecent; 24 | 25 | public abstract String getBranchTypeString(boolean capitalized); 26 | 27 | @Override 28 | public final boolean equals(@Nullable Object other) { 29 | return IGitCoreBranchSnapshot.defaultEquals(this, other); 30 | } 31 | 32 | @Override 33 | public final int hashCode() { 34 | return IGitCoreBranchSnapshot.defaultHashCode(this); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/BranchFullNameUtils.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import org.eclipse.jgit.lib.Constants; 4 | 5 | final class BranchFullNameUtils { 6 | private BranchFullNameUtils() {} 7 | 8 | static String getLocalBranchFullName(String localBranchName) { 9 | return Constants.R_HEADS + localBranchName; 10 | } 11 | 12 | static String getRemoteBranchName(String remoteName, String remoteBranchShortName) { 13 | return remoteName + "/" + remoteBranchShortName; 14 | } 15 | 16 | static String getRemoteBranchFullName(String remoteName, String remoteBranchShortName) { 17 | return Constants.R_REMOTES + getRemoteBranchName(remoteName, remoteBranchShortName); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/GitCoreCheckoutEntry.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Data; 5 | import lombok.RequiredArgsConstructor; 6 | import org.eclipse.jgit.lib.CheckoutEntry; 7 | 8 | import com.virtuslab.gitcore.api.IGitCoreCheckoutEntry; 9 | 10 | @Data 11 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE) 12 | public class GitCoreCheckoutEntry implements IGitCoreCheckoutEntry { 13 | private final String fromBranchName; 14 | private final String toBranchName; 15 | 16 | static GitCoreCheckoutEntry of(CheckoutEntry checkoutEntry) { 17 | return new GitCoreCheckoutEntry(checkoutEntry.getFromBranch(), checkoutEntry.getToBranch()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/GitCoreCommitHash.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import org.checkerframework.checker.nullness.qual.Nullable; 4 | import org.eclipse.jgit.lib.ObjectId; 5 | 6 | import com.virtuslab.gitcore.api.IGitCoreCommitHash; 7 | 8 | public final class GitCoreCommitHash extends GitCoreObjectHash implements IGitCoreCommitHash { 9 | 10 | private GitCoreCommitHash(ObjectId objectId) { 11 | super(objectId); 12 | } 13 | 14 | public static GitCoreCommitHash toGitCoreCommitHash(ObjectId objectId) { 15 | return new GitCoreCommitHash(objectId); 16 | } 17 | 18 | public static @Nullable IGitCoreCommitHash toGitCoreCommitHashOption(ObjectId objectId) { 19 | return objectId.equals(ObjectId.zeroId()) ? null : toGitCoreCommitHash(objectId); 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return ""; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/GitCoreHeadSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import io.vavr.collection.List; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.ToString; 7 | import org.checkerframework.checker.nullness.qual.Nullable; 8 | 9 | import com.virtuslab.gitcore.api.IGitCoreHeadSnapshot; 10 | import com.virtuslab.gitcore.api.IGitCoreLocalBranchSnapshot; 11 | import com.virtuslab.gitcore.api.IGitCoreReflogEntry; 12 | 13 | @RequiredArgsConstructor 14 | @ToString(onlyExplicitlyIncluded = true) 15 | public class GitCoreHeadSnapshot implements IGitCoreHeadSnapshot { 16 | 17 | @ToString.Include 18 | private final @Nullable IGitCoreLocalBranchSnapshot targetBranch; 19 | 20 | @Getter 21 | private final List reflogFromMostRecent; 22 | 23 | @Override 24 | public @Nullable IGitCoreLocalBranchSnapshot getTargetBranch() { 25 | return targetBranch; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/GitCoreObjectHash.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import org.checkerframework.checker.nullness.qual.Nullable; 7 | import org.checkerframework.common.value.qual.ArrayLen; 8 | import org.eclipse.jgit.lib.ObjectId; 9 | 10 | import com.virtuslab.gitcore.api.IGitCoreObjectHash; 11 | 12 | @RequiredArgsConstructor(access = AccessLevel.PACKAGE) 13 | public abstract class GitCoreObjectHash implements IGitCoreObjectHash { 14 | 15 | @Getter(AccessLevel.PACKAGE) 16 | private final ObjectId objectId; 17 | 18 | @Override 19 | public final @ArrayLen(40) String getHashString() { 20 | return objectId.getName(); 21 | } 22 | 23 | @Override 24 | public abstract String toString(); 25 | 26 | @Override 27 | public final boolean equals(@Nullable Object other) { 28 | return IGitCoreObjectHash.defaultEquals(this, other); 29 | } 30 | 31 | @Override 32 | public final int hashCode() { 33 | return IGitCoreObjectHash.defaultHashCode(this); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/GitCoreRemoteBranchSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import io.vavr.collection.List; 4 | import lombok.Getter; 5 | 6 | import com.virtuslab.gitcore.api.IGitCoreReflogEntry; 7 | import com.virtuslab.gitcore.api.IGitCoreRemoteBranchSnapshot; 8 | 9 | public class GitCoreRemoteBranchSnapshot extends BaseGitCoreBranchSnapshot implements IGitCoreRemoteBranchSnapshot { 10 | 11 | @Getter 12 | private final String remoteName; 13 | 14 | public GitCoreRemoteBranchSnapshot( 15 | String shortName, 16 | GitCoreCommit pointedCommit, 17 | List reflog, 18 | String remoteName) { 19 | super(shortName, pointedCommit, reflog); 20 | this.remoteName = remoteName; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return BranchFullNameUtils.getRemoteBranchName(remoteName, shortName); 26 | } 27 | 28 | @Override 29 | public String getFullName() { 30 | return BranchFullNameUtils.getRemoteBranchFullName(remoteName, shortName); 31 | } 32 | 33 | @Override 34 | public String getBranchTypeString(boolean capitalized) { 35 | return capitalized ? "Remote" : "remote"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/GitCoreRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import java.nio.file.Path; 4 | 5 | import com.virtuslab.gitcore.api.GitCoreException; 6 | import com.virtuslab.gitcore.api.IGitCoreRepository; 7 | import com.virtuslab.gitcore.api.IGitCoreRepositoryFactory; 8 | import com.virtuslab.qual.guieffect.UIThreadUnsafe; 9 | 10 | public class GitCoreRepositoryFactory implements IGitCoreRepositoryFactory { 11 | @UIThreadUnsafe 12 | public IGitCoreRepository create(Path rootDirectoryPath, Path mainGitDirectoryPath, Path worktreeGitDirectoryPath) 13 | throws GitCoreException { 14 | return new GitCoreRepository(rootDirectoryPath, mainGitDirectoryPath, worktreeGitDirectoryPath); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gitCore/jGit/src/main/java/com/virtuslab/gitcore/impl/jgit/GitCoreTreeHash.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import org.eclipse.jgit.lib.ObjectId; 4 | 5 | import com.virtuslab.gitcore.api.IGitCoreTreeHash; 6 | 7 | public final class GitCoreTreeHash extends GitCoreObjectHash implements IGitCoreTreeHash { 8 | 9 | private GitCoreTreeHash(ObjectId objectId) { 10 | super(objectId); 11 | } 12 | 13 | public static IGitCoreTreeHash toGitCoreTreeHash(ObjectId objectId) { 14 | return new GitCoreTreeHash(objectId); 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return ""; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gitCore/jGit/src/test/java/com/virtuslab/gitcore/impl/jgit/GitCoreCommitUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.gitcore.impl.jgit; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.nio.charset.StandardCharsets; 6 | 7 | import lombok.val; 8 | import org.eclipse.jgit.revwalk.RevCommit; 9 | import org.junit.jupiter.api.Test; 10 | 11 | public class GitCoreCommitUnitTest { 12 | 13 | private static final String rawCommitData = """ 14 | tree b8518260a35f740dbaa8161feda53017ab8c8be4 15 | parent e3be034fdef163e288f8219664f0df447bfe0ec3 16 | author foo 1664994622 +0200 17 | author foo 1664994622 +0200 18 | 19 | First line of subject 20 | - another line of subject 21 | - moar lines of subject 22 | 23 | First line of description 24 | More lines of description 25 | """; 26 | 27 | @Test 28 | public void shouldOnlyIncludeFirstLineOfSubjectInShortMessage() { 29 | val revCommit = RevCommit.parse(rawCommitData.getBytes(StandardCharsets.UTF_8)); 30 | val commit = new GitCoreCommit(revCommit); 31 | 32 | assertEquals("First line of subject", commit.getShortMessage()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.stdlib.default.dependency=false 2 | org.gradle.caching=true 3 | org.gradle.configureOnDemand=true 4 | org.gradle.jvmargs=-Xmx3G 5 | org.gradle.parallel=true 6 | org.jetbrains.intellij.platform.buildFeature.selfUpdateCheck=false 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /intellij-versions.properties: -------------------------------------------------------------------------------- 1 | eapOfLatestSupportedMajor=252.19874.12-EAP-SNAPSHOT 2 | earliestSupportedMajor=2024.2 3 | earliestSupportedMajorKotlinVersion=1.9 4 | latestMinorsOfOldSupportedMajors=2024.2.6,2024.3.6 5 | latestStable=2025.1.2 6 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | # So that Lombok doesn't try to search for lombok.config file in subfolders. 2 | config.stopBubbling = true 3 | 4 | # So that Lombok-generated `equals` methods have its parameter marked as `@Nullable`; 5 | # otherwise Checker would raise an error about breaking inheritance contract with `java.lang.Object#equals`. 6 | lombok.addNullAnnotations = checkerframework 7 | lombok.equalsAndHashCode.callSuper = call 8 | lombok.log.custom.declaration = kr.pe.kwonnam.slf4jlambda.LambdaLogger kr.pe.kwonnam.slf4jlambda.LambdaLoggerFactory.getLogger(TYPE) 9 | lombok.log.fieldName = LOG 10 | lombok.toString.callSuper = call 11 | -------------------------------------------------------------------------------- /qual/build.gradle.kts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VirtusLab/git-machete-intellij-plugin/63bbccfb0fe440ef2e75744abfab688ad92cfe01/qual/build.gradle.kts -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/async/BackgroundableQueuedElsewhere.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.async; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Used to mark methods that create an instance of {@code com.intellij.openapi.progress.Task.Backgroundable}, 10 | * but do not call {@code #queue()}. 11 | *

12 | * Typically, it is a smell that indicates that the programmer forgot to actually schedule the task. 13 | * Such cases are detected by ArchUnit test {@code com.virtuslab.archunit.BackgroundTaskEnqueuingTestSuite}. 14 | * Still, in some rare cases it might happen that a method passes the newly-created backgroundable 15 | * to downstream APIs to actually enqueue. 16 | * Such methods must be marked as {@link BackgroundableQueuedElsewhere} for {@code BackgroundTaskEnqueuingTestSuite} to ignore. 17 | *

18 | * This annotation must have runtime retention to be visible to ArchUnit tests. 19 | */ 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Target({ElementType.METHOD}) 22 | public @interface BackgroundableQueuedElsewhere {} 23 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/async/ContinuesInBackground.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.async; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Used to mark methods that schedule a background task. 10 | * It is not enforced during compilation whether the annotation is used correctly. 11 | * Its purpose is to make the programmer aware of the increased risk of race conditions, 12 | * esp. to avoid treating such methods as if they completed in a fully synchronous/blocking manner. 13 | *

14 | * As for now, we use an ArchUnit test {@code com.virtuslab.archunit.BackgroundTaskEnqueuingTestSuite} 15 | * to enforce that: 16 | *

    17 | *
  1. methods that call {@code queue()} on classes extending {@code Task.Backgroundable} are marked as {@link ContinuesInBackground}
  2. 18 | *
  3. methods that call {@code git4idea.branch.GitBrancher#checkout} are marked as {@link ContinuesInBackground}
  4. 19 | *
  5. methods that call {@link ContinuesInBackground} methods are themselves marked as {@link ContinuesInBackground}
  6. 20 | *
21 | *

22 | * This annotation must have runtime retention to be visible to ArchUnit tests. 23 | */ 24 | @Retention(RetentionPolicy.RUNTIME) 25 | @Target({ElementType.METHOD}) 26 | public @interface ContinuesInBackground {} 27 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/async/DoesNotContinueInBackground.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.async; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Used to mark methods that get a free pass on calling {@link ContinuesInBackground} methods, 10 | * despite not being marked as {@link ContinuesInBackground} themselves. 11 | *

12 | * This is only taken into account by ArchUnit test {@code com.virtuslab.archunit.BackgroundTaskEnqueuingTestSuite} 13 | * that enforces the correct usage of {@link ContinuesInBackground} annotation. 14 | *

15 | * This annotation must have runtime retention to be visible to ArchUnit tests. 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 19 | public @interface DoesNotContinueInBackground { 20 | String reason(); 21 | } 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/guieffect/IgnoreUIThreadUnsafeCalls.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.guieffect; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Used to mark methods that get a free pass on calling {@link UIThreadUnsafe} methods, 10 | * despite not being marked as {@link UIThreadUnsafe} themselves. 11 | *

12 | * This is only taken into account by ArchUnit test {@code com.virtuslab.archunit.UIThreadUnsafeMethodInvocationsTestSuite} 13 | * that enforces the correct usage of {@link UIThreadUnsafe} annotation. 14 | *

15 | * Needs to be used sparingly, as this basically allows for a method to call potentially heavyweight operations on UI thread. 16 | * And that, in turn, might lead to UI freeze. 17 | *

18 | * This annotation must have runtime retention to be visible to ArchUnit tests. 19 | */ 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 22 | public @interface IgnoreUIThreadUnsafeCalls { 23 | /** 24 | * {@code value} must include full names (in the format as returned by 25 | * {@code com.tngtech.archunit.core.domain.AccessTarget#getFullName()}) 26 | * of UI-thread-unsafe methods that can legally be called from the annotated method. 27 | */ 28 | String[] value(); 29 | } 30 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/backend/api/ConfirmedLocal.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.backend.api; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.backend.api.IBranchReference} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.backend.api.ILocalBranchReference}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedLocal {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/backend/api/ConfirmedNonRoot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.backend.api; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.backend.api.IManagedBranchSnapshot} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.backend.api.INonRootManagedBranchSnapshot}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedNonRoot {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/backend/api/ConfirmedRemote.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.backend.api; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.backend.api.IBranchReference} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.backend.api.IRemoteBranchReference}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedRemote {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/backend/api/ConfirmedRoot.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.backend.api; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.backend.api.IManagedBranchSnapshot} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.backend.api.IRootManagedBranchSnapshot}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedRoot {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/frontend/graph/api/elements/ConfirmedGraphEdge.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.frontend.graph.api.elements; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.frontend.graph.api.elements.IGraphElement} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.frontend.graph.api.elements.GraphEdge}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedGraphEdge {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/frontend/graph/api/elements/ConfirmedGraphNode.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.frontend.graph.api.elements; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.frontend.graph.api.elements.IGraphElement} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.frontend.graph.api.elements.GraphNode}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedGraphNode {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/frontend/graph/api/items/ConfirmedBranchItem.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.frontend.graph.api.items; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.frontend.graph.api.items.IBranchItem} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.frontend.graph.impl.items.BranchItem}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedBranchItem {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/gitmachete/frontend/graph/api/items/ConfirmedCommitItem.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.gitmachete.frontend.graph.api.items; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.SubtypeOf; 9 | 10 | import com.virtuslab.qual.subtyping.internal.SubtypingTop; 11 | 12 | /** 13 | * Used to annotate a type of a {@code com.virtuslab.gitmachete.frontend.graph.api.items.IBranchItem} object 14 | * that has been statically proven to be a {@code com.virtuslab.gitmachete.frontend.graph.impl.items.CommitItem}. 15 | *

16 | * See Subtyping Checker manual. 17 | */ 18 | @Retention(RetentionPolicy.CLASS) 19 | @SubtypeOf(SubtypingTop.class) 20 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 21 | public @interface ConfirmedCommitItem {} 22 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/internal/SubtypingTop.java: -------------------------------------------------------------------------------- 1 | package com.virtuslab.qual.subtyping.internal; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import org.checkerframework.framework.qual.DefaultQualifierInHierarchy; 9 | import org.checkerframework.framework.qual.SubtypeOf; 10 | 11 | /** 12 | * There needs to be single subtyping hierarchy with single bottom and top annotation. 13 | * We could theoretically create a separate hierarchy with a dedicated top and bottom type 14 | * for each pair of annotations from {@link com.virtuslab.qual.subtyping}.* packages, 15 | * but then Subtyping Checker 16 | * would raise an error about multiple top/bottom types. 17 | */ 18 | @DefaultQualifierInHierarchy 19 | @Retention(RetentionPolicy.CLASS) 20 | @SubtypeOf({}) 21 | @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) 22 | public @interface SubtypingTop {} 23 | -------------------------------------------------------------------------------- /qual/src/main/java/com/virtuslab/qual/subtyping/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Module private. Do not use outside {@link com.virtuslab.qual.subtyping}. 3 | */ 4 | package com.virtuslab.qual.subtyping.internal; 5 | -------------------------------------------------------------------------------- /scalafmt.conf: -------------------------------------------------------------------------------- 1 | version = 3.5.9 2 | runner.dialect = scala213 3 | maxColumn = 120 4 | -------------------------------------------------------------------------------- /scripts/close-github-milestone: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e -o pipefail -u -x 4 | 5 | milestone_title=$1 6 | 7 | milestones_json_array=$(gh api repos/VirtusLab/git-machete-intellij-plugin/milestones) 8 | milestone=$(echo "$milestones_json_array" | jq -c --arg TITLE "$milestone_title" '.[] | select(.title == $TITLE)') 9 | 10 | number=$(echo "$milestone" | jq '.number') 11 | # open issues and PRs are counted together in the same field 12 | open_issue_count=$(echo "$milestone" | jq '.open_issues') 13 | 14 | if [[ $open_issue_count = 0 ]]; then 15 | gh api --method PATCH "repos/VirtusLab/git-machete-intellij-plugin/milestones/$number" -f state=closed 16 | fi 17 | -------------------------------------------------------------------------------- /scripts/enforce-astub-explicit-annotation-import: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e -o pipefail -u 4 | 5 | self_dir=$(cd "$(dirname "$0")" &>/dev/null; pwd -P) 6 | source "$self_dir"/utils.sh 7 | 8 | exit_code=0 9 | 10 | for file in $(git ls-files '*.astub'); do 11 | annotations_imported_in_file=$(grep -Po '(?<=import ).*(?=;)' "$file" | rev | cut -d. -f1 | rev | sort -u) 12 | annotations_used_across_file=$(grep -Po '(?<=@)[a-zA-Z0-9.]*' "$file" | sort -u) 13 | 14 | # Print the lines missing from the first input but present in the second 15 | unimported_annotations=$(comm -13 <(echo "$annotations_imported_in_file") <(echo "$annotations_used_across_file")) 16 | if [[ $unimported_annotations ]]; then 17 | echo "$file: $(echo -n "$unimported_annotations" | tr '\n' ',' | sed 's/,/, /g') must be imported explicitly" 18 | exit_code=1 19 | fi 20 | 21 | # Print the lines present in the first input but missing from the second 22 | unused_annotations=$(comm -23 <(echo "$annotations_imported_in_file") <(echo "$annotations_used_across_file")) 23 | if [[ $unused_annotations ]]; then 24 | echo "$file: $(echo -n "$unused_annotations" | tr '\n' ',' | sed 's/,/, /g') imported but unused" 25 | exit_code=1 26 | fi 27 | done 28 | 29 | exit $exit_code 30 | -------------------------------------------------------------------------------- /scripts/enforce-change-notes-updated-on-pr-to-master: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e -o pipefail -u 4 | 5 | self_dir=$(cd "$(dirname "$0")" &>/dev/null; pwd -P) 6 | source "$self_dir"/utils.sh 7 | 8 | if [[ ${CI_PULL_REQUEST-} && ${GITHUB_TOKEN-} ]]; then 9 | # In case of a PR build, CI_PULL_REQUEST should be a link of the form https://github.com/VirtusLab/git-machete-intellij-plugin/pull/123 10 | pr_num=${CI_PULL_REQUEST##*/} 11 | # Implicit usage of ${GITHUB_TOKEN} by gh 12 | base_branch=$(gh pr view "$pr_num" --json "baseRefName") 13 | 14 | # PRs to master are typically either release or hotfix PRs, both of which should have change notes updated 15 | if [[ $base_branch == master ]]; then 16 | ./gradlew -q verifyChangeLogContents 17 | fi 18 | fi 19 | -------------------------------------------------------------------------------- /scripts/enforce-indent-two-spaces-outside-java: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e -o pipefail -u 4 | 5 | self_dir=$(cd "$(dirname "$0")" &>/dev/null; pwd -P) 6 | self_name=$(basename -s .sh "$0") 7 | 8 | git ls-files \ 9 | ':!*.flex' ':!gradlew' ':!*.java' ':!*.kt' ':!*.md' \ 10 | ':!plugin-verifier.gradle' '!*.scala' ':!scripts/setup-multiroot-sandbox' \ 11 | ':!*.svg' ':!testCommon/src/test/resources/*.sh' ':!*.xml' \ 12 | | xargs awk -f "$self_dir/$self_name.awk" 13 | -------------------------------------------------------------------------------- /scripts/enforce-indent-two-spaces-outside-java.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk 2 | 3 | FNR == 1 { prev_non_empty = "" } 4 | 5 | ( /^ {3}/ && prev_non_empty !~ /^ {2}/ ) || ( /^ {5}/ && prev_non_empty !~ /^ {4}/ ) { 6 | print FILENAME ":" FNR ": likely three or four spaces used for indent instead of two" 7 | exit_code = 1 8 | } 9 | 10 | /^.+$/ { prev_non_empty = $0 } 11 | 12 | END { exit exit_code } 13 | -------------------------------------------------------------------------------- /scripts/enforce-issue-number-for-todos: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e -o pipefail -u 4 | 5 | self_dir=$(cd "$(dirname "$0")" &>/dev/null; pwd -P) 6 | source "$self_dir"/utils.sh 7 | 8 | # Negative lookahead (?!...), requires Perl syntax (-P): find fixmes/todos NOT followed by issue number 9 | if git grep -PIin '(\*|//|#|