diff --git a/swh/loader/git/converters.py b/swh/loader/git/converters.py --- a/swh/loader/git/converters.py +++ b/swh/loader/git/converters.py @@ -27,6 +27,13 @@ TimestampWithTimezone, ) +COMMIT_MODE_MASK = 0o160000 +"""Mode/perms of tree entries that point to a commit. +They are normally equal to this mask, but may have more bits set to 1.""" +TREE_MODE_MASK = 0o040000 +"""Mode/perms of tree entries that point to a tree. +They are normally equal to this mask, but may have more bits set to 1.""" + class HashMismatch(Exception): pass @@ -82,18 +89,17 @@ entries = [] - entry_mode_map = { - 0o040000: "dir", - 0o160000: "rev", - 0o100644: "file", - 0o100755: "file", - 0o120000: "file", - } - for entry in tree.iteritems(): + if entry.mode & COMMIT_MODE_MASK == COMMIT_MODE_MASK: + type_ = "rev" + elif entry.mode & TREE_MODE_MASK == TREE_MODE_MASK: + type_ = "dir" + else: + type_ = "file" + entries.append( DirectoryEntry( - type=entry_mode_map.get(entry.mode, "file"), + type=type_, perms=entry.mode, name=entry.path, target=hash_to_bytes(entry.sha.decode("ascii")), diff --git a/swh/loader/git/tests/test_converters.py b/swh/loader/git/tests/test_converters.py --- a/swh/loader/git/tests/test_converters.py +++ b/swh/loader/git/tests/test_converters.py @@ -10,6 +10,7 @@ import subprocess import tempfile +import dulwich.objects import dulwich.repo import pytest @@ -17,6 +18,8 @@ from swh.model.hashutil import bytehex_to_hash, hash_to_bytehex, hash_to_bytes from swh.model.model import ( Content, + Directory, + DirectoryEntry, ObjectType, Person, Release, @@ -215,6 +218,33 @@ with pytest.raises(converters.HashMismatch): converters.dulwich_tree_to_directory(tree) + def test_tree_perms(self): + entries = [ + (b"blob_100644", 0o100644, "file"), + (b"blob_100664", 0o100664, "file"), + (b"blob_100666", 0o100666, "file"), + (b"blob_120000", 0o120000, "file"), + (b"commit_160644", 0o160644, "rev"), + (b"commit_160664", 0o160664, "rev"), + (b"commit_160666", 0o160666, "rev"), + (b"commit_normal", 0o160000, "rev"), + (b"tree_040644", 0o040644, "dir"), + (b"tree_040664", 0o040664, "dir"), + (b"tree_040666", 0o040666, "dir"), + (b"tree_normal", 0o040000, "dir"), + ] + + tree = dulwich.objects.Tree() + for (name, mode, _) in entries: + tree.add(name, mode, b"00" * 20) + + assert converters.dulwich_tree_to_directory(tree) == Directory( + entries=tuple( + DirectoryEntry(type=type, perms=perms, name=name, target=b"\x00" * 20) + for (name, perms, type) in entries + ) + ) + def test_commit_to_revision(self): sha1 = b"9768d0b576dbaaecd80abedad6dfd0d72f1476da"