From 71bf75cecafb36da98918e1124a8be8f1a6d56e3 Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Wed, 27 Oct 2021 20:41:05 +0200 Subject: [PATCH] Added merge feature --- build.gradle.kts | 2 +- src/main/kotlin/app/git/BranchesManager.kt | 14 ++++ src/main/kotlin/app/git/GitManager.kt | 7 ++ src/main/kotlin/app/ui/CommitChanges.kt | 21 ++--- src/main/kotlin/app/ui/GMenu.kt | 6 -- src/main/kotlin/app/ui/Log.kt | 46 +++++++++-- src/main/kotlin/app/ui/RepositoryOpen.kt | 3 + src/main/kotlin/app/ui/dialogs/MergeDialog.kt | 79 +++++++++++++++++++ 8 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 src/main/kotlin/app/ui/dialogs/MergeDialog.kt diff --git a/build.gradle.kts b/build.gradle.kts index a1468a0..e77386e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,7 +41,7 @@ tasks.withType() { compose.desktop { application { - mainClass = "MainKt" + mainClass = "app.MainKt" nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb, TargetFormat.AppImage) diff --git a/src/main/kotlin/app/git/BranchesManager.kt b/src/main/kotlin/app/git/BranchesManager.kt index 5ffb828..c5e2c0b 100644 --- a/src/main/kotlin/app/git/BranchesManager.kt +++ b/src/main/kotlin/app/git/BranchesManager.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.withContext import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.ListBranchCommand +import org.eclipse.jgit.api.MergeCommand import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.revwalk.RevCommit import javax.inject.Inject @@ -56,6 +57,19 @@ class BranchesManager @Inject constructor() { .call() } + suspend fun mergeBranch(git: Git, branch: Ref, fastForward: Boolean) = withContext(Dispatchers.IO) { + val fastForwardMode = if(fastForward) + MergeCommand.FastForwardMode.FF + else + MergeCommand.FastForwardMode.NO_FF + + git + .merge() + .include(branch) + .setFastForward(fastForwardMode) + .call() + } + suspend fun deleteBranch(git: Git, branch: Ref) = withContext(Dispatchers.IO) { git diff --git a/src/main/kotlin/app/git/GitManager.kt b/src/main/kotlin/app/git/GitManager.kt index e6c2bc1..436a434 100644 --- a/src/main/kotlin/app/git/GitManager.kt +++ b/src/main/kotlin/app/git/GitManager.kt @@ -287,6 +287,13 @@ class GitManager @Inject constructor( refreshRepositoryInfo() } } + + fun mergeBranch(ref: Ref, fastForward: Boolean) = managerScope.launch { + safeProcessing { + branchesManager.mergeBranch(safeGit, ref, fastForward) + refreshRepositoryInfo() + } + } } diff --git a/src/main/kotlin/app/ui/CommitChanges.kt b/src/main/kotlin/app/ui/CommitChanges.kt index d4812fe..b8c5c3d 100644 --- a/src/main/kotlin/app/ui/CommitChanges.kt +++ b/src/main/kotlin/app/ui/CommitChanges.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -61,15 +62,17 @@ fun CommitChanges( .fillMaxWidth() ) { Column { - Text( - text = commit.fullMessage, - fontSize = 14.sp, - modifier = Modifier - .fillMaxWidth() - .height(120.dp) - .padding(8.dp) - .verticalScroll(scroll), - ) + SelectionContainer { + Text( + text = commit.fullMessage, + fontSize = 14.sp, + modifier = Modifier + .fillMaxWidth() + .height(120.dp) + .padding(8.dp) + .verticalScroll(scroll), + ) + } Divider(modifier = Modifier.fillMaxWidth()) diff --git a/src/main/kotlin/app/ui/GMenu.kt b/src/main/kotlin/app/ui/GMenu.kt index 997616e..265585e 100644 --- a/src/main/kotlin/app/ui/GMenu.kt +++ b/src/main/kotlin/app/ui/GMenu.kt @@ -2,20 +2,14 @@ package app.ui import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* -import androidx.compose.material.ButtonDefaults import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.input.pointer.pointerMoveFilter import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp diff --git a/src/main/kotlin/app/ui/Log.kt b/src/main/kotlin/app/ui/Log.kt index ab1d8f8..4253278 100644 --- a/src/main/kotlin/app/ui/Log.kt +++ b/src/main/kotlin/app/ui/Log.kt @@ -35,6 +35,7 @@ import app.theme.headerText import app.theme.primaryTextColor import app.theme.secondaryTextColor import app.ui.components.ScrollableLazyColumn +import app.ui.dialogs.MergeDialog import app.ui.dialogs.NewBranchDialog import app.ui.dialogs.NewTagDialog import org.eclipse.jgit.lib.ObjectIdRef @@ -69,6 +70,7 @@ fun Log( onCreateBranchOnCommit: (branchName: String, graphNode: GraphNode) -> Unit, onCreateTagOnCommit: (tagName: String, graphNode: GraphNode) -> Unit, onCheckoutRef: (ref: Ref) -> Unit, + onMergeBranch: (ref: Ref, fastForwards: Boolean) -> Unit, selectedIndex: MutableState = remember { mutableStateOf(-1) } ) { val logStatusState = gitManager.logStatus.collectAsState() @@ -275,7 +277,22 @@ fun Log( commit = item, selected = selectedIndex.value == index, refs = commitRefs, - onCheckoutRef = onCheckoutRef + onCheckoutRef = onCheckoutRef, + onMergeBranch = { ref -> + dialogManager.show { + MergeDialog( + currentBranchName = "HEAD", + mergeBranchName = ref.name, + onReject = { + dialogManager.dismiss() + }, + onAccept = { fastForward -> + dialogManager.dismiss() + onMergeBranch(ref, fastForward) + } + ) + } + }, ) } } @@ -293,6 +310,7 @@ fun CommitMessage( selected: Boolean, refs: List, onCheckoutRef: (ref: Ref) -> Unit, + onMergeBranch: (ref: Ref) -> Unit, ) { val textColor = if (selected) { MaterialTheme.colors.primary @@ -326,6 +344,9 @@ fun CommitMessage( ref = ref, onCheckoutBranch = { onCheckoutRef(ref) + }, + onMergeBranch = { + onMergeBranch(ref) } ) } @@ -475,14 +496,29 @@ fun UncommitedChangesGraphLine( @OptIn(ExperimentalFoundationApi::class) @Composable -fun BranchChip(modifier: Modifier = Modifier, ref: Ref, onCheckoutBranch: () -> Unit) { +fun BranchChip( + modifier: Modifier = Modifier, + isCurrentBranch: Boolean = false, + ref: Ref, + onCheckoutBranch: () -> Unit, + onMergeBranch: () -> Unit, +) { val contextMenuItemsList = { - listOf( + mutableListOf( ContextMenuItem( label = "Checkout branch", onClick = onCheckoutBranch - ) - ) + ), + + ).apply { + if (!isCurrentBranch) + add( + ContextMenuItem( + label = "Merge branch", + onClick = onMergeBranch + ) + ) + } } RefChip( diff --git a/src/main/kotlin/app/ui/RepositoryOpen.kt b/src/main/kotlin/app/ui/RepositoryOpen.kt index f8a7b27..c7bef03 100644 --- a/src/main/kotlin/app/ui/RepositoryOpen.kt +++ b/src/main/kotlin/app/ui/RepositoryOpen.kt @@ -108,6 +108,9 @@ fun RepositoryOpenPage(gitManager: GitManager, dialogManager: DialogManager) { onCheckoutRef = { ref -> gitManager.checkoutRef(ref) }, + onMergeBranch = { ref , fastForward -> + gitManager.mergeBranch(ref, fastForward) + }, onRevCommitSelected = { commit -> selectedRevCommit = commit uncommitedChangesSelected = false diff --git a/src/main/kotlin/app/ui/dialogs/MergeDialog.kt b/src/main/kotlin/app/ui/dialogs/MergeDialog.kt new file mode 100644 index 0000000..93ed4d2 --- /dev/null +++ b/src/main/kotlin/app/ui/dialogs/MergeDialog.kt @@ -0,0 +1,79 @@ +package app.ui.dialogs + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusOrder +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@Composable +fun MergeDialog( + currentBranchName: String, + mergeBranchName: String, + fastForward: Boolean = false, + onReject: () -> Unit, + onAccept: (fastForward: Boolean) -> Unit +) { + var fastForwardCheck by remember { mutableStateOf(fastForward) } + + Column( + modifier = Modifier + .background(MaterialTheme.colors.background), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Row { + Text( + text = currentBranchName, + ) + + Text(" -----------> ") + + Text( + text = mergeBranchName, + ) + } + + Row { + Checkbox( + checked = fastForwardCheck, + onCheckedChange = { checked -> + fastForwardCheck = checked + } + ) + + Text( + "Fast forward", + modifier = Modifier.padding(start = 8.dp) + ) + + } + Row( + modifier = Modifier + .padding(top = 16.dp) + .align(Alignment.End) + ) { + TextButton( + modifier = Modifier.padding(end = 8.dp), + onClick = { + onReject() + } + ) { + Text("Cancel") + } + Button( + onClick = { + onAccept(fastForwardCheck) + } + ) { + Text("Merge") + } + } + } +} \ No newline at end of file