Kaynağa Gözat

Add failing test to ensure we don't fiddle with checkout path encoding.

Gary van der Merwe 10 yıl önce
ebeveyn
işleme
ed8574ee54

+ 2 - 1
dulwich/index.py

@@ -486,7 +486,8 @@ def build_index_from_tree(prefix, index_path, object_store, tree_id,
     for entry in object_store.iter_tree_contents(tree_id):
         if not validate_path(entry.path, validate_path_element):
             continue
-        full_path = os.path.join(prefix, entry.path.decode(sys.getfilesystemencoding()))
+        full_path = os.path.join(prefix,
+            entry.path.decode(sys.getfilesystemencoding()))
 
         if not os.path.exists(os.path.dirname(full_path)):
             os.makedirs(os.path.dirname(full_path))

+ 36 - 1
dulwich/tests/test_index.py

@@ -1,4 +1,5 @@
 # test_index.py -- Tests for the git index
+# encoding: utf-8
 # Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
 #
 # This program is free software; you can redistribute it and/or
@@ -52,9 +53,10 @@ from dulwich.objects import (
     )
 from dulwich.repo import Repo
 from dulwich.tests import (
+    expectedFailure,
     TestCase,
     skipIf,
-)
+    )
 
 class IndexTestCase(TestCase):
 
@@ -393,6 +395,39 @@ class BuildIndexTests(TestCase):
                 filee.id)
             self.assertFileContents(epath, 'd', symlink=True)
 
+    @expectedFailure
+    def test_no_decode_encode(self):
+        repo_dir = tempfile.mkdtemp()
+        repo_dir_bytes = repo_dir.encode(sys.getfilesystemencoding())
+        self.addCleanup(shutil.rmtree, repo_dir)
+        with closing(Repo.init(repo_dir)) as repo:
+
+            # Populate repo
+            file = Blob.from_string(b'foo')
+
+            tree = Tree()
+            latin1_name = u'À'.encode('latin1')
+            utf8_name = u'À'.encode('utf8')
+            tree[latin1_name] = (stat.S_IFREG | 0o644, file.id)
+            tree[utf8_name] = (stat.S_IFREG | 0o644, file.id)
+
+            repo.object_store.add_objects(
+                [(o, None) for o in [file, tree]])
+
+            build_index_from_tree(
+                repo.path, repo.index_path(),
+                repo.object_store, tree.id)
+
+            # Verify index entries
+            index = repo.open_index()
+
+            latin1_path = os.path.join(repo_dir_bytes, latin1_name)
+            self.assertTrue(os.path.exists(latin1_path))
+
+            utf8_path = os.path.join(repo_dir_bytes, utf8_name)
+            self.assertTrue(os.path.exists(utf8_path))
+
+
 class GetUnstagedChangesTests(TestCase):
 
     def test_get_unstaged_changes(self):

+ 30 - 5
dulwich/tests/test_repository.py

@@ -25,9 +25,9 @@ import locale
 import os
 import stat
 import shutil
+import sys
 import tempfile
 import warnings
-import sys
 
 from dulwich import errors
 from dulwich.object_store import (
@@ -40,6 +40,7 @@ from dulwich.repo import (
     MemoryRepo,
     )
 from dulwich.tests import (
+    expectedFailure,
     TestCase,
     skipIf,
     )
@@ -522,6 +523,7 @@ class BuildRepoRootTests(TestCase):
         self._repo_dir = self.get_repo_dir()
         os.makedirs(self._repo_dir)
         r = self._repo = Repo.init(self._repo_dir)
+        self.addCleanup(tear_down_repo, r)
         self.assertFalse(r.bare)
         self.assertEqual(b'ref: refs/heads/master', r.refs.read_ref(b'HEAD'))
         self.assertRaises(KeyError, lambda: r.refs[b'refs/heads/master'])
@@ -537,10 +539,6 @@ class BuildRepoRootTests(TestCase):
         self.assertEqual([], r[commit_sha].parents)
         self._root_commit = commit_sha
 
-    def tearDown(self):
-        tear_down_repo(self._repo)
-        super(BuildRepoRootTests, self).tearDown()
-
     def test_build_repo(self):
         r = self._repo
         self.assertEqual(b'ref: refs/heads/master', r.refs.read_ref(b'HEAD'))
@@ -747,3 +745,30 @@ class BuildRepoRootTests(TestCase):
         os.remove(os.path.join(r.path, 'a'))
         r.stage(['a'])
         r.stage(['a'])  # double-stage a deleted path
+
+    @expectedFailure
+    def test_commit_no_encode_decode(self):
+        r = self._repo
+        repo_path_bytes = r.path.encode(sys.getfilesystemencoding())
+        encodings = ('utf8', 'latin1')
+        names = [u'À'.encode(encoding) for encoding in encodings]
+        for name, encoding in zip(names, encodings):
+            full_path = os.path.join(repo_path_bytes, name)
+            with open(full_path, 'wb') as f:
+                f.write(encoding.encode('ascii'))
+            # These files are break tear_down_repo, so cleanup these files
+            # ourselves.
+            self.addCleanup(os.remove, full_path)
+
+        r.stage(names)
+        commit_sha = r.do_commit(b'Files with different encodings',
+             committer=b'Test Committer <test@nodomain.com>',
+             author=b'Test Author <test@nodomain.com>',
+             commit_timestamp=12395, commit_timezone=0,
+             author_timestamp=12395, author_timezone=0,
+             ref=None, merge_heads=[self._root_commit])
+
+        for name, encoding in zip(names, encodings):
+            mode, id = tree_lookup_path(r.get_object, r[commit_sha].tree, name)
+            self.assertEqual(stat.S_IFREG | 0o644, mode)
+            self.assertEqual(encoding.encode('ascii'), r[id].data)