Skip to content

Commit 974bb27

Browse files
authored
Merge pull request #1641 from scala-steward-org/fix/1393
Fix (modify/delete) conflicts in GitAlg.mergeTheirs
2 parents fb03b08 + da0bb9a commit 974bb27

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

modules/core/src/main/scala/org/scalasteward/core/git/GitAlg.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,19 @@ object GitAlg {
163163
for {
164164
before <- latestSha1(repo, Branch.head)
165165
repoDir <- workspaceAlg.repoDir(repo)
166-
sign = if (config.signCommits) List("--gpg-sign") else List.empty[String]
166+
sign = if (config.signCommits) List("--gpg-sign") else List.empty
167167
_ <- exec(Nel.of("merge", "--strategy-option=theirs") ++ (sign :+ branch.name), repoDir)
168+
.handleErrorWith { throwable =>
169+
// Resolve CONFLICT (modify/delete) by deleting unmerged files:
170+
for {
171+
unmergedFiles <- exec(Nel.of("diff", "--name-only", "--diff-filter=U"), repoDir)
172+
_ <- Nel.fromList(unmergedFiles.filter(_.nonEmpty)) match {
173+
case Some(files) => files.traverse(file => exec(Nel.of("rm", file), repoDir))
174+
case None => F.raiseError(throwable)
175+
}
176+
_ <- commitAll(repo, "Remove unmerged files")
177+
} yield List.empty
178+
}
168179
after <- latestSha1(repo, Branch.head)
169180
} yield Option.when(before =!= after)(Commit())
170181

modules/core/src/test/scala/org/scalasteward/core/git/GitAlgTest.scala

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,23 @@ class GitAlgTest extends AnyFunSuite with Matchers {
124124
} yield (c1, m1, c2, m2)
125125
p.unsafeRunSync() shouldBe ((true, false, false, true))
126126
}
127+
128+
test("mergeTheirs: CONFLICT (modify/delete)") {
129+
val repo = Repo("merge", "theirs2")
130+
val p = for {
131+
repoDir <- workspaceAlg.repoDir(repo)
132+
_ <- GitAlgTest.createGitRepoWithConflictFileRemovedOnMaster[IO](repoDir)
133+
master = Branch("master")
134+
branch = Branch("conflicts-yes")
135+
c1 <- ioGitAlg.hasConflicts(repo, branch, master)
136+
m1 <- ioGitAlg.isMerged(repo, master, branch)
137+
_ <- ioGitAlg.checkoutBranch(repo, branch)
138+
_ <- ioGitAlg.mergeTheirs(repo, master)
139+
c2 <- ioGitAlg.hasConflicts(repo, branch, master)
140+
m2 <- ioGitAlg.isMerged(repo, master, branch)
141+
} yield (c1, m1, c2, m2)
142+
p.unsafeRunSync() shouldBe ((true, false, false, true))
143+
}
127144
}
128145

129146
object GitAlgTest {
@@ -159,4 +176,31 @@ object GitAlgTest {
159176
_ <- processAlg.exec(Nel.of("git", "add", "file2"), repoDir)
160177
_ <- processAlg.exec(Nel.of("git", "commit", "-m", "Modify file2 on master"), repoDir)
161178
} yield ()
179+
180+
def createGitRepoWithConflictFileRemovedOnMaster[F[_]](repoDir: File)(implicit
181+
fileAlg: FileAlg[F],
182+
processAlg: ProcessAlg[F],
183+
F: Monad[F]
184+
): F[Unit] =
185+
for {
186+
_ <- fileAlg.deleteForce(repoDir)
187+
_ <- fileAlg.ensureExists(repoDir)
188+
_ <- processAlg.exec(Nel.of("git", "init", "."), repoDir)
189+
// work on master
190+
_ <- fileAlg.writeFile(repoDir / "file1", "file1, line1")
191+
_ <- fileAlg.writeFile(repoDir / "file2", "file2, line1")
192+
_ <- processAlg.exec(Nel.of("git", "add", "file1"), repoDir)
193+
_ <- processAlg.exec(Nel.of("git", "add", "file2"), repoDir)
194+
_ <- processAlg.exec(Nel.of("git", "commit", "-m", "Initial commit"), repoDir)
195+
// work on conflicts-yes
196+
_ <- processAlg.exec(Nel.of("git", "checkout", "-b", "conflicts-yes"), repoDir)
197+
_ <- fileAlg.writeFile(repoDir / "file2", "file2, line1\nfile2, line2 on conflicts-yes")
198+
_ <- processAlg.exec(Nel.of("git", "add", "file2"), repoDir)
199+
_ <- processAlg.exec(Nel.of("git", "commit", "-m", "Modify file2 on conflicts-yes"), repoDir)
200+
_ <- processAlg.exec(Nel.of("git", "checkout", "master"), repoDir)
201+
// work on master
202+
_ <- processAlg.exec(Nel.of("git", "rm", "file2"), repoDir)
203+
_ <- processAlg.exec(Nel.of("git", "add", "-A"), repoDir)
204+
_ <- processAlg.exec(Nel.of("git", "commit", "-m", "Remove file2 on master"), repoDir)
205+
} yield ()
162206
}

0 commit comments

Comments
 (0)