@@ -84,7 +84,7 @@ final class NurtureAlg[F[_]](config: Config)(implicit
84
84
update => {
85
85
val updateData =
86
86
UpdateData (data, fork, update, baseBranch, baseSha1, git.branchFor(update))
87
- processUpdate(updateData).flatMap {
87
+ processUpdate(updateData, seenBranches ).flatMap {
88
88
case result @ Created (newPrNumber) =>
89
89
(for {
90
90
_ <- closeObsoletePullRequests(updateData, newPrNumber)
@@ -99,7 +99,7 @@ final class NurtureAlg[F[_]](config: Config)(implicit
99
99
)
100
100
} yield ()
101
101
102
- def processUpdate (data : UpdateData ): F [ProcessResult ] =
102
+ def processUpdate (data : UpdateData , seenBranches : Ref [ F , List [ Branch ]] ): F [ProcessResult ] =
103
103
for {
104
104
_ <- logger.info(s " Process update ${data.update.show}" )
105
105
head = vcs.listingBranch(config.vcsType, data.fork, data.update)
@@ -109,9 +109,9 @@ final class NurtureAlg[F[_]](config: Config)(implicit
109
109
logger.info(s " PR ${pr.html_url} is closed " ) >>
110
110
removeRemoteBranch(data.repo, data.updateBranch).as(Ignored )
111
111
case Some (pr) =>
112
- logger.info(s " Found PR ${pr.html_url}" ) >> updatePullRequest(data)
112
+ logger.info(s " Found PR ${pr.html_url}" ) >> updatePullRequest(data, seenBranches )
113
113
case None =>
114
- applyNewUpdate(data)
114
+ applyNewUpdate(data, seenBranches )
115
115
}
116
116
_ <- pullRequests.headOption.traverse_ { pr =>
117
117
pullRequestRepository.createOrUpdate(
@@ -155,13 +155,30 @@ final class NurtureAlg[F[_]](config: Config)(implicit
155
155
gitAlg.removeBranch(repo, branch)
156
156
}
157
157
158
- def applyNewUpdate (data : UpdateData ): F [ProcessResult ] =
158
+ def ensureDistinctBranch (
159
+ data : UpdateData ,
160
+ seenBranches : Ref [F , List [Branch ]],
161
+ whenDistinct : F [ProcessResult ]
162
+ ): F [ProcessResult ] =
163
+ seenBranches.get
164
+ .flatMap(_.forallM(gitAlg.diff(data.repo, _).map(_.nonEmpty)))
165
+ .ifM(
166
+ whenDistinct,
167
+ logger.warn(" Discovered a duplicate branch, not pushing" ).as(Ignored )
168
+ )
169
+
170
+ def applyNewUpdate (data : UpdateData , seenBranches : Ref [F , List [Branch ]]): F [ProcessResult ] =
159
171
gitAlg.returnToCurrentBranch(data.repo) {
160
172
val createBranch = logger.info(s " Create branch ${data.updateBranch.name}" ) >>
161
173
gitAlg.createBranch(data.repo, data.updateBranch)
162
174
editAlg.applyUpdate(data.repoData, data.update, createBranch).flatMap { editCommits =>
163
175
if (editCommits.isEmpty) logger.warn(" No commits created" ).as(Ignored )
164
- else pushCommits(data, editCommits) >> createPullRequest(data)
176
+ else
177
+ ensureDistinctBranch(
178
+ data,
179
+ seenBranches,
180
+ pushCommits(data, editCommits) >> createPullRequest(data)
181
+ )
165
182
}
166
183
}
167
184
@@ -210,13 +227,14 @@ final class NurtureAlg[F[_]](config: Config)(implicit
210
227
_ <- logger.info(s " Created PR ${pr.html_url}" )
211
228
} yield Created (pr.number)
212
229
213
- def updatePullRequest (data : UpdateData ): F [ProcessResult ] =
230
+ def updatePullRequest (data : UpdateData , seenBranches : Ref [ F , List [ Branch ]] ): F [ProcessResult ] =
214
231
if (data.repoConfig.updatePullRequestsOrDefault =!= PullRequestUpdateStrategy .Never )
215
232
gitAlg.returnToCurrentBranch(data.repo) {
216
233
for {
217
234
_ <- gitAlg.checkoutBranch(data.repo, data.updateBranch)
218
235
update <- shouldBeUpdated(data)
219
- result <- if (update) mergeAndApplyAgain(data) else F .pure[ProcessResult ](Ignored )
236
+ result <-
237
+ if (update) mergeAndApplyAgain(data, seenBranches) else F .pure[ProcessResult ](Ignored )
220
238
} yield result
221
239
}
222
240
else
@@ -242,14 +260,18 @@ final class NurtureAlg[F[_]](config: Config)(implicit
242
260
result.flatMap { case (update, msg) => logger.info(msg).as(update) }
243
261
}
244
262
245
- def mergeAndApplyAgain (data : UpdateData ): F [ProcessResult ] =
263
+ def mergeAndApplyAgain (data : UpdateData , seenBranches : Ref [ F , List [ Branch ]] ): F [ProcessResult ] =
246
264
for {
247
265
_ <- logger.info(
248
266
s " Merge branch ${data.baseBranch.name} into ${data.updateBranch.name} and apply again "
249
267
)
250
268
maybeMergeCommit <- gitAlg.mergeTheirs(data.repo, data.baseBranch)
251
269
editCommits <- editAlg.applyUpdate(data.repoData, data.update)
252
- result <- pushCommits(data, maybeMergeCommit.toList ++ editCommits)
270
+ result <- ensureDistinctBranch(
271
+ data,
272
+ seenBranches,
273
+ pushCommits(data, maybeMergeCommit.toList ++ editCommits)
274
+ )
253
275
} yield result
254
276
}
255
277
0 commit comments