Skip to content

Commit de02829

Browse files
committed
Added automatic snapshot of uncommited changes before merge
Fixes #214
1 parent abbe47f commit de02829

File tree

7 files changed

+366
-3
lines changed

7 files changed

+366
-3
lines changed

src/main/composeResources/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,8 @@
7777
<string name="uncommited_changes_primary_button_skip">Skip</string>
7878
<string name="uncommited_changes_secondary_button_abort">Abort</string>
7979
<string name="uncommited_changes_amend_check">Amend previous commit</string>
80+
81+
<!-- Merge automatic stash -->
82+
<string name="merge_automatic_stash_description">Automatic stash before merge of "%1$s" to "%2$s"</string>
83+
<string name="pull_with_merge_automatic_stash_description">Automatic stash before pull of "%1$s"</string>
8084
</resources>

src/main/kotlin/com/jetpackduba/gitnuro/git/branches/MergeBranchUseCase.kt

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,51 @@
11
package com.jetpackduba.gitnuro.git.branches
22

33
import com.jetpackduba.gitnuro.exceptions.UncommittedChangesDetectedException
4+
import com.jetpackduba.gitnuro.extensions.simpleName
5+
import com.jetpackduba.gitnuro.generated.resources.Res
6+
import com.jetpackduba.gitnuro.generated.resources.merge_automatic_stash_description
7+
import com.jetpackduba.gitnuro.git.stash.DeleteStashUseCase
8+
import com.jetpackduba.gitnuro.git.stash.SnapshotStashCreateCommand
9+
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommittedChangesUseCase
10+
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
411
import kotlinx.coroutines.Dispatchers
512
import kotlinx.coroutines.withContext
613
import org.eclipse.jgit.api.Git
714
import org.eclipse.jgit.api.MergeCommand
815
import org.eclipse.jgit.api.MergeResult
916
import org.eclipse.jgit.lib.Ref
17+
import org.eclipse.jgit.revwalk.RevCommit
18+
import org.jetbrains.compose.resources.getString
1019
import javax.inject.Inject
1120

12-
class MergeBranchUseCase @Inject constructor() {
21+
class MergeBranchUseCase @Inject constructor(
22+
private val checkHasUncommittedChangesUseCase: CheckHasUncommittedChangesUseCase,
23+
private val deleteStashUseCase: DeleteStashUseCase,
24+
private val appSettingsRepository: AppSettingsRepository,
25+
) {
1326
/**
1427
* @return true if success has conflicts, false if success without conflicts
1528
*/
1629
suspend operator fun invoke(git: Git, branch: Ref, fastForward: Boolean) = withContext(Dispatchers.IO) {
30+
var backupStash: RevCommit? = null
31+
32+
if (appSettingsRepository.mergeAutoStash) {
33+
val hasUncommitedChanges = checkHasUncommittedChangesUseCase(git)
34+
if (hasUncommitedChanges) {
35+
val snapshotStashCreateCommand = SnapshotStashCreateCommand(
36+
repository = git.repository,
37+
workingDirectoryMessage = getString(
38+
Res.string.merge_automatic_stash_description,
39+
branch.simpleName,
40+
git.repository.branch
41+
),
42+
includeUntracked = true
43+
)
44+
45+
backupStash = snapshotStashCreateCommand.call()
46+
}
47+
}
48+
1749
val fastForwardMode = if (fastForward)
1850
MergeCommand.FastForwardMode.FF
1951
else
@@ -29,6 +61,12 @@ class MergeBranchUseCase @Inject constructor() {
2961
throw UncommittedChangesDetectedException("Merge failed, makes sure you repository doesn't contain uncommitted changes.")
3062
}
3163

32-
mergeResult.mergeStatus == MergeResult.MergeStatus.CONFLICTING
64+
val hasConflicts = mergeResult.mergeStatus == MergeResult.MergeStatus.CONFLICTING
65+
66+
if (!hasConflicts && backupStash != null) {
67+
deleteStashUseCase(git, backupStash)
68+
}
69+
70+
return@withContext hasConflicts
3371
}
3472
}

src/main/kotlin/com/jetpackduba/gitnuro/git/remote_operations/PullBranchUseCase.kt

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
package com.jetpackduba.gitnuro.git.remote_operations
22

3+
import com.jetpackduba.gitnuro.generated.resources.Res
4+
import com.jetpackduba.gitnuro.generated.resources.pull_with_merge_automatic_stash_description
5+
import com.jetpackduba.gitnuro.git.stash.DeleteStashUseCase
6+
import com.jetpackduba.gitnuro.git.stash.SnapshotStashCreateCommand
7+
import com.jetpackduba.gitnuro.git.workspace.CheckHasUncommittedChangesUseCase
38
import com.jetpackduba.gitnuro.repositories.AppSettingsRepository
49
import kotlinx.coroutines.Dispatchers
510
import kotlinx.coroutines.withContext
611
import org.eclipse.jgit.api.Git
712
import org.eclipse.jgit.lib.ConfigConstants
813
import org.eclipse.jgit.lib.Repository
14+
import org.eclipse.jgit.revwalk.RevCommit
915
import org.eclipse.jgit.transport.CredentialsProvider
16+
import org.jetbrains.compose.resources.getString
1017
import javax.inject.Inject
1118

1219
class PullBranchUseCase @Inject constructor(
20+
private val checkHasUncommittedChangesUseCase: CheckHasUncommittedChangesUseCase,
1321
private val handleTransportUseCase: HandleTransportUseCase,
1422
private val appSettingsRepository: AppSettingsRepository,
1523
private val hasPullResultConflictsUseCase: HasPullResultConflictsUseCase,
24+
private val deleteStashUseCase: DeleteStashUseCase,
1625
) {
1726
suspend operator fun invoke(git: Git, pullType: PullType): PullHasConflicts = withContext(Dispatchers.IO) {
1827
useBuiltinLfs(git.repository) {
@@ -22,7 +31,26 @@ class PullBranchUseCase @Inject constructor(
2231
PullType.DEFAULT -> appSettingsRepository.pullRebase
2332
}
2433

25-
handleTransportUseCase(git) {
34+
val pullWithMerge = !pullWithRebase
35+
var backupStash: RevCommit? = null
36+
37+
if (appSettingsRepository.mergeAutoStash && pullWithMerge) {
38+
val hasUncommitedChanges = checkHasUncommittedChangesUseCase(git)
39+
if (hasUncommitedChanges) {
40+
val snapshotStashCreateCommand = SnapshotStashCreateCommand(
41+
repository = git.repository,
42+
workingDirectoryMessage = getString(
43+
Res.string.pull_with_merge_automatic_stash_description,
44+
git.repository.branch
45+
),
46+
includeUntracked = true
47+
)
48+
49+
backupStash = snapshotStashCreateCommand.call()
50+
}
51+
}
52+
53+
val pullHasConflicts = handleTransportUseCase(git) {
2654
val pullResult = git
2755
.pull()
2856
.setTransportConfigCallback { this.handleTransport(it) }
@@ -32,6 +60,13 @@ class PullBranchUseCase @Inject constructor(
3260

3361
return@handleTransportUseCase hasPullResultConflictsUseCase(pullWithRebase, pullResult)
3462
}
63+
64+
if (!pullHasConflicts && backupStash != null) {
65+
deleteStashUseCase(git, backupStash)
66+
}
67+
68+
pullHasConflicts
69+
3570
}
3671
}
3772
}

0 commit comments

Comments
 (0)