@@ -78,124 +78,167 @@ public class VersionContext : BuildContextBase
7878 var gitVersionSettings = new GitVersionSettings
7979 {
8080 UpdateAssemblyInfo = false ,
81- Verbosity = GitVersionVerbosity . Verbose
81+ Verbosity = GitVersionVerbosity . Verbose ,
82+ NoFetch = true
8283 } ;
8384
84- var gitDirectory = ".git" ;
85- if ( ! CakeContext . DirectoryExists ( gitDirectory ) )
85+ var mutexName = $ "Global\\ Cake_GitVersion_Clone_{ generalContext . Solution . Name } ";
86+
87+ CakeContext . Information ( "Trying to acquire mutex to determine version" ) ;
88+
89+ using ( var mutex = new System . Threading . Mutex ( false , mutexName , out var createdNew ) )
8690 {
87- CakeContext . Information ( "No local .git directory found, treating as dynamic repository" ) ;
91+ if ( ! mutex . WaitOne ( TimeSpan . FromMinutes ( 2 ) ) )
92+ {
93+ throw new Exception ( "Could not acquire mutex to determine version" ) ;
94+ }
8895
89- // Make a *BIG* assumption that the solution name == repository name
90- var repositoryName = generalContext . Solution . Name ;
91- var dynamicRepositoryPath = System . IO . Path . Combine ( System . IO . Path . GetTempPath ( ) , repositoryName ) ;
96+ CakeContext . Information ( "Mutex acquired" ) ;
9297
93- // Note: for now (until we fix the dynamic cloning in the code below), clear cache must be true
94- var clearCache = ClearCache || true ;
95- if ( clearCache )
98+ var gitDirectory = ".git" ;
99+ if ( ! CakeContext . DirectoryExists ( gitDirectory ) )
96100 {
97- CakeContext . Warning ( "Cleaning the cloned temp directory, disable by setting 'GitVersion_ClearCache' to 'false'" ) ;
98-
99- if ( CakeContext . DirectoryExists ( dynamicRepositoryPath ) )
101+ CakeContext . Information ( "No local .git directory found, treating as dynamic repository" ) ;
102+
103+ // Make a *BIG* assumption that the solution name == repository name
104+ var repositoryName = generalContext . Solution . Name ;
105+ var dynamicRepositoryPath = System . IO . Path . Combine ( System . IO . Path . GetTempPath ( ) , repositoryName ) ;
106+
107+ // Note: for now we fully clear the cache each time until we found a solid way to pull the latest changes
108+ var clearCache = ClearCache || true ;
109+ if ( clearCache )
100110 {
101- CakeContext . DeleteDirectory ( dynamicRepositoryPath , new DeleteDirectorySettings
111+ CakeContext . Warning ( "Cleaning the cloned temp directory, disable by setting 'GitVersion_ClearCache' to 'false'" ) ;
112+
113+ if ( CakeContext . DirectoryExists ( dynamicRepositoryPath ) )
102114 {
103- Force = true ,
104- Recursive = true
105- } ) ;
115+ CakeContext . DeleteDirectory ( dynamicRepositoryPath , new DeleteDirectorySettings
116+ {
117+ Force = true ,
118+ Recursive = true
119+ } ) ;
120+ }
106121 }
107- }
108122
109- // Validate first
110- if ( string . IsNullOrWhiteSpace ( generalContext . Repository . BranchName ) )
111- {
112- throw new Exception ( "No local .git directory was found, but repository branch was not specified either. Make sure to specify the branch" ) ;
113- }
123+ // Validate first
124+ if ( string . IsNullOrWhiteSpace ( generalContext . Repository . BranchName ) )
125+ {
126+ throw new Exception ( "No local .git directory was found, but repository branch was not specified either. Make sure to specify the branch" ) ;
127+ }
114128
115- if ( string . IsNullOrWhiteSpace ( generalContext . Repository . Url ) )
116- {
117- throw new Exception ( "No local .git directory was found, but repository url was not specified either. Make sure to specify the branch" ) ;
118- }
129+ if ( string . IsNullOrWhiteSpace ( generalContext . Repository . Url ) )
130+ {
131+ throw new Exception ( "No local .git directory was found, but repository url was not specified either. Make sure to specify the branch" ) ;
132+ }
119133
120- CakeContext . Information ( $ "Fetching dynamic repository from url '{ generalContext . Repository . Url } ' => '{ dynamicRepositoryPath } '") ;
134+ CakeContext . Information ( $ "Fetching dynamic repository from url '{ generalContext . Repository . Url } ' => '{ dynamicRepositoryPath } '") ;
121135
122- // Note: starting with GitVersion 6.x, we need to handle dynamic repos ourselves,
123- // and we will be using LibGit2Sharp directly to support cloning a specific commit id
136+ // Note: starting with GitVersion 6.x, we need to handle dynamic repos ourselves,
137+ // and we will be using Cake.Git and LibGit2Sharp directly to support cloning a specific commit id
124138
125- // var gitCloneSettings = new GitCloneSettings
126- // {
127- // //BranchName = generalContext.Repository.BranchName,
128- // BranchName = generalContext.Repository.CommitId,
129- // Checkout = true,
130- // IsBare = false,
131- // RecurseSubmodules = false,
132- // };
139+ var existingRepository = false ;
140+ if ( CakeContext . DirectoryExists ( dynamicRepositoryPath ) )
141+ {
142+ CakeContext . Information ( "Dynamic repository directory already exists" ) ;
133143
134- var cloneOptions = new LibGit2Sharp . CloneOptions
135- {
136- IsBare = false ,
137- Checkout = true ,
138- BranchName = generalContext . Repository . BranchName ,
139- RecurseSubmodules = false
140- } ;
141-
142- if ( ! string . IsNullOrWhiteSpace ( generalContext . Repository . Username ) &&
143- ! string . IsNullOrWhiteSpace ( generalContext . Repository . Password ) )
144- {
145- CakeContext . Information ( "Cloning with authentication" ) ;
144+ if ( CakeContext . GitIsValidRepository ( dynamicRepositoryPath ) )
145+ {
146+ CakeContext . Information ( "Dynamic repository already exists, reusing existing clone" ) ;
147+ existingRepository = true ;
148+ }
149+ else
150+ {
151+ CakeContext . Information ( "Dynamic repository already exists but is not valid, recloning" ) ;
152+
153+ CakeContext . DeleteDirectory ( dynamicRepositoryPath , new DeleteDirectorySettings
154+ {
155+ Force = true ,
156+ Recursive = true
157+ } ) ;
158+ }
159+ }
146160
147- cloneOptions . FetchOptions . CredentialsProvider =
148- ( url , user , cred ) => new LibGit2Sharp . UsernamePasswordCredentials
149- {
150- Username = generalContext . Repository . Username ,
151- Password = generalContext . Repository . Password
161+ if ( existingRepository )
162+ {
163+ // TODO: How to pull?
164+ }
165+ else
166+ {
167+ var gitCloneSettings = new GitCloneSettings
168+ {
169+ BranchName = generalContext . Repository . BranchName ,
170+ Checkout = true ,
171+ IsBare = false ,
172+ RecurseSubmodules = false ,
152173 } ;
153- }
154- else
155- {
156- CakeContext . Information ( "Cloning without authentication" ) ;
157- }
158-
159- LibGit2Sharp . Repository . Clone ( generalContext . Repository . Url , dynamicRepositoryPath , cloneOptions ) ;
160174
161- if ( ! CakeContext . GitIsValidRepository ( dynamicRepositoryPath ) )
162- {
163- throw new Exception ( $ "Cloned repository at '{ dynamicRepositoryPath } ' is not a valid repository") ;
164- }
175+ if ( ! string . IsNullOrWhiteSpace ( generalContext . Repository . Username ) &&
176+ ! string . IsNullOrWhiteSpace ( generalContext . Repository . Password ) )
177+ {
178+ CakeContext . Information ( "Cloning with authentication" ) ;
179+
180+ CakeContext . GitClone ( generalContext . Repository . Url ,
181+ dynamicRepositoryPath ,
182+ generalContext . Repository . Username ,
183+ generalContext . Repository . Password ,
184+ gitCloneSettings ) ;
185+ }
186+ else
187+ {
188+ CakeContext . Information ( "Cloning without authentication" ) ;
165189
166- CakeContext . Information ( "Switching to correct commit ID" ) ;
167-
168- // According to docs, to not get into a detached head state, we need to:
169- //
170- // git checkout -B 'branch' 'commit id'
171- //
172- // This seems impossible via Cake.Git (and LibGit2Sharp directly), so we will
173- // just invoke git.exe directly here
174- //
175- //CakeContext.GitCheckout(dynamicRepositoryPath, generalContext.Repository.CommitId);
176-
177- var gitExe = CakeContext . Tools . Resolve ( "git.exe" ) . FullPath ;
178-
179- using ( var process = CakeContext . StartAndReturnProcess ( gitExe ,
180- new ProcessSettings
181- {
182- WorkingDirectory = dynamicRepositoryPath ,
183- Arguments = $ "checkout -B { generalContext . Repository . BranchName } { generalContext . Repository . CommitId } ",
184- } ) )
185- {
186- process . WaitForExit ( ) ;
190+ CakeContext . GitClone ( generalContext . Repository . Url ,
191+ dynamicRepositoryPath ,
192+ gitCloneSettings ) ;
193+ }
194+ }
187195
188- // This should output 0 as valid arguments supplied
189- CakeContext . Information ( "Exit code: {0}" , process . GetExitCode ( ) ) ;
196+ //LibGit2Sharp.Repository.Clone(generalContext.Repository.Url, dynamicRepositoryPath, cloneOptions);
197+
198+ if ( ! CakeContext . GitIsValidRepository ( dynamicRepositoryPath ) )
199+ {
200+ throw new Exception ( $ "Cloned repository at '{ dynamicRepositoryPath } ' is not a valid repository") ;
201+ }
202+
203+ CakeContext . Information ( "Ensuring correct commit ID" ) ;
204+
205+ // According to docs, to not get into a detached head state, we need to:
206+ //
207+ // git checkout -B 'branch' 'commit id'
208+ //
209+ // This seems impossible via Cake.Git (and LibGit2Sharp directly), so we will
210+ // just invoke git.exe directly here
211+ //
212+ //CakeContext.GitCheckout(dynamicRepositoryPath, generalContext.Repository.CommitId);
213+
214+ var gitCommit = CakeContext . GitLogTip ( dynamicRepositoryPath ) ;
215+ if ( ! string . Equals ( gitCommit . Sha , generalContext . Repository . CommitId , StringComparison . OrdinalIgnoreCase ) )
216+ {
217+ var gitExe = CakeContext . Tools . Resolve ( "git.exe" ) . FullPath ;
218+
219+ using ( var process = CakeContext . StartAndReturnProcess ( gitExe ,
220+ new ProcessSettings
221+ {
222+ WorkingDirectory = dynamicRepositoryPath ,
223+ Arguments = $ "checkout -B { generalContext . Repository . BranchName } { generalContext . Repository . CommitId } ",
224+ } ) )
225+ {
226+ process . WaitForExit ( ) ;
227+
228+ // This should output 0 as valid arguments supplied
229+ CakeContext . Information ( "Exit code: {0}" , process . GetExitCode ( ) ) ;
230+ }
231+ }
232+
233+ CakeContext . Information ( "Preparing GitVersion settings" ) ;
234+
235+ gitVersionSettings . WorkingDirectory = dynamicRepositoryPath ;
190236 }
191237
192- CakeContext . Information ( "Preparing GitVersion settings " ) ;
238+ CakeContext . Information ( "Running GitVersion" ) ;
193239
194- gitVersionSettings . RepositoryPath = dynamicRepositoryPath ;
195- gitVersionSettings . Verbosity = GitVersionVerbosity . Verbose ;
240+ _gitVersionContext = CakeContext . GitVersion ( gitVersionSettings ) ;
196241 }
197-
198- _gitVersionContext = CakeContext . GitVersion ( gitVersionSettings ) ;
199242 }
200243
201244 return _gitVersionContext ;
0 commit comments