Skip to content

Commit 8dbff4e

Browse files
committed
Fixed handling of broken symlinks.
Skipping broken symlinks, but not all symlinks. Reported in #20
1 parent 3800876 commit 8dbff4e

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Changed
6161

6262
Fixed
6363
* https://github.com/Robpol86/sphinxcontrib-versioning/issues/13
64+
* https://github.com/Robpol86/sphinxcontrib-versioning/pull/20
6465

6566
Removed
6667
* Jinja2 context variables: ``scv_root_ref_is_branch`` ``scv_root_ref_is_tag``

sphinxcontrib/versioning/git.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ def export(local_root, commit, target):
277277
:param str commit: Git commit SHA to export.
278278
:param str target: Directory to export to.
279279
"""
280+
log = logging.getLogger(__name__)
280281
git_command = ['git', 'archive', '--format=tar', commit]
281282

282283
with TempDir() as temp_dir:
@@ -289,7 +290,12 @@ def export(local_root, commit, target):
289290
if not os.path.exists(t_dirpath):
290291
os.makedirs(t_dirpath)
291292
for args in ((os.path.join(s_dirpath, f), os.path.join(t_dirpath, f)) for f in s_filenames):
292-
shutil.copy(*args)
293+
try:
294+
shutil.copy(*args)
295+
except IOError:
296+
if not os.path.islink(args[0]):
297+
raise
298+
log.debug('Skipping broken symlink: %s', args[0])
293299

294300

295301
def clone(local_root, new_root, branch, rel_dest, exclude):

tests/test_git/test_export.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,27 @@ def test_new_branch_tags(tmpdir, local_light, fail):
9292
files = [f.relto(target) for f in target.listdir()]
9393
assert files == ['README']
9494
assert target.join('README').read() == 'new'
95+
96+
97+
def test_symlink(tmpdir, local, run):
98+
"""Test repos with broken symlinks.
99+
100+
:param tmpdir: pytest fixture.
101+
:param local: conftest fixture.
102+
:param run: conftest fixture.
103+
"""
104+
orphan = tmpdir.ensure('to_be_removed')
105+
local.join('good_symlink').mksymlinkto('README')
106+
local.join('broken_symlink').mksymlinkto('to_be_removed')
107+
run(local, ['git', 'add', 'good_symlink', 'broken_symlink'])
108+
run(local, ['git', 'commit', '-m', 'Added symlinks.'])
109+
run(local, ['git', 'push', 'origin', 'master'])
110+
orphan.remove()
111+
112+
target = tmpdir.ensure_dir('target')
113+
sha = run(local, ['git', 'rev-parse', 'HEAD']).strip()
114+
115+
export(str(local), sha, str(target))
116+
run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--']) # Exit 0 if nothing changed.
117+
files = sorted(f.relto(target) for f in target.listdir())
118+
assert files == ['README', 'good_symlink']

0 commit comments

Comments
 (0)