Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
ad5012f9
Commit
ad5012f9
authored
Nov 14, 2013
by
jctanner
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4691 from cg-soft/git-bare-ref-repo-support
Add support for bare git reference repos
parents
303e9960
f41d4ac3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
102 additions
and
35 deletions
+102
-35
library/source_control/git
+76
-34
test/TestRunner.py
+26
-1
No files found.
library/source_control/git
View file @
ad5012f9
...
...
@@ -43,6 +43,12 @@ options:
- What version of the repository to check out. This can be the
full 40-character I(SHA-1) hash, the literal string C(HEAD), a
branch name, or a tag name.
reference:
required: false
default: null
version_added: "1.4"
description:
- Reference repository (see "git clone --reference ...")
remote:
required: false
default: "origin"
...
...
@@ -81,6 +87,14 @@ options:
description:
- Path to git executable to use. If not supplied,
the normal mechanism for resolving binary paths will be used.
bare:
required: false
default: "no"
choices: [ "yes", "no" ]
version_added: "1.4"
description:
- if C(yes), repository will be created as a bare repo, otherwise
it will be a standard repo with a workspace.
notes:
- "If the task seems to be hanging, first verify remote host is in C(known_hosts).
SSH will prompt user to authorize the first contact with a remote host. To avoid this prompt,
...
...
@@ -104,15 +118,14 @@ EXAMPLES = '''
import
re
import
tempfile
def
get_version
(
git_path
,
dest
):
def
get_version
(
git_path
,
dest
,
ref
=
"HEAD"
):
''' samples the version of the git repo '''
os
.
chdir
(
dest
)
cmd
=
"
%
s show"
%
(
git_path
,)
sha
=
os
.
popen
(
cmd
)
.
read
()
.
split
(
"
\n
"
)
sha
=
sha
[
0
]
.
split
()[
1
]
cmd
=
"
%
s rev-parse
%
s"
%
(
git_path
,
ref
)
sha
=
os
.
popen
(
cmd
)
.
read
()
.
rstrip
(
"
\n
"
)
return
sha
def
clone
(
git_path
,
module
,
repo
,
dest
,
remote
,
depth
,
version
):
def
clone
(
git_path
,
module
,
repo
,
dest
,
remote
,
depth
,
version
,
bare
,
reference
):
''' makes a new git repo if it does not already exist '''
dest_dirname
=
os
.
path
.
dirname
(
dest
)
try
:
...
...
@@ -120,16 +133,28 @@ def clone(git_path, module, repo, dest, remote, depth, version):
except
:
pass
os
.
chdir
(
dest_dirname
)
cmd
=
[
git_path
,
'clone'
,
'-o'
,
remote
,
'--recursive'
]
if
is_remote_branch
(
git_path
,
module
,
dest
,
repo
,
version
)
\
or
is_remote_tag
(
git_path
,
module
,
dest
,
repo
,
version
):
cmd
.
extend
([
'--branch'
,
version
])
cmd
=
[
git_path
,
'clone'
]
if
bare
:
cmd
.
append
(
'--bare'
)
else
:
cmd
.
extend
([
'--origin'
,
remote
,
'--recursive'
])
if
is_remote_branch
(
git_path
,
module
,
dest
,
repo
,
version
)
\
or
is_remote_tag
(
git_path
,
module
,
dest
,
repo
,
version
):
cmd
.
extend
([
'--branch'
,
version
])
if
depth
:
cmd
.
extend
([
'--depth'
,
str
(
depth
)
])
if
reference
:
cmd
.
extend
([
'--reference'
,
str
(
reference
)
])
cmd
.
extend
([
repo
,
dest
])
return
module
.
run_command
(
cmd
,
check_rc
=
True
)
def
has_local_mods
(
git_path
,
dest
):
module
.
run_command
(
cmd
,
check_rc
=
True
)
if
bare
:
os
.
chdir
(
dest
)
if
remote
!=
'origin'
:
module
.
run_command
([
git_path
,
'remote'
,
'add'
,
remote
,
repo
],
check_rc
=
True
)
def
has_local_mods
(
git_path
,
dest
,
bare
):
if
bare
:
return
False
os
.
chdir
(
dest
)
cmd
=
"
%
s status -s"
%
(
git_path
,)
lines
=
os
.
popen
(
cmd
)
.
read
()
.
splitlines
()
...
...
@@ -146,7 +171,7 @@ def reset(git_path, module, dest):
cmd
=
"
%
s reset --hard HEAD"
%
(
git_path
,)
return
module
.
run_command
(
cmd
,
check_rc
=
True
)
def
get_remote_head
(
git_path
,
module
,
dest
,
version
,
remote
):
def
get_remote_head
(
git_path
,
module
,
dest
,
version
,
remote
,
bare
):
cloning
=
False
if
remote
==
module
.
params
[
'repo'
]:
cloning
=
True
...
...
@@ -157,7 +182,7 @@ def get_remote_head(git_path, module, dest, version, remote):
# cloning the repo, just get the remote's HEAD version
cmd
=
'
%
s ls-remote
%
s -h HEAD'
%
(
git_path
,
remote
)
else
:
head_branch
=
get_head_branch
(
git_path
,
module
,
dest
,
remote
)
head_branch
=
get_head_branch
(
git_path
,
module
,
dest
,
remote
,
bare
)
cmd
=
'
%
s ls-remote
%
s -h refs/heads/
%
s'
%
(
git_path
,
remote
,
head_branch
)
elif
is_remote_branch
(
git_path
,
module
,
dest
,
remote
,
version
):
cmd
=
'
%
s ls-remote
%
s -h refs/heads/
%
s'
%
(
git_path
,
remote
,
version
)
...
...
@@ -217,7 +242,7 @@ def is_not_a_branch(git_path, module, dest):
return
True
return
False
def
get_head_branch
(
git_path
,
module
,
dest
,
remote
):
def
get_head_branch
(
git_path
,
module
,
dest
,
remote
,
bare
=
False
):
'''
Determine what branch HEAD is associated with. This is partly
taken from lib/ansible/utils/__init__.py. It finds the correct
...
...
@@ -225,7 +250,10 @@ def get_head_branch(git_path, module, dest, remote):
associated with. In the case of a detached HEAD, this will look
up the branch in .git/refs/remotes/<remote>/HEAD.
'''
repo_path
=
os
.
path
.
join
(
dest
,
'.git'
)
if
bare
:
repo_path
=
dest
else
:
repo_path
=
os
.
path
.
join
(
dest
,
'.git'
)
# Check if the .git is a file. If it is a file, it means that we are in a submodule structure.
if
os
.
path
.
isfile
(
repo_path
):
try
:
...
...
@@ -248,14 +276,20 @@ def get_head_branch(git_path, module, dest, remote):
f
.
close
()
return
branch
def
fetch
(
git_path
,
module
,
repo
,
dest
,
version
,
remote
):
def
fetch
(
git_path
,
module
,
repo
,
dest
,
version
,
remote
,
bare
):
''' updates repo from remote sources '''
os
.
chdir
(
dest
)
(
rc
,
out1
,
err1
)
=
module
.
run_command
(
"
%
s fetch
%
s"
%
(
git_path
,
remote
))
if
bare
:
(
rc
,
out1
,
err1
)
=
module
.
run_command
([
git_path
,
'fetch'
,
remote
,
'+refs/heads/*:refs/heads/*'
])
else
:
(
rc
,
out1
,
err1
)
=
module
.
run_command
(
"
%
s fetch
%
s"
%
(
git_path
,
remote
))
if
rc
!=
0
:
module
.
fail_json
(
msg
=
"Failed to download remote objects and refs"
)
(
rc
,
out2
,
err2
)
=
module
.
run_command
(
"
%
s fetch --tags
%
s"
%
(
git_path
,
remote
))
if
bare
:
(
rc
,
out2
,
err2
)
=
module
.
run_command
([
git_path
,
'fetch'
,
remote
,
'+refs/tags/*:refs/tags/*'
])
else
:
(
rc
,
out2
,
err2
)
=
module
.
run_command
(
"
%
s fetch --tags
%
s"
%
(
git_path
,
remote
))
if
rc
!=
0
:
module
.
fail_json
(
msg
=
"Failed to download remote objects and refs"
)
(
rc
,
out3
,
err3
)
=
submodule_update
(
git_path
,
module
,
dest
)
...
...
@@ -314,24 +348,31 @@ def main():
repo
=
dict
(
required
=
True
,
aliases
=
[
'name'
]),
version
=
dict
(
default
=
'HEAD'
),
remote
=
dict
(
default
=
'origin'
),
reference
=
dict
(
default
=
None
),
force
=
dict
(
default
=
'yes'
,
type
=
'bool'
),
depth
=
dict
(
default
=
None
,
type
=
'int'
),
update
=
dict
(
default
=
'yes'
,
type
=
'bool'
),
executable
=
dict
(
default
=
None
),
bare
=
dict
(
default
=
'no'
,
type
=
'bool'
),
),
supports_check_mode
=
True
)
dest
=
os
.
path
.
abspath
(
os
.
path
.
expanduser
(
module
.
params
[
'dest'
]))
repo
=
module
.
params
[
'repo'
]
version
=
module
.
params
[
'version'
]
remote
=
module
.
params
[
'remote'
]
force
=
module
.
params
[
'force'
]
depth
=
module
.
params
[
'depth'
]
update
=
module
.
params
[
'update'
]
git_path
=
module
.
params
[
'executable'
]
or
module
.
get_bin_path
(
'git'
,
True
)
gitconfig
=
os
.
path
.
join
(
dest
,
'.git'
,
'config'
)
dest
=
os
.
path
.
abspath
(
os
.
path
.
expanduser
(
module
.
params
[
'dest'
]))
repo
=
module
.
params
[
'repo'
]
version
=
module
.
params
[
'version'
]
remote
=
module
.
params
[
'remote'
]
force
=
module
.
params
[
'force'
]
depth
=
module
.
params
[
'depth'
]
update
=
module
.
params
[
'update'
]
bare
=
module
.
params
[
'bare'
]
reference
=
module
.
params
[
'reference'
]
git_path
=
module
.
params
[
'executable'
]
or
module
.
get_bin_path
(
'git'
,
True
)
if
bare
:
gitconfig
=
os
.
path
.
join
(
dest
,
'config'
)
else
:
gitconfig
=
os
.
path
.
join
(
dest
,
'.git'
,
'config'
)
rc
,
out
,
err
,
status
=
(
0
,
None
,
None
,
None
)
...
...
@@ -343,7 +384,7 @@ def main():
if
module
.
check_mode
:
remote_head
=
get_remote_head
(
git_path
,
module
,
dest
,
version
,
repo
)
module
.
exit_json
(
changed
=
True
,
before
=
before
,
after
=
remote_head
)
clone
(
git_path
,
module
,
repo
,
dest
,
remote
,
depth
,
version
)
clone
(
git_path
,
module
,
repo
,
dest
,
remote
,
depth
,
version
,
bare
,
reference
)
elif
not
update
:
# Just return having found a repo already in the dest path
# this does no checking that the repo is the actual repo
...
...
@@ -352,9 +393,8 @@ def main():
module
.
exit_json
(
changed
=
False
,
before
=
before
,
after
=
before
)
else
:
# else do a pull
local_mods
=
has_local_mods
(
git_path
,
dest
)
local_mods
=
has_local_mods
(
git_path
,
dest
,
bare
)
before
=
get_version
(
git_path
,
dest
)
remote_head
=
get_remote_head
(
git_path
,
module
,
dest
,
version
,
remote
)
if
local_mods
:
# failure should happen regardless of check mode
if
not
force
:
...
...
@@ -363,6 +403,7 @@ def main():
if
not
module
.
check_mode
:
reset
(
git_path
,
module
,
dest
)
# exit if already at desired sha version
remote_head
=
get_remote_head
(
git_path
,
module
,
dest
,
version
,
remote
,
bare
)
if
before
==
remote_head
:
if
local_mods
:
module
.
exit_json
(
changed
=
True
,
before
=
before
,
after
=
remote_head
,
...
...
@@ -371,11 +412,12 @@ def main():
module
.
exit_json
(
changed
=
False
,
before
=
before
,
after
=
remote_head
)
if
module
.
check_mode
:
module
.
exit_json
(
changed
=
True
,
before
=
before
,
after
=
remote_head
)
fetch
(
git_path
,
module
,
repo
,
dest
,
version
,
remote
)
fetch
(
git_path
,
module
,
repo
,
dest
,
version
,
remote
,
bare
)
# switch to version specified regardless of whether
# we cloned or pulled
switch_version
(
git_path
,
module
,
dest
,
remote
,
version
)
if
not
bare
:
switch_version
(
git_path
,
module
,
dest
,
remote
,
version
)
# determine if we changed anything
after
=
get_version
(
git_path
,
dest
)
...
...
test/TestRunner.py
View file @
ad5012f9
...
...
@@ -170,10 +170,13 @@ class TestRunner(unittest.TestCase):
def
test_git
(
self
):
self
.
_run
(
'file'
,
[
'path=/tmp/gitdemo'
,
'state=absent'
])
self
.
_run
(
'file'
,
[
'path=/tmp/gd'
,
'state=absent'
])
self
.
_run
(
'file'
,
[
'path=/tmp/gdbare'
,
'state=absent'
])
self
.
_run
(
'file'
,
[
'path=/tmp/gdreference'
,
'state=absent'
])
self
.
_run
(
'file'
,
[
'path=/tmp/gdreftest'
,
'state=absent'
])
self
.
_run
(
'command'
,
[
'git init gitdemo'
,
'chdir=/tmp'
])
self
.
_run
(
'command'
,
[
'touch a'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'git add *'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'git commit -m "test commit
2
"'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'git commit -m "test commit
1
"'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'touch b'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'git add *'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'git commit -m "test commit 2"'
,
'chdir=/tmp/gitdemo'
])
...
...
@@ -186,6 +189,28 @@ class TestRunner(unittest.TestCase):
# test the force option when set
result
=
self
.
_run
(
'git'
,
[
"repo=
\"
file:///tmp/gitdemo
\"
"
,
"dest=/tmp/gd"
,
"force=yes"
])
assert
result
[
'changed'
]
# test the bare option
result
=
self
.
_run
(
'git'
,
[
"repo=
\"
file:///tmp/gitdemo
\"
"
,
"dest=/tmp/gdbare"
,
"bare=yes"
,
"remote=test"
])
assert
result
[
'changed'
]
# test a no-op fetch
result
=
self
.
_run
(
'git'
,
[
"repo=
\"
file:///tmp/gitdemo
\"
"
,
"dest=/tmp/gdbare"
,
"bare=yes"
])
assert
not
result
[
'changed'
]
# test whether fetch is working for bare repos
self
.
_run
(
'command'
,
[
'touch c'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'git add *'
,
'chdir=/tmp/gitdemo'
])
self
.
_run
(
'command'
,
[
'git commit -m "test commit 3"'
,
'chdir=/tmp/gitdemo'
])
result
=
self
.
_run
(
'git'
,
[
"repo=
\"
file:///tmp/gitdemo
\"
"
,
"dest=/tmp/gdbare"
,
"bare=yes"
])
assert
result
[
'changed'
]
# test reference repos
result
=
self
.
_run
(
'git'
,
[
"repo=
\"
file:///tmp/gdbare
\"
"
,
"dest=/tmp/gdreference"
,
"bare=yes"
])
assert
result
[
'changed'
]
result
=
self
.
_run
(
'git'
,
[
"repo=
\"
file:///tmp/gitdemo
\"
"
,
"dest=/tmp/gdreftest"
,
"reference=/tmp/gdreference/"
])
assert
result
[
'changed'
]
assert
os
.
path
.
isfile
(
'/tmp/gdreftest/a'
)
result
=
self
.
_run
(
'command'
,
[
'ls'
,
'chdir=/tmp/gdreference/objects/pack'
])
assert
result
[
'stdout'
]
!=
''
result
=
self
.
_run
(
'command'
,
[
'ls'
,
'chdir=/tmp/gdreftest/.git/objects/pack'
])
assert
result
[
'stdout'
]
==
''
def
test_file
(
self
):
filedemo
=
tempfile
.
mkstemp
()[
1
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment