@ -34,8 +34,6 @@ class Repo(object):
self . _initialized = False
try :
self . _ensure_cloned ( )
# Pick up any tags or branch updates since we last ran:
self . update ( )
except :
self . log . exception ( " Unable to initialize repo for %s " % remote )
@ -60,16 +58,29 @@ class Repo(object):
self . _ensure_cloned ( )
self . repo = git . Repo ( self . local_path )
def reset ( self ) :
self . _ensure_cloned ( )
self . log . debug ( " Resetting repository %s " % self . local_path )
self . update ( )
origin = self . repo . remotes . origin
for ref in origin . refs :
if ref . remote_head == ' HEAD ' :
continue
self . repo . create_head ( ref . remote_head , ref , force = True )
# Reset to remote HEAD (usually origin/master)
self . repo . head . reference = origin . refs [ ' HEAD ' ]
self . repo . head . reset ( index = True , working_tree = True )
self . repo . git . clean ( ' -x ' , ' -f ' , ' -d ' )
def getBranchHead ( self , branch ) :
return self . repo . heads [ branch ]
def checkout ( self , ref ) :
self . _ensure_cloned ( )
self . log . debug ( " Checking out %s " % ref )
self . repo . head . reference = ref
self . repo . head . reset ( index = True , working_tree = True )
self . repo . git . clean ( ' -x ' , ' -f ' , ' -d ' )
if self . repo . re_hexsha_only . match ( ref ) :
self . repo . git . checkout ( ref )
else :
self . fetch ( ref )
self . repo . git . checkout ( " FETCH_HEAD " )
def cherryPick ( self , ref ) :
self . _ensure_cloned ( )
@ -94,15 +105,15 @@ class Repo(object):
# data was fetched properly subsequent fetches don't seem to fail.
# So try again if an AssertionError is caught.
origin = self . repo . remotes . origin
self . log . debug ( " Fetching %s " % ref )
try :
origin . fetch ( ref )
except AssertionError :
origin . fetch ( ref )
# If the repository is packed, and we fetch a change that is
# also entirely packed, the cache may be out of date.
# See the comment in update() and
# also entirely packed, the cache may be out of date for the
# same reason as reset() above. Avoid these problems by
# recreating the repo object.
# https://bugs.launchpad.net/zuul/+bug/1078946
self . repo = git . Repo ( self . local_path )
@ -171,18 +182,13 @@ class Merger(object):
r . recreateRepoObject ( )
return r
def updateRepo ( self , project , ref = None ) :
def updateRepo ( self , project ) :
repo = self . getRepo ( project )
try :
if ref :
self . log . debug ( " Fetching ref %s for local repository %s " %
( ref , project ) )
repo . fetch ( ref )
else :
self . log . info ( " Updating local repository %s " % project )
repo . update ( )
self . log . info ( " Updating local repository %s " , project )
repo . update ( )
except :
self . log . exception ( " Unable to update %s " % project )
self . log . exception ( " Unable to update %s " , project )
def _mergeChange ( self , change , ref , target_ref ) :
repo = self . getRepo ( change . project )
@ -237,8 +243,14 @@ class Merger(object):
# Only current change to merge against tip of change.branch
if len ( sibling_items ) == 1 :
repo = self . getRepo ( item . change . project )
# we need to reset here in order to call getBranchHead
try :
repo . reset ( )
except :
self . log . exception ( " Unable to reset repo %s " % repo )
return False
commit = self . _mergeChange ( item . change ,
item . change . branch ,
repo . getBranchHead ( item . change . branch ) ,
target_ref = target_ref )
# Sibling changes exist. Merge current change against newest sibling.
elif ( len ( sibling_items ) > = 2 and