فهرست منبع

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

Gary van der Merwe 10 سال پیش
والد
کامیت
ed8574ee54
3فایلهای تغییر یافته به همراه68 افزوده شده و 7 حذف شده
  1. 2 1
      dulwich/index.py
  2. 36 1
      dulwich/tests/test_index.py
  3. 30 5
      dulwich/tests/test_repository.py

+ 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)