@@ -49,6 +49,10 @@ type WorkingDir interface {
49
49
// Delete deletes the workspace for this repo and pull.
50
50
Delete (r models.Repo , p models.PullRequest ) error
51
51
DeleteForWorkspace (r models.Repo , p models.PullRequest , workspace string ) error
52
+ // Set a flag in the workingdir so Clone() can know that it is safe to re-clone the workingdir if
53
+ // the upstream branch has been modified. This is only safe after grabbing the project lock
54
+ // and before running any plans
55
+ SetSafeToReClone ()
52
56
}
53
57
54
58
// FileWorkspace implements WorkingDir with the file system.
@@ -75,6 +79,8 @@ type FileWorkspace struct {
75
79
GithubAppEnabled bool
76
80
// use the global setting without overriding
77
81
GpgNoSigningEnabled bool
82
+ // flag indicating if a re-clone will be safe (project lock held, about to run plan)
83
+ SafeToReClone bool
78
84
}
79
85
80
86
// Clone git clones headRepo, checks out the branch and then returns the absolute
@@ -94,6 +100,7 @@ func (w *FileWorkspace) Clone(
94
100
additionalBranches []string ) (string , bool , error ) {
95
101
cloneDir := w .cloneDir (p .BaseRepo , p , workspace )
96
102
hasDiverged := false
103
+ defer func () { w .SafeToReClone = false }()
97
104
98
105
if ! w .alreadyClonedHEAD (log , cloneDir , p ) {
99
106
if err := w .forceClone (log , cloneDir , headRepo , p ); err != nil {
@@ -111,7 +118,7 @@ func (w *FileWorkspace) Clone(
111
118
// We're prefix matching here because BitBucket doesn't give us the full
112
119
// commit, only a 12 character prefix.
113
120
if strings .HasPrefix (currCommit , p .HeadCommit ) {
114
- if w .CheckoutMerge && w .recheckDiverged (log , p , headRepo , cloneDir ) {
121
+ if w .SafeToReClone && w . CheckoutMerge && w .recheckDiverged (log , p , headRepo , cloneDir ) {
115
122
log .Info ("base branch has been updated, using merge strategy and will clone again" )
116
123
hasDiverged = true
117
124
} else {
@@ -254,17 +261,17 @@ func (w *FileWorkspace) forceClone(log logging.SimpleLogging,
254
261
if ! w .CheckoutMerge {
255
262
return runGit ("clone" , "--depth=1" , "--branch" , p .HeadBranch , "--single-branch" , headCloneURL , cloneDir )
256
263
}
257
-
264
+
258
265
// if merge strategy...
259
266
260
267
// if no checkout depth, omit depth arg
261
268
if w .CheckoutDepth == 0 {
262
269
if err := runGit ("clone" , "--branch" , p .BaseBranch , "--single-branch" , baseCloneURL , cloneDir ); err != nil {
263
- return err
270
+ return err
264
271
}
265
272
} else {
266
- if err := runGit ("clone" , "--depth" , fmt .Sprint (w .CheckoutDepth ), "--branch" , p .BaseBranch , "--single-branch" , baseCloneURL , cloneDir ); err != nil {
267
- return err
273
+ if err := runGit ("clone" , "--depth" , fmt .Sprint (w .CheckoutDepth ), "--branch" , p .BaseBranch , "--single-branch" , baseCloneURL , cloneDir ); err != nil {
274
+ return err
268
275
}
269
276
}
270
277
@@ -279,16 +286,16 @@ func (w *FileWorkspace) forceClone(log logging.SimpleLogging,
279
286
fetchRemote = "origin"
280
287
}
281
288
282
- // if no checkout depth, omit depth arg
283
- if w .CheckoutDepth == 0 {
284
- if err := runGit ("fetch" , fetchRemote , fetchRef ); err != nil {
285
- return err
286
- }
287
- } else {
288
- if err := runGit ("fetch" , "--depth" , fmt .Sprint (w .CheckoutDepth ), fetchRemote , fetchRef ); err != nil {
289
- return err
290
- }
291
- }
289
+ // if no checkout depth, omit depth arg
290
+ if w .CheckoutDepth == 0 {
291
+ if err := runGit ("fetch" , fetchRemote , fetchRef ); err != nil {
292
+ return err
293
+ }
294
+ } else {
295
+ if err := runGit ("fetch" , "--depth" , fmt .Sprint (w .CheckoutDepth ), fetchRemote , fetchRef ); err != nil {
296
+ return err
297
+ }
298
+ }
292
299
293
300
if w .GpgNoSigningEnabled {
294
301
if err := runGit ("config" , "--local" , "commit.gpgsign" , "false" ); err != nil {
@@ -355,3 +362,8 @@ func (w *FileWorkspace) sanitizeGitCredentials(s string, base models.Repo, head
355
362
baseReplaced := strings .Replace (s , base .CloneURL , base .SanitizedCloneURL , - 1 )
356
363
return strings .Replace (baseReplaced , head .CloneURL , head .SanitizedCloneURL , - 1 )
357
364
}
365
+
366
+ // Set the flag that indicates it is safe to re-clone if necessary
367
+ func (w * FileWorkspace ) SetSafeToReClone () {
368
+ w .SafeToReClone = true
369
+ }
0 commit comments