@ -134,11 +134,8 @@ class SCMWrapper(object):
@staticmethod
@staticmethod
def _get_first_remote_url ( checkout_path ) :
def _get_first_remote_url ( checkout_path ) :
log = scm . GIT . Capture (
log = scm . GIT . YieldConfigRegexp ( checkout_path , r ' remote.*.url ' )
[ ' config ' , ' --local ' , ' --get-regexp ' , r ' remote.*.url ' ] ,
return next ( log ) [ 1 ]
cwd = checkout_path )
# Get the second token of the first line of the log.
return log . splitlines ( ) [ 0 ] . split ( ' ' , 1 ) [ 1 ]
def GetCacheMirror ( self ) :
def GetCacheMirror ( self ) :
if getattr ( self , ' cache_dir ' , None ) :
if getattr ( self , ' cache_dir ' , None ) :
@ -592,26 +589,35 @@ class GitWrapper(SCMWrapper):
def wrapper ( * args ) :
def wrapper ( * args ) :
return_val = f ( * args )
return_val = f ( * args )
if os . path . exists ( os . path . join ( args [ 0 ] . checkout_path , ' .git ' ) ) :
if os . path . exists ( os . path . join ( args [ 0 ] . checkout_path , ' .git ' ) ) :
# The config updates to the project are stored in this list
# and updated consecutively after the reads. The updates
# are done this way because `scm.GIT.GetConfig` caches
# the config file and `scm.GIT.SetConfig` evicts the cache.
# This ensures we don't interleave reads and writes causing
# the cache to set and unset consecutively.
config_updates = [ ]
if scm . GIT . GetConfig ( args [ 0 ] . checkout_path ,
' diff.ignoresubmodules ' ) != ' dirty ' :
# If diff.ignoreSubmodules is not already set, set it to `all`.
# If diff.ignoreSubmodules is not already set, set it to `all`.
config = subprocess2 . capture ( [ ' git ' , ' config ' , ' -l ' ] ,
config_updates . append ( ( ' diff.ignoreSubmodules ' , ' dirty ' ) )
cwd = args [ 0 ] . checkout_path ) . decode (
' utf-8 ' ) . strip ( ) . splitlines ( )
if scm . GIT . GetConfig ( args [ 0 ] . checkout_path ,
if ' diff.ignoresubmodules=dirty ' not in config :
' fetch.recursesubmodules ' ) != ' off ' :
subprocess2 . capture (
config_updates . append ( ( ' fetch.recurseSubmodules ' , ' off ' ) )
[ ' git ' , ' config ' , ' diff.ignoreSubmodules ' , ' dirty ' ] ,
cwd = args [ 0 ] . checkout_path )
if scm . GIT . GetConfig ( args [ 0 ] . checkout_path ,
if ' fetch.recursesubmodules=off ' not in config :
' push.recursesubmodules ' ) != ' off ' :
subprocess2 . capture (
[ ' git ' , ' config ' , ' fetch.recurseSubmodules ' , ' off ' ] ,
cwd = args [ 0 ] . checkout_path )
if ' push.recursesubmodules=off ' not in config :
# The default is off, but if user sets submodules.recurse to
# The default is off, but if user sets submodules.recurse to
# on, this becomes on too. We never want to push submodules
# on, this becomes on too. We never want to push submodules
# for gclient managed repositories. Push, even if a no-op,
# for gclient managed repositories. Push, even if a no-op,
# will increase `git cl upload` latency.
# will increase `git cl upload` latency.
subprocess2 . capture (
config_updates . append ( ( ' push.recurseSubmodules ' , ' off ' ) )
[ ' git ' , ' config ' , ' push.recurseSubmodules ' , ' off ' ] ,
cwd = args [ 0 ] . checkout_path )
for update in config_updates :
scm . GIT . SetConfig ( args [ 0 ] . checkout_path , update [ 0 ] ,
update [ 1 ] )
return return_val
return return_val
return wrapper
return wrapper
@ -739,7 +745,8 @@ class GitWrapper(SCMWrapper):
# See if the url has changed (the unittests use git://foo for the url,
# See if the url has changed (the unittests use git://foo for the url,
# let that through).
# let that through).
current_url = self . _Capture ( [ ' config ' , ' remote. %s .url ' % self . remote ] )
current_url = scm . GIT . GetConfig ( self . checkout_path ,
f ' remote. { self . remote } .url ' )
return_early = False
return_early = False
# TODO(maruel): Delete url != 'git://foo' since it's just to make the
# TODO(maruel): Delete url != 'git://foo' since it's just to make the
# unit test pass. (and update the comment above)
# unit test pass. (and update the comment above)
@ -750,12 +757,9 @@ class GitWrapper(SCMWrapper):
strp_current_url = current_url [ : - 4 ] if current_url . endswith (
strp_current_url = current_url [ : - 4 ] if current_url . endswith (
' .git ' ) else current_url
' .git ' ) else current_url
if ( strp_current_url . rstrip ( ' / ' ) != strp_url . rstrip ( ' / ' )
if ( strp_current_url . rstrip ( ' / ' ) != strp_url . rstrip ( ' / ' )
and url != ' git://foo ' and
and url != ' git://foo ' and scm . GIT . GetConfigBool (
subprocess2 . capture ( [
self . checkout_path ,
' git ' , ' config ' ,
f ' remote. { self . remote } .gclient-auto-fix-url ' ) ) :
' remote. %s .gclient-auto-fix-url ' % self . remote
] ,
cwd = self . checkout_path ) . strip ( ) != ' False ' ) :
self . Print ( ' _____ switching %s from %s to new upstream %s ' %
self . Print ( ' _____ switching %s from %s to new upstream %s ' %
( self . relpath , current_url , url ) )
( self . relpath , current_url , url ) )
if not ( options . force or options . reset ) :
if not ( options . force or options . reset ) :
@ -1553,34 +1557,30 @@ class GitWrapper(SCMWrapper):
if requested . """
if requested . """
if options . force or options . reset :
if options . force or options . reset :
try :
try :
self . _Run (
scm . GIT . SetConfig ( self . checkout_path ,
[ ' config ' , ' --unset-all ' ,
f ' remote. { self . remote } .fetch ' ,
' remote. %s .fetch ' % self . remote ] , options )
modify_all = True )
self . _Run ( [
scm . GIT . SetConfig (
' config ' ,
self . checkout_path , f ' remote. { self . remote } .fetch ' ,
' remote. %s .fetch ' % self . remote ,
f ' +refs/heads/*:refs/remotes/ { self . remote } /* ' )
' +refs/heads/*:refs/remotes/ %s /* ' % self . remote
] , options )
except subprocess2 . CalledProcessError as e :
except subprocess2 . CalledProcessError as e :
# If exit code was 5, it means we attempted to unset a config
# If exit code was 5, it means we attempted to unset a config
# that didn't exist. Ignore it.
# that didn't exist. Ignore it.
if e . returncode != 5 :
if e . returncode != 5 :
raise
raise
if hasattr ( options , ' with_branch_heads ' ) and options . with_branch_heads :
if hasattr ( options , ' with_branch_heads ' ) and options . with_branch_heads :
config_cmd = [
scm. GIT . SetConfig (
' config ' ,
self . checkout_path ,
' remote. %s .fetch ' % self . remote ,
f' remote. { self . remote } .fetch ' ,
' +refs/branch-heads/*:refs/remotes/branch-heads/* ' ,
' +refs/branch-heads/*:refs/remotes/branch-heads/* ' ,
' ^ \\ +refs/branch-heads/ \\ *:.*$ '
value_pattern = ' ^ \\ +refs/branch-heads/ \\ *:.*$ ' ,
]
modify_all = True )
self . _Run ( config_cmd , options )
if hasattr ( options , ' with_tags ' ) and options . with_tags :
if hasattr ( options , ' with_tags ' ) and options . with_tags :
config_cmd = [
scm . GIT . SetConfig ( self . checkout_path ,
' config ' ,
f ' remote. { self . remote } .fetch ' ,
' remote. %s .fetch ' % self . remote , ' +refs/tags/*:refs/tags/* ' ,
' +refs/tags/*:refs/tags/* ' ,
' ^ \\ +refs/tags/ \\ *:.*$ '
value_pattern = ' ^ \\ +refs/tags/ \\ *:.*$ ' ,
]
modify_all = True )
self . _Run ( config_cmd , options )
def _AutoFetchRef ( self , options , revision , depth = None ) :
def _AutoFetchRef ( self , options , revision , depth = None ) :
""" Attempts to fetch |revision| if not available in local repo.
""" Attempts to fetch |revision| if not available in local repo.