@@ -275,31 +275,45 @@ def fetch(self):
275
275
It returns a dict structure associating each (remote, ref) to their
276
276
SHA in local repository.
277
277
"""
278
- merges_requested = [(m ["remote" ], m ["ref" ])
279
- for m in self .merges ]
280
278
basecmd = ("git" , "fetch" )
281
279
logger .info ("Fetching required remotes" )
282
280
fetch_heads = {}
283
281
ls_remote_refs = collections .defaultdict (list ) # to ls-query
284
- while merges_requested :
285
- remote , ref = merges_requested [0 ]
286
- merges_requested = merges_requested [1 :]
282
+ for merge in self .merges :
283
+ remote = merge ["remote" ]
284
+ ref = merge ["ref" ]
285
+ pin = merge .get ("pin" )
287
286
cmd = (
288
287
basecmd +
289
288
self ._fetch_options ({"remote" : remote , "ref" : ref }) +
290
289
(remote ,))
291
290
if remote not in self .fetch_all :
292
291
cmd += (ref , )
293
292
else :
293
+ if pin :
294
+ # Probably solvable, but a little too tricky for me to
295
+ # figure out right now
296
+ raise GitAggregatorException (
297
+ "Cannot use fetch_all with pin"
298
+ )
294
299
ls_remote_refs [remote ].append (ref )
295
300
self .log_call (cmd , cwd = self .cwd )
296
- with open (os .path .join (self .cwd , ".git" , "FETCH_HEAD" ), "r" ) as f :
297
- for line in f :
298
- fetch_head , for_merge , _ = line .split ("\t " )
299
- if for_merge == "not-for-merge" :
300
- continue
301
- break
302
- fetch_heads [(remote , ref )] = fetch_head
301
+ if pin :
302
+ try :
303
+ fetch_heads [(remote , ref )] = self .rev_parse (pin )
304
+ except Exception :
305
+ logger .error (
306
+ "Could not find pin %r after fetching %r" , pin , ref
307
+ )
308
+ raise
309
+ else :
310
+ with open (os .path .join (self .cwd , ".git" , "FETCH_HEAD" )) as f :
311
+ for line in f :
312
+ fetch_head , for_merge , _ = line .split ("\t " )
313
+ if for_merge == "not-for-merge" :
314
+ continue
315
+ break
316
+ fetch_heads [(remote , ref )] = fetch_head
303
317
if self .fetch_all :
304
318
if self .fetch_all is True :
305
319
remotes = self .remotes
@@ -311,31 +325,16 @@ def fetch(self):
311
325
remote ["url" ],
312
326
ls_remote_refs [remote ["name" ]])
313
327
for _ , ref , sha in refs :
314
- if (remote ["name" ], ref ) in merges_requested :
315
- merges_requested .remove ((remote ["name" ], ref ))
316
328
fetch_heads [(remote ["name" ], ref )] = sha
317
- if len (merges_requested ):
318
- # Last case: our ref is a sha and remote git repository does
319
- # not support querying commit directly by SHA. In this case
320
- # we need just to check if ref is actually SHA, and if we have
321
- # this SHA locally.
322
- for remote , ref in merges_requested :
323
- if not re .search ("[0-9a-f]{4,}" , ref ):
324
- raise ValueError ("Could not resolv ref %r on remote %r"
325
- % (ref , remote ))
326
- valid_local_shas = self .log_call (
327
- ['git' , 'rev-parse' , '-v' ] + [sha
328
- for _r , sha in merges_requested ],
329
- cwd = self .cwd , callwith = subprocess .check_output
330
- ).strip ().splitlines ()
331
- for remote , sha in merges_requested :
332
- if sha not in valid_local_shas :
333
- raise ValueError (
334
- "Could not find SHA ref %r after fetch on remote %r"
335
- % (ref , remote ))
336
- fetch_heads [(remote ["name" ], sha )] = sha
337
329
return fetch_heads
338
330
331
+ def rev_parse (self , ref ):
332
+ return self .log_call (
333
+ ["git" , "rev-parse" , "--verify" , ref ],
334
+ callwith = subprocess .check_output ,
335
+ cwd = self .cwd ,
336
+ ).strip ()
337
+
339
338
def push (self ):
340
339
remote = self .target ['remote' ]
341
340
branch = self .target ['branch' ]
@@ -384,11 +383,7 @@ def _switch_to_branch(self, branch_name, ref=None):
384
383
logger .info ("Switch to branch %s" , branch_name )
385
384
cmd = ['git' , 'checkout' , '-B' , branch_name ]
386
385
if ref is not None :
387
- sha1 = self .log_call (
388
- ['git' , 'rev-parse' , ref ],
389
- callwith = subprocess .check_output ,
390
- cwd = self .cwd ).strip ()
391
- cmd .append (sha1 )
386
+ cmd .append (self .rev_parse (ref ))
392
387
self .log_call (cmd , cwd = self .cwd )
393
388
394
389
def _execute_shell_command_after (self ):
0 commit comments