diff --git a/NEWS b/NEWS index 9d292c8a6..28cf85cef 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,11 @@ * Handle commit identity fields with multiple ">" characters. (Nicolas Dandrimont) + IMPROVEMENTS + + * ``dulwich.porcelain.get_object_by_path`` method for easily + accessing a path in another tree. (Jelmer Vernooij) + 0.19.6 2018-08-11 BUG FIXES diff --git a/dulwich/porcelain.py b/dulwich/porcelain.py index 9110255e2..4569eae84 100644 --- a/dulwich/porcelain.py +++ b/dulwich/porcelain.py @@ -1385,3 +1385,23 @@ def describe(repo): # Return plain commit if no parent tag can be found return 'g{}'.format(latest_commit.id.decode('ascii')[:7]) + + +def get_object_by_path(repo, path, committish=None): + """Get an object by path. + + :param repo: A path to the repository + :param path: Path to look up + :param committish: Commit to look up path in + :return: A `ShaFile` object + """ + if committish is None: + committish = "HEAD" + # Get the repository + with open_repo_closing(repo) as r: + commit = parse_commit(repo, committish) + base_tree = commit.tree + (mode, sha) = tree_lookup_path( + r.object_store.__getitem__, + base_tree, path) + return r[sha] diff --git a/dulwich/tests/test_porcelain.py b/dulwich/tests/test_porcelain.py index f8e82320f..6147e3540 100644 --- a/dulwich/tests/test_porcelain.py +++ b/dulwich/tests/test_porcelain.py @@ -1541,3 +1541,24 @@ def test_path_to_tree_path_rel(self): os.path.join(os.getcwd(), '..'), 'baz')) finally: os.chdir(cwd) + + +class GetObjectBypathTests(PorcelainTestCase): + + def test_simple(self): + fullpath = os.path.join(self.repo.path, 'foo') + with open(fullpath, 'w') as f: + f.write("BAR") + porcelain.add(repo=self.repo.path, paths=[fullpath]) + porcelain.commit( + self.repo.path, message=b"Some message", + author=b"Joe ", + committer=b"Bob ") + self.assertEqual( + b"BAR", + porcelain.get_object_by_path(self.repo, 'foo').data) + + def test_missing(self): + self.assertRaises( + KeyError, + porcelain.get_object_by_path, self.repo, 'foo')