@@ -167,8 +167,7 @@ public static bool MergeDownstream( BuildContext context, DownstreamMergeSetting
167167
168168 if ( ! downstreamProductFamily . TryGetDependencyDefinition ( product . ProductName , out var downstreamDependencyDefinition ) )
169169 {
170- context . Console . WriteError (
171- $ "The '{ product . ProductName } ' downstream product version '{ downstreamProductFamily . Version } ' is not configured." ) ;
170+ context . Console . WriteError ( $ "The '{ product . ProductName } ' downstream product version '{ downstreamProductFamily . Version } ' is not configured." ) ;
172171
173172 return false ;
174173 }
@@ -190,180 +189,195 @@ public static bool MergeDownstream( BuildContext context, DownstreamMergeSetting
190189 return false ;
191190 }
192191
193- context . Console . WriteImportantMessage ( $ "Pulling changes from '{ downstreamBranch } ' downstream branch" ) ;
194-
195- if ( ! GitHelper . TryCheckoutAndPull ( context , downstreamBranch ) )
192+ try
196193 {
197- return false ;
198- }
194+ context . Console . WriteImportantMessage ( $ "Pulling changes from '{ downstreamBranch } ' downstream branch" ) ;
199195
200- if ( ! GitHelper . TryGetCommitsCount ( context , "HEAD" , sourceBranch , sourceProductFamily , out var commitsCount ) )
201- {
202- return false ;
203- }
196+ if ( ! GitHelper . TryCheckoutAndPull ( context , downstreamBranch ) )
197+ {
198+ return false ;
199+ }
204200
205- if ( commitsCount < 0 )
206- {
207- throw new InvalidOperationException ( $ "Invalid commits count: { commitsCount } " ) ;
208- }
201+ if ( ! GitHelper . TryGetCommitsCount ( context , "HEAD" , sourceBranch , sourceProductFamily , out var commitsCount ) )
202+ {
203+ return false ;
204+ }
209205
210- if ( commitsCount == 0 )
211- {
212- context . Console . WriteSuccess ( $ "There are no commits to merge from '{ sourceBranch } ' branch to '{ downstreamBranch } ' branch." ) ;
206+ if ( commitsCount < 0 )
207+ {
208+ throw new InvalidOperationException ( $ "Invalid commits count: { commitsCount } " ) ;
209+ }
213210
214- return true ;
215- }
211+ if ( commitsCount == 0 )
212+ {
213+ context . Console . WriteSuccess ( $ "There are no commits to merge from '{ sourceBranch } ' branch to '{ downstreamBranch } ' branch." ) ;
216214
217- context . Console . WriteImportantMessage ( $ "There are { commitsCount } commits to merge from '{ sourceBranch } ' branch to '{ downstreamBranch } ' branch." ) ;
215+ return true ;
216+ }
218217
219- var pullRequestStatusCheckBuildTypeId = downstreamDependencyDefinition . CiConfiguration . PullRequestStatusCheckBuildType ;
220- var isPullRequestRequired = pullRequestStatusCheckBuildTypeId != null ;
221- string targetBranch ;
222- bool targetBranchExistsRemotely ;
218+ context . Console . WriteImportantMessage ( $ "There are { commitsCount } commits to merge from '{ sourceBranch } ' branch to '{ downstreamBranch } ' branch." ) ;
223219
224- if ( isPullRequestRequired )
225- {
226- targetBranch = $ "merge/{ downstreamProductFamily . Version } /{ product . ProductFamily . Version } -{ sourceCommitHash } ";
220+ var pullRequestStatusCheckBuildTypeId = downstreamDependencyDefinition . CiConfiguration . PullRequestStatusCheckBuildType ;
221+ var isPullRequestRequired = pullRequestStatusCheckBuildTypeId != null ;
222+ string targetBranch ;
223+ bool targetBranchExistsRemotely ;
227224
228- context . Console . WriteMessage (
229- $ "Checking '{ product . ProductName } ' product version '{ downstreamProductFamily . Version } ' for pending merge branches." ) ;
225+ if ( isPullRequestRequired )
226+ {
227+ targetBranch = $ "merge/{ downstreamProductFamily . Version } /{ product . ProductFamily . Version } -{ sourceCommitHash } ";
230228
231- var filter = $ "merge/{ downstreamProductFamily . Version } /*";
229+ context . Console . WriteMessage (
230+ $ "Checking '{ product . ProductName } ' product version '{ downstreamProductFamily . Version } ' for pending merge branches." ) ;
232231
233- if ( ! GitHelper . TryGetRemoteReferences ( context , settings , filter , out var references ) )
234- {
235- return false ;
236- }
232+ var filter = $ "merge/{ downstreamProductFamily . Version } /*";
237233
238- var targetBranchReference = $ "refs/heads/{ targetBranch } ";
234+ if ( ! GitHelper . TryGetRemoteReferences ( context , settings , filter , out var references ) )
235+ {
236+ return false ;
237+ }
238+
239+ var targetBranchReference = $ "refs/heads/{ targetBranch } ";
239240
240- targetBranchExistsRemotely = references . Any ( r => r . Reference == targetBranchReference ) ;
241+ targetBranchExistsRemotely = references . Any ( r => r . Reference == targetBranchReference ) ;
241242
242- var formerTargetBranchReferences = references . Where ( r => r . Reference != targetBranchReference ) . ToArray ( ) ;
243+ var formerTargetBranchReferences = references . Where ( r => r . Reference != targetBranchReference ) . ToArray ( ) ;
243244
244- var reusableBranches = formerTargetBranchReferences . Where ( r => r . Reference . StartsWith (
245- $ "refs/heads/merge/{ downstreamProductFamily . Version } /{ product . ProductFamily . Version } -",
246- StringComparison . OrdinalIgnoreCase ) )
247- . ToArray ( ) ;
245+ var reusableBranches = formerTargetBranchReferences . Where ( r => r . Reference . StartsWith (
246+ $ "refs/heads/merge/{ downstreamProductFamily . Version } /{ product . ProductFamily . Version } -",
247+ StringComparison . OrdinalIgnoreCase ) )
248+ . ToArray ( ) ;
248249
249- if ( reusableBranches . Length == 1 )
250+ if ( reusableBranches . Length == 1 )
251+ {
252+ targetBranch = reusableBranches [ 0 ] . Reference . Substring ( "refs/heads/" . Length ) ;
253+ targetBranchExistsRemotely = true ;
254+ }
255+ else if ( formerTargetBranchReferences . Length > 0 && ! settings . Force )
256+ {
257+ ExplainUnmergedBranches (
258+ context . Console ,
259+ formerTargetBranchReferences . Select ( r => r . Reference ) ,
260+ settings . Force ,
261+ targetBranchExistsRemotely
262+ ? $ "Until a new commit is pushed to the '{ sourceBranch } ' source branch, there's no need to delete the '{ targetBranch } ' target branch, as it will be reused next time the downstream merge is run."
263+ : null ) ;
264+
265+ if ( ! settings . Force )
266+ {
267+ return false ;
268+ }
269+ }
270+ }
271+ else
250272 {
251- targetBranch = reusableBranches [ 0 ] . Reference . Substring ( "refs/heads/" . Length ) ;
273+ targetBranch = downstreamBranch ;
252274 targetBranchExistsRemotely = true ;
253275 }
254- else if ( formerTargetBranchReferences . Length > 0 && ! settings . Force )
255- {
256- ExplainUnmergedBranches (
257- context . Console ,
258- formerTargetBranchReferences . Select ( r => r . Reference ) ,
259- settings . Force ,
260- targetBranchExistsRemotely
261- ? $ "Until a new commit is pushed to the '{ sourceBranch } ' source branch, there's no need to delete the '{ targetBranch } ' target branch, as it will be reused next time the downstream merge is run."
262- : null ) ;
263276
264- if ( ! settings . Force )
277+ bool targetBranchExists ;
278+
279+ if ( targetBranchExistsRemotely )
280+ {
281+ targetBranchExists = true ;
282+ }
283+ else
284+ {
285+ if ( ! GitHelper . TryGetCurrentCommitHash ( context , targetBranch , out var targetBranchCurrentCommitHash ) )
265286 {
266287 return false ;
267288 }
268- }
269- }
270- else
271- {
272- targetBranch = downstreamBranch ;
273- targetBranchExistsRemotely = true ;
274- }
275289
276- bool targetBranchExists ;
290+ targetBranchExists = targetBranchCurrentCommitHash != null ;
291+ }
277292
278- if ( targetBranchExistsRemotely )
279- {
280- targetBranchExists = true ;
281- }
282- else
283- {
284- if ( ! GitHelper . TryGetCurrentCommitHash ( context , targetBranch , out var targetBranchCurrentCommitHash ) )
293+ if ( targetBranchExists )
285294 {
286- return false ;
295+ context . Console . WriteImportantMessage ( $ "The '{ targetBranch } ' target branch already exists. Let's use it." ) ;
296+
297+ if ( ! GitHelper . TryCheckoutAndPull ( context , targetBranch ) )
298+ {
299+ return false ;
300+ }
287301 }
302+ else
303+ {
304+ context . Console . WriteImportantMessage ( $ "The '{ targetBranch } ' target branch doesn't exits. Let's create it." ) ;
288305
289- targetBranchExists = targetBranchCurrentCommitHash != null ;
290- }
306+ if ( ! GitHelper . TryCreateBranch ( context , targetBranch ) )
307+ {
308+ return false ;
309+ }
291310
292- if ( targetBranchExists )
293- {
294- context . Console . WriteImportantMessage ( $ "The '{ targetBranch } ' target branch already exists. Let's use it." ) ;
311+ context . Console . WriteImportantMessage ( $ "The '{ targetBranch } ' target was created." ) ;
312+ }
295313
296- if ( ! GitHelper . TryCheckoutAndPull ( context , targetBranch ) )
314+ // Push the branch now to avoid issues when the DownstreamMergeCommand
315+ // is executed again with the same upstream changes
316+ // or when developers are required to resolve conflicts.
317+ if ( ! GitHelper . TryPush ( context ) )
297318 {
298319 return false ;
299320 }
300- }
301- else
302- {
303- context . Console . WriteImportantMessage ( $ "The '{ targetBranch } ' target branch doesn't exits. Let's create it." ) ;
304321
305- if ( ! GitHelper . TryCreateBranch ( context , targetBranch ) )
322+ if ( ! TryMerge ( context , sourceBranch , targetBranch , downstreamBranch , out var areChangesPending ) )
306323 {
307324 return false ;
308325 }
309326
310- context . Console . WriteImportantMessage ( $ "The '{ targetBranch } ' target was created." ) ;
311- }
312-
313- // Push the branch now to avoid issues when the DownstreamMergeCommand
314- // is executed again with the same upstream changes
315- // or when developers are required to resolve conflicts.
316- if ( ! GitHelper . TryPush ( context ) )
317- {
318- return false ;
319- }
320-
321- if ( ! TryMerge ( context , sourceBranch , targetBranch , downstreamBranch , out var areChangesPending ) )
322- {
323- return false ;
324- }
325-
326- if ( ! areChangesPending )
327- {
328- // This shouldn't happen often - just when the merge conflict is solved without using the merge branch prepared by the tool.
329- context . Console . WriteSuccess ( $ "There is nothing to merge from '{ sourceBranch } ' branch to '{ downstreamBranch } ' branch." ) ;
327+ if ( ! areChangesPending )
328+ {
329+ // This shouldn't happen often - just when the merge conflict is solved without using the merge branch prepared by the tool.
330+ context . Console . WriteSuccess ( $ "There is nothing to merge from '{ sourceBranch } ' branch to '{ downstreamBranch } ' branch." ) ;
330331
331- return true ;
332- }
332+ return true ;
333+ }
333334
334- context . Console . WriteSuccess ( $ "Changes from '{ sourceBranch } ' missing in '{ downstreamBranch } ' branch have been merged in branch '{ targetBranch } '." ) ;
335+ context . Console . WriteSuccess (
336+ $ "Changes from '{ sourceBranch } ' missing in '{ downstreamBranch } ' branch have been merged in branch '{ targetBranch } '." ) ;
335337
336- if ( isPullRequestRequired )
337- {
338- if ( ! TryCreatePullRequest ( context , targetBranch , downstreamBranch , sourceBranch , out var pullRequestUrl , out var requiresBuild ) )
338+ if ( isPullRequestRequired )
339339 {
340- return false ;
341- }
342-
343- if ( requiresBuild )
344- {
345- if ( ! TryScheduleBuild (
346- downstreamDependencyDefinition . CiConfiguration ,
347- context . Console ,
348- targetBranch ,
349- sourceBranch ,
350- pullRequestUrl ,
351- pullRequestStatusCheckBuildTypeId ! , // Checked by isPullRequestRequired
352- out var buildUrl ) )
340+ if ( ! TryCreatePullRequest ( context , targetBranch , downstreamBranch , sourceBranch , out var pullRequestUrl , out var requiresBuild ) )
353341 {
354342 return false ;
355343 }
356344
357- context . Console . WriteSuccess ( $ "Created pull request { pullRequestUrl } and scheduled build { buildUrl } ." ) ;
345+ if ( requiresBuild )
346+ {
347+ if ( ! TryScheduleBuild (
348+ downstreamDependencyDefinition . CiConfiguration ,
349+ context . Console ,
350+ targetBranch ,
351+ sourceBranch ,
352+ pullRequestUrl ,
353+ pullRequestStatusCheckBuildTypeId ! , // Checked by isPullRequestRequired
354+ out var buildUrl ) )
355+ {
356+ return false ;
357+ }
358+
359+ context . Console . WriteSuccess ( $ "Created pull request { pullRequestUrl } and scheduled build { buildUrl } ." ) ;
360+ }
361+ else
362+ {
363+ context . Console . WriteSuccess ( $ "Created and merged pull request { pullRequestUrl } ." ) ;
364+ }
358365 }
359- else
360- {
361- context . Console . WriteSuccess ( $ "Created and merged pull request { pullRequestUrl } ." ) ;
362366
367+ return true ;
368+ }
369+ finally
370+ {
371+ try
372+ {
373+ // Go back to the original branch.
374+ GitHelper . TryCheckoutAndPull ( context , product . DependencyDefinition . Branch ) ;
375+ }
376+ catch ( Exception e )
377+ {
378+ context . Console . WriteError ( e . ToString ( ) ) ;
363379 }
364380 }
365-
366- return true ;
367381 }
368382
369383 private static bool TryMerge (
0 commit comments