commit - 467a9f9e6cf87869b5f547253ba5148b1288b4b0
commit + 662b2117d16044d0c348a48e316229a2da046adf
blob - eaa127a1296a7d588ce5a43c71ebfc40e8520ca5
blob + d1a876fd7fb6bb7a57e253919eadae85fcdd0af4
--- .gitignore
+++ .gitignore
.mypy_cache/
.eggs
dulwich.dist-info
+.stestr
blob - /dev/null
blob + 64964357e1f50efe6cb570df8d609b9a692a93d2 (mode 644)
--- /dev/null
+++ .stestr.conf
+[DEFAULT]
+test_path=dulwich/tests
blob - 29a4749f6eb7e1cfed1b60a5d90cd021e9fd10d1
blob + 41df77cb18f9fe41ee34b2ea91f62eb998ccbe15
--- NEWS
+++ NEWS
+0.20.27 2022-01-04
+
+ * Allow adding files to repository in pre-commit hook.
+ (Jelmer Vernooij, #916)
+
+ * Raise SubmoduleEncountered in ``tree_lookup_path``.
+ (Jelmer Vernooij)
+
0.20.26 2021-10-29
* Support os.PathLike arguments to Repo.stage().
blob - 4433a294d4ae9d8cc99984c45c134ee665cfa451
blob + 3f3f472b7348f4aa816b6ebe9616187914f8c6b9
--- PKG-INFO
+++ PKG-INFO
Metadata-Version: 2.1
Name: dulwich
-Version: 0.20.26
+Version: 0.20.27
Summary: Python Git Library
Home-page: https://www.dulwich.io/
Author: Jelmer Vernooij
blob - 888b48f0605589b966ee4e903a226ba8c5b54014
blob + cb4d90567e8c0bd5de88570241991fe0bf84be73
--- dulwich/__init__.py
+++ dulwich/__init__.py
"""Python implementation of the Git file formats and protocols."""
-__version__ = (0, 20, 26)
+__version__ = (0, 20, 27)
blob - 85de5f098d2cb3b9b1a346c45fd812372f2096d7
blob + 001abe42b13471c889d2eb464026b8492bfcb3fb
--- dulwich/hooks.py
+++ dulwich/hooks.py
class PreCommitShellHook(ShellHook):
"""pre-commit shell hook"""
- def __init__(self, controldir):
+ def __init__(self, cwd, controldir):
filepath = os.path.join(controldir, "hooks", "pre-commit")
- ShellHook.__init__(self, "pre-commit", filepath, 0, cwd=controldir)
+ ShellHook.__init__(self, "pre-commit", filepath, 0, cwd=cwd)
class PostCommitShellHook(ShellHook):
def __init__(self, controldir):
self.controldir = controldir
filepath = os.path.join(controldir, "hooks", "post-receive")
- ShellHook.__init__(self, "post-receive", filepath, 0)
+ ShellHook.__init__(self, "post-receive", path=filepath, numparam=0)
def execute(self, client_refs):
# do nothing if the script doesn't exist
blob - 551f9c1f100fe4abcfe4907bf58ca38e468bce2d
blob + f6b0db483bbba0874007a906e9fd32a305d95bf4
--- dulwich/object_store.py
+++ dulwich/object_store.py
def _collect_ancestors(
self,
heads,
- common=set(),
- shallow=set(),
+ common=frozenset(),
+ shallow=frozenset(),
get_parents=lambda commit: commit.parents,
):
"""Collect all ancestors of heads up to (excluding) those in common.
blob - 8bdb40176b5daff30a4b46c8cee6435c288f1229
blob + 74ade5c1eff423b5dc083664681cd0f3cabc9023
--- dulwich/objects.py
+++ dulwich/objects.py
def sha_to_hex(sha):
"""Takes a string and returns the hex of the sha within"""
hexsha = binascii.hexlify(sha)
- assert len(hexsha) == 40, "Incorrect length of sha1 string: %d" % hexsha
+ assert len(hexsha) == 40, "Incorrect length of sha1 string: %s" % hexsha
return hexsha
hexsha.decode("ascii"),
name.decode(encoding, "replace"),
)
+
+
+class SubmoduleEncountered(Exception):
+ """A submodule was encountered while resolving a path."""
+
+ def __init__(self, path, sha):
+ self.path = path
+ self.sha = sha
class Tree(ShaFile):
parts = path.split(b"/")
sha = self.id
mode = None
- for p in parts:
+ for i, p in enumerate(parts):
if not p:
continue
+ if mode is not None and S_ISGITLINK(mode):
+ raise SubmoduleEncountered(b'/'.join(parts[:i]), sha)
obj = lookup_obj(sha)
if not isinstance(obj, Tree):
raise NotTreeError(sha)
blob - 235e71774a5d60d12d4f964ccb185a5fb16d768e
blob + 29b0e6694b1e27e3cf4ba3de92cdd5f95f3ed00b
--- dulwich/repo.py
+++ dulwich/repo.py
New commit SHA1
"""
+ try:
+ if not no_verify:
+ self.hooks["pre-commit"].execute()
+ except HookError as e:
+ raise CommitError(e)
+ except KeyError: # no hook defined, silent fallthrough
+ pass
+
c = Commit()
if tree is None:
index = self.open_index()
raise ValueError("tree must be a 40-byte hex sha string")
c.tree = tree
- try:
- if not no_verify:
- self.hooks["pre-commit"].execute()
- except HookError as e:
- raise CommitError(e)
- except KeyError: # no hook defined, silent fallthrough
- pass
-
config = self.get_config_stack()
if merge_heads is None:
merge_heads = self._read_heads("MERGE_HEAD")
if os.path.isfile(hidden_path):
with open(hidden_path, "r") as f:
path = read_gitfile(f)
- self.bare = False
self._controldir = os.path.join(root, path)
else:
self._controldir = hidden_path
with graft_file:
self._graftpoints.update(parse_graftpoints(graft_file))
- self.hooks["pre-commit"] = PreCommitShellHook(self.controldir())
+ self.hooks["pre-commit"] = PreCommitShellHook(self.path, self.controldir())
self.hooks["commit-msg"] = CommitMsgShellHook(self.controldir())
self.hooks["post-commit"] = PostCommitShellHook(self.controldir())
self.hooks["post-receive"] = PostReceiveShellHook(self.controldir())
blob - b3fb0e290776b37986485e859d7af0054f76f444
blob + 6e416f1d5e43f52d9eeb75674927246b12f99bbf
--- dulwich/tests/test_hooks.py
+++ dulwich/tests/test_hooks.py
)
pre_commit = os.path.join(repo_dir, "hooks", "pre-commit")
- hook = PreCommitShellHook(repo_dir)
+ hook = PreCommitShellHook(repo_dir, repo_dir)
with open(pre_commit, "w") as f:
f.write(pre_commit_fail)
blob - 68789aacb3abed59695a69a647b10b55b13e909d
blob + 2f0329f2840b84326570efa1fb06f8d84a87407e
--- dulwich/tests/test_object_store.py
+++ dulwich/tests/test_object_store.py
Tree,
TreeEntry,
EmptyFileException,
+ SubmoduleEncountered,
+ S_IFGITLINK,
)
from dulwich.object_store import (
DiskObjectStore,
(b"ad/bd/c", blob_c.id, 0o100755),
(b"ad/c", blob_c.id, 0o100644),
(b"c", blob_c.id, 0o100644),
+ (b"d", blob_c.id, S_IFGITLINK),
]
self.tree_id = commit_tree(self.store, blobs)
o_id = tree_lookup_path(self.get_object, self.tree_id, b"ad/bd/")[1]
self.assertTrue(isinstance(self.store[o_id], Tree))
+ def test_lookup_submodule(self):
+ tree_lookup_path(self.get_object, self.tree_id, b"d")[1]
+ self.assertRaises(
+ SubmoduleEncountered, tree_lookup_path, self.get_object,
+ self.tree_id, b"d/a")
+
def test_lookup_nonexistent(self):
self.assertRaises(
KeyError, tree_lookup_path, self.get_object, self.tree_id, b"j"
blob - 05034888609904094a31020f069f235f8c6c016a
blob + f8975cad544709687eb17bcaf16907b184744b56
--- dulwich/tests/test_repository.py
+++ dulwich/tests/test_repository.py
self.assertRaises(
errors.CommitError,
r.do_commit,
- "failed commit",
- committer="Test Committer <test@nodomain.com>",
- author="Test Author <test@nodomain.com>",
+ b"failed commit",
+ committer=b"Test Committer <test@nodomain.com>",
+ author=b"Test Author <test@nodomain.com>",
commit_timestamp=12345,
commit_timezone=0,
author_timestamp=12345,
commit_sha = r.do_commit(
b"empty commit",
+ 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,
+ )
+ self.assertEqual([], r[commit_sha].parents)
+
+ def test_shell_hook_pre_commit_add_files(self):
+ if os.name != "posix":
+ self.skipTest("shell hook tests requires POSIX shell")
+
+ pre_commit_contents = """#!%(executable)s
+import sys
+sys.path.extend(':'.join(%(path)s))
+from dulwich.repo import Repo
+
+with open('foo', 'w') as f:
+ f.write('newfile')
+
+r = Repo('.')
+r.stage(['foo'])
+""" % {'executable': sys.executable, 'path': repr(sys.path)}
+
+ repo_dir = os.path.join(self.mkdtemp())
+ self.addCleanup(shutil.rmtree, repo_dir)
+ r = Repo.init(repo_dir)
+ self.addCleanup(r.close)
+
+ with open(os.path.join(repo_dir, 'blah'), 'w') as f:
+ f.write('blah')
+
+ r.stage(['blah'])
+
+ pre_commit = os.path.join(r.controldir(), "hooks", "pre-commit")
+
+ with open(pre_commit, "w") as f:
+ f.write(pre_commit_contents)
+ os.chmod(pre_commit, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
+
+ commit_sha = r.do_commit(
+ b"new commit",
committer=b"Test Committer <test@nodomain.com>",
author=b"Test Author <test@nodomain.com>",
commit_timestamp=12395,
)
self.assertEqual([], r[commit_sha].parents)
+ tree = r[r[commit_sha].tree]
+ self.assertEqual(set([b'blah', b'foo']), set(tree))
+
def test_shell_hook_post_commit(self):
if os.name != "posix":
self.skipTest("shell hook tests requires POSIX shell")
blob - 4433a294d4ae9d8cc99984c45c134ee665cfa451
blob + 3f3f472b7348f4aa816b6ebe9616187914f8c6b9
--- dulwich.egg-info/PKG-INFO
+++ dulwich.egg-info/PKG-INFO
Metadata-Version: 2.1
Name: dulwich
-Version: 0.20.26
+Version: 0.20.27
Summary: Python Git Library
Home-page: https://www.dulwich.io/
Author: Jelmer Vernooij
blob - 75bc62eb2b568f43d43518ae5b2c38c61eaa47be
blob + a9f8ea6e10a235c8784b00f27a4bd695767ba248
--- dulwich.egg-info/SOURCES.txt
+++ dulwich.egg-info/SOURCES.txt
.flake8
.gitignore
.mailmap
+.stestr.conf
.testr.conf
AUTHORS
CODE_OF_CONDUCT.md
dulwich.egg-info/not-zip-safe
dulwich.egg-info/requires.txt
dulwich.egg-info/top_level.txt
+dulwich/../docs/tutorial/conclusion.txt
+dulwich/../docs/tutorial/encoding.txt
+dulwich/../docs/tutorial/file-format.txt
+dulwich/../docs/tutorial/index.txt
+dulwich/../docs/tutorial/introduction.txt
+dulwich/../docs/tutorial/object-store.txt
+dulwich/../docs/tutorial/porcelain.txt
+dulwich/../docs/tutorial/remote.txt
+dulwich/../docs/tutorial/repo.txt
+dulwich/../docs/tutorial/tag.txt
dulwich/cloud/__init__.py
dulwich/cloud/gcs.py
dulwich/contrib/README.md
blob - b1b6e5e3283945b58ca84f7e567f5baf3212060b
blob + 8ca2a2fb253b8e6c74e80d5499feec21834c7deb
--- setup.py
+++ setup.py
'For 2.7 support, please install a version prior to 0.20')
-dulwich_version_string = '0.20.26'
+dulwich_version_string = '0.20.27'
class DulwichDistribution(Distribution):