Skip to content

Commit

Permalink
Merge branch 'fix/tree_path' of git://github.com/r0mainK/dulwich
Browse files Browse the repository at this point in the history
Fixes #598
  • Loading branch information
jelmer committed Jul 18, 2018
2 parents 5f3c8c1 + 7125a45 commit 8d82f4f
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 23 deletions.
27 changes: 18 additions & 9 deletions dulwich/porcelain.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,25 @@ def open_repo_closing(path_or_repo):


def path_to_tree_path(repopath, path):
"""Convert a path to a path usable in e.g. an index.
"""Convert a path to a path usable in an index, e.g. bytes and relative to
the repository root.
:param repo: Repository
:param path: A path
:param repopath: Repository path, absolute or relative to the cwd
:param path: A path, absolute or relative to the cwd
:return: A path formatted for use in e.g. an index
"""
os.path.relpath(path, repopath)
if os.path.sep != '/':
path = path.replace(os.path.sep, '/')
return path.encode(sys.getfilesystemencoding())
if not isinstance(path, bytes):
path = path.encode(sys.getfilesystemencoding())
if not isinstance(repopath, bytes):
repopath = repopath.encode(sys.getfilesystemencoding())
if os.path.isabs(path) and not os.path.isabs(repopath):
repopath = os.path.abspath(repopath)
elif os.path.isabs(repopath) and not os.path.isabs(path):
path = os.path.abspath(path)
treepath = os.path.relpath(path, repopath)
if treepath.startswith(b'..'):
raise ValueError('Path not in repo')
return treepath


def archive(repo, committish=None, outstream=default_bytes_out_stream,
Expand Down Expand Up @@ -1188,10 +1197,10 @@ def check_ignore(repo, paths, no_index=False):
index = r.open_index()
ignore_manager = IgnoreFilterManager.from_repo(r)
for path in paths:
if os.path.isabs(path):
path = os.path.relpath(path, r.path)
if not no_index and path_to_tree_path(r.path, path) in index:
continue
if os.path.isabs(path):
path = os.path.relpath(path, r.path)
if ignore_manager.is_ignored(path):
yield path

Expand Down
123 changes: 109 additions & 14 deletions dulwich/tests/test_porcelain.py
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ def test_empty(self):
results.staged)
self.assertEqual([], results.unstaged)

def test_status(self):
def test_status_base(self):
"""Integration test for `status` functionality."""

# Commit a dummy file then modify it
Expand Down Expand Up @@ -859,6 +859,41 @@ def test_status(self):
filename_add.encode('ascii'))
self.assertEqual(results.unstaged, [b'foo'])

def test_status_all(self):
del_path = os.path.join(self.repo.path, 'foo')
mod_path = os.path.join(self.repo.path, 'bar')
add_path = os.path.join(self.repo.path, 'baz')
us_path = os.path.join(self.repo.path, 'blye')
ut_path = os.path.join(self.repo.path, 'blyat')
with open(del_path, 'w') as f:
f.write('origstuff')
with open(mod_path, 'w') as f:
f.write('origstuff')
with open(us_path, 'w') as f:
f.write('origstuff')
porcelain.add(repo=self.repo.path, paths=[del_path, mod_path, us_path])
porcelain.commit(repo=self.repo.path, message=b'test status',
author=b'author <email>',
committer=b'committer <email>')
porcelain.remove(self.repo.path, [del_path])
with open(add_path, 'w') as f:
f.write('origstuff')
with open(mod_path, 'w') as f:
f.write('more_origstuff')
with open(us_path, 'w') as f:
f.write('more_origstuff')
porcelain.add(repo=self.repo.path, paths=[add_path, mod_path])
with open(us_path, 'w') as f:
f.write('\norigstuff')
with open(ut_path, 'w') as f:
f.write('origstuff')
results = porcelain.status(self.repo.path)
self.assertDictEqual(
{'add': [b'baz'], 'delete': [b'foo'], 'modify': [b'bar']},
results.staged)
self.assertListEqual(results.unstaged, [b'blye'])
self.assertListEqual(results.untracked, ['blyat'])

def test_get_tree_changes_add(self):
"""Unit test for get_tree_changes add."""

Expand Down Expand Up @@ -1283,27 +1318,48 @@ class CheckIgnoreTests(PorcelainTestCase):

def test_check_ignored(self):
with open(os.path.join(self.repo.path, '.gitignore'), 'w') as f:
f.write("foo")
with open(os.path.join(self.repo.path, 'foo'), 'w') as f:
f.write("BAR")
with open(os.path.join(self.repo.path, 'bar'), 'w') as f:
f.write("BAR")
f.write('foo')
foo_path = os.path.join(self.repo.path, 'foo')
with open(foo_path, 'w') as f:
f.write('BAR')
bar_path = os.path.join(self.repo.path, 'bar')
with open(bar_path, 'w') as f:
f.write('BAR')
self.assertEqual(
['foo'],
list(porcelain.check_ignore(self.repo, ['foo'])))
self.assertEqual([], list(porcelain.check_ignore(self.repo, ['bar'])))
list(porcelain.check_ignore(self.repo, [foo_path])))
self.assertEqual(
[], list(porcelain.check_ignore(self.repo, [bar_path])))

def test_check_added(self):
with open(os.path.join(self.repo.path, 'foo'), 'w') as f:
f.write("BAR")
def test_check_added_abs(self):
path = os.path.join(self.repo.path, 'foo')
with open(path, 'w') as f:
f.write('BAR')
self.repo.stage(['foo'])
with open(os.path.join(self.repo.path, '.gitignore'), 'w') as f:
f.write("foo\n")
f.write('foo\n')
self.assertEqual(
[], list(porcelain.check_ignore(self.repo, ['foo'])))
[], list(porcelain.check_ignore(self.repo, [path])))
self.assertEqual(
['foo'],
list(porcelain.check_ignore(self.repo, ['foo'], no_index=True)))
list(porcelain.check_ignore(self.repo, [path], no_index=True)))

def test_check_added_rel(self):
with open(os.path.join(self.repo.path, 'foo'), 'w') as f:
f.write('BAR')
self.repo.stage(['foo'])
with open(os.path.join(self.repo.path, '.gitignore'), 'w') as f:
f.write('foo\n')
cwd = os.getcwd()
os.mkdir(os.path.join(self.repo.path, 'bar'))
os.chdir(os.path.join(self.repo.path, 'bar'))
try:
self.assertEqual(
list(porcelain.check_ignore(self.repo, ['../foo'])), [])
self.assertEqual(['../foo'], list(
porcelain.check_ignore(self.repo, ['../foo'], no_index=True)))
finally:
os.chdir(cwd)


class UpdateHeadTests(PorcelainTestCase):
Expand Down Expand Up @@ -1431,3 +1487,42 @@ def test_tag_and_commit(self):
self.assertEqual(
'tryme-1-g{}'.format(sha[:7].decode('ascii')),
porcelain.describe(self.repo.path))


class HelperTests(PorcelainTestCase):
def test_path_to_tree_path_base(self):
self.assertEqual(
b'bar', porcelain.path_to_tree_path('/home/foo', '/home/foo/bar'))
self.assertEqual(b'bar', porcelain.path_to_tree_path('.', './bar'))
self.assertEqual(b'bar', porcelain.path_to_tree_path('.', 'bar'))
cwd = os.getcwd()
self.assertEqual(
b'bar', porcelain.path_to_tree_path('.', os.path.join(cwd, 'bar')))
self.assertEqual(b'bar', porcelain.path_to_tree_path(cwd, 'bar'))

def test_path_to_tree_path_syntax(self):
self.assertEqual(b'bar', porcelain.path_to_tree_path(b'.', './bar'))
self.assertEqual(b'bar', porcelain.path_to_tree_path('.', b'./bar'))
self.assertEqual(b'bar', porcelain.path_to_tree_path(b'.', b'./bar'))

def test_path_to_tree_path_error(self):
with self.assertRaises(ValueError):
porcelain.path_to_tree_path('/home/foo/', '/home/bar/baz')

def test_path_to_tree_path_rel(self):
cwd = os.getcwd()
os.mkdir(os.path.join(self.repo.path, 'foo'))
os.mkdir(os.path.join(self.repo.path, 'foo/bar'))
try:
os.chdir(os.path.join(self.repo.path, 'foo/bar'))
self.assertEqual(b'bar/baz', porcelain.path_to_tree_path(
'..', 'baz'))
self.assertEqual(b'bar/baz', porcelain.path_to_tree_path(
os.path.join(os.getcwd(), '..'),
os.path.join(os.getcwd(), 'baz')))
self.assertEqual(b'bar/baz', porcelain.path_to_tree_path(
'..', os.path.join(os.getcwd(), 'baz')))
self.assertEqual(b'bar/baz', porcelain.path_to_tree_path(
os.path.join(os.getcwd(), '..'), 'baz'))
finally:
os.chdir(cwd)

0 comments on commit 8d82f4f

Please sign in to comment.