@ -369,18 +369,17 @@ def clone(git_path, module, repo, dest, remote, depth, version, bare,
pass
pass
cmd = [ git_path , ' clone ' ]
cmd = [ git_path , ' clone ' ]
branch_or_tag = is_remote_branch ( git_path , module , dest , repo , version ) \
or is_remote_tag ( git_path , module , dest , repo , version )
if bare :
if bare :
cmd . append ( ' --bare ' )
cmd . append ( ' --bare ' )
else :
else :
cmd . extend ( [ ' --origin ' , remote ] )
cmd . extend ( [ ' --origin ' , remote ] )
if branch_or_tag :
if depth :
cmd . extend ( [ ' --branch ' , version ] )
if version == ' HEAD ' \
if depth and ( branch_or_tag or version == ' HEAD ' or refspec ) :
or refspec \
# only use depth if the remote opject is branch or tag (i.e. fetchable)
or is_remote_branch ( git_path , module , dest , repo , version ) \
cmd . extend ( [ ' --depth ' , str ( depth ) ] )
or is_remote_tag ( git_path , module , dest , repo , version ) :
# only use depth if the remote opject is branch or tag (i.e. fetchable)
cmd . extend ( [ ' --depth ' , str ( depth ) ] )
if reference :
if reference :
cmd . extend ( [ ' --reference ' , str ( reference ) ] )
cmd . extend ( [ ' --reference ' , str ( reference ) ] )
cmd . extend ( [ repo , dest ] )
cmd . extend ( [ repo , dest ] )
@ -594,7 +593,7 @@ def set_remote_url(git_path, module, repo, dest, remote):
# for Git versions prior to 1.7.5 that lack required functionality.
# for Git versions prior to 1.7.5 that lack required functionality.
return remote_url is not None
return remote_url is not None
def fetch ( git_path , module , repo , dest , version , remote , depth , bare , refspec ):
def fetch ( git_path , module , repo , dest , version , remote , depth , bare , refspec , git_version_used ):
''' updates repo from remote sources '''
''' updates repo from remote sources '''
set_remote_url ( git_path , module , repo , dest , remote )
set_remote_url ( git_path , module , repo , dest , remote )
commands = [ ]
commands = [ ]
@ -630,20 +629,22 @@ def fetch(git_path, module, repo, dest, version, remote, depth, bare, refspec):
# version
# version
fetch_cmd . extend ( [ ' --depth ' , str ( depth ) ] )
fetch_cmd . extend ( [ ' --depth ' , str ( depth ) ] )
fetch_cmd . extend ( [ remote ] )
if not depth or not refspecs :
if not depth or not refspecs :
# don't try to be minimalistic but do a full clone
# don't try to be minimalistic but do a full clone
# also do this if depth is given, but version is something that can't be fetched directly
# also do this if depth is given, but version is something that can't be fetched directly
if bare :
if bare :
refspecs = [ ' +refs/heads/*:refs/heads/* ' , ' +refs/tags/*:refs/tags/* ' ]
refspecs = [ ' +refs/heads/*:refs/heads/* ' , ' +refs/tags/*:refs/tags/* ' ]
else :
else :
# unlike in bare mode, there's no way to combine the
# ensure all tags are fetched
# additional refspec with the default git fetch behavior,
if git_version_used > = LooseVersion ( ' 1.9 ' ) :
# so use two commands
fetch_cmd . append ( ' --tags ' )
commands . append ( ( fetch_str , fetch_cmd ) )
else :
refspecs = [ ' +refs/tags/*:refs/tags/* ' ]
# old git versions have a bug in --tags that prevents updating existing tags
commands . append ( ( fetch_str , fetch_cmd + [ remote ] ) )
refspecs = [ ' +refs/tags/*:refs/tags/* ' ]
if refspec :
if refspec :
refspecs . append ( refspec )
refspecs . append ( refspec )
fetch_cmd . extend ( [ remote ] )
commands . append ( ( fetch_str , fetch_cmd + refspecs ) )
commands . append ( ( fetch_str , fetch_cmd + refspecs ) )
@ -744,7 +745,15 @@ def set_remote_branch(git_path, module, dest, remote, version, depth):
def switch_version ( git_path , module , dest , remote , version , verify_commit , depth ) :
def switch_version ( git_path , module , dest , remote , version , verify_commit , depth ) :
cmd = ' '
cmd = ' '
if version != ' HEAD ' :
if version == ' HEAD ' :
branch = get_head_branch ( git_path , module , dest , remote )
( rc , out , err ) = module . run_command ( " %s checkout --force %s " % ( git_path , branch ) , cwd = dest )
if rc != 0 :
module . fail_json ( msg = " Failed to checkout branch %s " % branch ,
stdout = out , stderr = err , rc = rc )
cmd = " %s reset --hard %s " % ( git_path , remote )
else :
# FIXME check for local_branch first, should have been fetched already
if is_remote_branch ( git_path , module , dest , remote , version ) :
if is_remote_branch ( git_path , module , dest , remote , version ) :
if not is_local_branch ( git_path , module , dest , version ) :
if not is_local_branch ( git_path , module , dest , version ) :
if depth :
if depth :
@ -760,13 +769,6 @@ def switch_version(git_path, module, dest, remote, version, verify_commit, depth
cmd = " %s reset --hard %s / %s " % ( git_path , remote , version )
cmd = " %s reset --hard %s / %s " % ( git_path , remote , version )
else :
else :
cmd = " %s checkout --force %s " % ( git_path , version )
cmd = " %s checkout --force %s " % ( git_path , version )
else :
branch = get_head_branch ( git_path , module , dest , remote )
( rc , out , err ) = module . run_command ( " %s checkout --force %s " % ( git_path , branch ) , cwd = dest )
if rc != 0 :
module . fail_json ( msg = " Failed to checkout branch %s " % branch ,
stdout = out , stderr = err , rc = rc )
cmd = " %s reset --hard %s " % ( git_path , remote )
( rc , out1 , err1 ) = module . run_command ( cmd , cwd = dest )
( rc , out1 , err1 ) = module . run_command ( cmd , cwd = dest )
if rc != 0 :
if rc != 0 :
if version != ' HEAD ' :
if version != ' HEAD ' :
@ -906,7 +908,7 @@ def main():
result . update ( before = None )
result . update ( before = None )
local_mods = False
local_mods = False
repo_updated = Non e
need_fetch = Tru e
if ( dest and not os . path . exists ( gitconfig ) ) or ( not dest and not allow_clone ) :
if ( dest and not os . path . exists ( gitconfig ) ) or ( not dest and not allow_clone ) :
# if there is no git configuration, do a clone operation unless:
# if there is no git configuration, do a clone operation unless:
# * the user requested no clone (they just want info)
# * the user requested no clone (they just want info)
@ -922,7 +924,7 @@ def main():
module . exit_json ( * * result )
module . exit_json ( * * result )
# there's no git config, so clone
# there's no git config, so clone
clone ( git_path , module , repo , dest , remote , depth , version , bare , reference , refspec , verify_commit )
clone ( git_path , module , repo , dest , remote , depth , version , bare , reference , refspec , verify_commit )
repo_updated = Tru e
need_fetch = Fals e
elif not update :
elif not update :
# Just return having found a repo already in the dest path
# Just return having found a repo already in the dest path
# this does no checking that the repo is the actual repo
# this does no checking that the repo is the actual repo
@ -951,38 +953,26 @@ def main():
if remote_url_changed :
if remote_url_changed :
result . update ( remote_url_changed = True )
result . update ( remote_url_changed = True )
remote_head = get_remote_head ( git_path , module , dest , version , remote , bare )
if need_fetch :
if result [ ' before ' ] == remote_head :
if module . check_mode :
if local_mods :
remote_head = get_remote_head ( git_path , module , dest , version , remote , bare )
result . update ( changed = True , after = remote_head , msg = ' Local modifications exist ' )
result . update ( changed = ( result [ ' before ' ] != remote_head ) , after = remote_head )
# FIXME: This diff should fail since the new remote_head is not fetched yet?!
if module . _diff :
if module . _diff :
diff = get_diff ( module , git_path , dest , repo , remote , depth , bare , result [ ' before ' ] , result [ ' after ' ] )
diff = get_diff ( module , git_path , dest , repo , remote , depth , bare , result [ ' before ' ] , result [ ' after ' ] )
if diff :
if diff :
result [ ' diff ' ] = diff
result [ ' diff ' ] = diff
module . exit_json ( * * result )
module . exit_json ( * * result )
elif version == ' HEAD ' :
# If the remote and local match and we're using the default of
# HEAD (It's not a real tag) then exit early
repo_updated = False
elif is_remote_tag ( git_path , module , dest , repo , version ) :
# if the remote is a tag and we have the tag locally, exit early
if version in get_tags ( git_path , module , dest ) :
repo_updated = False
else :
else :
# if the remote is a branch and we have the branch locally, exit early
fetch ( git_path , module , repo , dest , version , remote , depth , bare , refspec , git_version_used )
if version in get_branches ( git_path , module , dest ) :
repo_updated = False
if repo_updated is None :
result [ ' after ' ] = get_version ( module , git_path , dest )
if module . check_mode :
result . update ( changed = ( result [ ' before ' ] != remote_head ) , after = remote_head )
if result [ ' before ' ] == result [ ' after ' ] :
if module . _diff :
if local_mods :
diff = get_diff ( module , git_path , dest , repo , remote , depth , bare , result [ ' before ' ] , result [ ' after ' ] )
result . update ( changed = True , after = remote_head , msg = ' Local modifications exist ' )
if diff :
# no diff, since the repo didn't change
result [ ' diff ' ] = diff
module . exit_json ( * * result )
module . exit_json ( * * result )
fetch ( git_path , module , repo , dest , version , remote , depth , bare , refspec )
repo_updated = True
# switch to version specified regardless of whether
# switch to version specified regardless of whether
# we got new revisions from the repository
# we got new revisions from the repository
@ -996,12 +986,10 @@ def main():
if submodules_updated :
if submodules_updated :
result . update ( submodules_changed = submodules_updated )
result . update ( submodules_changed = submodules_updated )
if module . check_mode :
if module . check_mode :
if submodules_updated :
result . update ( changed = True , after = remote_head )
result . update ( changed = True , after = remote_head )
module . exit_json ( * * result )
module . exit_json ( * * result )
if submodules_updated :
# Switch to version specified
# Switch to version specified
submodule_update ( git_path , module , dest , track_submodules , force = force )
submodule_update ( git_path , module , dest , track_submodules , force = force )