summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/test_base.py9
-rw-r--r--test/test_commit.py31
-rw-r--r--test/test_diff.py70
-rw-r--r--test/test_remote.py424
-rw-r--r--test/test_repo.py336
-rw-r--r--test/test_submodule.py238
-rw-r--r--test/test_util.py21
7 files changed, 673 insertions, 456 deletions
diff --git a/test/test_base.py b/test/test_base.py
index ccfdc8ed..30029367 100644
--- a/test/test_base.py
+++ b/test/test_base.py
@@ -9,6 +9,7 @@ import sys
import tempfile
from unittest import SkipTest, skipIf
+from git import Repo
from git.objects import Blob, Tree, Commit, TagObject
from git.compat import is_win
from git.objects.util import get_object_type_by_name
@@ -95,14 +96,18 @@ class TestBase(_TestBase):
self.assertEqual(self.rorepo.head.reference.object, self.rorepo.active_branch.object)
@with_rw_repo("HEAD", bare=True)
- def test_with_bare_rw_repo(self, bare_rw_repo):
+ def test_with_bare_rw_repo(self, bare_rw_repo: Repo):
assert bare_rw_repo.config_reader("repository").getboolean("core", "bare")
assert osp.isfile(osp.join(bare_rw_repo.git_dir, "HEAD"))
+ assert osp.isdir(bare_rw_repo.working_dir)
+ assert bare_rw_repo.working_tree_dir is None
@with_rw_repo("0.1.6")
- def test_with_rw_repo(self, rw_repo):
+ def test_with_rw_repo(self, rw_repo: Repo):
assert not rw_repo.config_reader("repository").getboolean("core", "bare")
+ assert osp.isdir(rw_repo.working_tree_dir)
assert osp.isdir(osp.join(rw_repo.working_tree_dir, "lib"))
+ assert osp.isdir(rw_repo.working_dir)
@skipIf(HIDE_WINDOWS_FREEZE_ERRORS, "FIXME: Freezes! sometimes...")
@with_rw_and_rw_remote_repo("0.1.6")
diff --git a/test/test_commit.py b/test/test_commit.py
index c5a43c94..1efc6889 100644
--- a/test/test_commit.py
+++ b/test/test_commit.py
@@ -159,6 +159,37 @@ class TestCommit(TestCommitSerialization):
self.assertEqual(commit.committer_tz_offset, 14400, commit.committer_tz_offset)
self.assertEqual(commit.message, "initial project\n")
+ def test_renames(self):
+ commit = self.rorepo.commit("185d847ec7647fd2642a82d9205fb3d07ea71715")
+ files = commit.stats.files
+
+ # when a file is renamed, the output of git diff is like "dir/{old => new}"
+ # unless we disable rename with --no-renames, which produces two lines
+ # one with the old path deletes and another with the new added
+ self.assertEqual(len(files), 2)
+
+ def check_entries(path, changes):
+ expected = {
+ ".github/workflows/Future.yml" : {
+ 'insertions': 57,
+ 'deletions': 0,
+ 'lines': 57
+ },
+ ".github/workflows/test_pytest.yml" : {
+ 'insertions': 0,
+ 'deletions': 55,
+ 'lines': 55
+ },
+ }
+ assert path in expected
+ assert isinstance(changes, dict)
+ for key in ("insertions", "deletions", "lines"):
+ assert changes[key] == expected[path][key]
+
+ for path, changes in files.items():
+ check_entries(path, changes)
+ # END for each stated file
+
def test_unicode_actor(self):
# assure we can parse unicode actors correctly
name = "Üäöß ÄußÉ"
diff --git a/test/test_diff.py b/test/test_diff.py
index 7065f063..50433774 100644
--- a/test/test_diff.py
+++ b/test/test_diff.py
@@ -411,3 +411,73 @@ class TestDiff(TestBase):
cp = c.parents[0]
diff_index = c.diff(cp, ["does/not/exist"])
self.assertEqual(len(diff_index), 0)
+
+ @with_rw_directory
+ def test_rename_override(self, rw_dir):
+ """Test disabling of diff rename detection"""
+
+ # create and commit file_a.txt
+ repo = Repo.init(rw_dir)
+ file_a = osp.join(rw_dir, "file_a.txt")
+ with open(file_a, "w", encoding='utf-8') as outfile:
+ outfile.write("hello world\n")
+ repo.git.add(Git.polish_url(file_a))
+ repo.git.commit(message="Added file_a.txt")
+
+ # remove file_a.txt
+ repo.git.rm(Git.polish_url(file_a))
+
+ # create and commit file_b.txt with similarity index of 52
+ file_b = osp.join(rw_dir, "file_b.txt")
+ with open(file_b, "w", encoding='utf-8') as outfile:
+ outfile.write("hello world\nhello world")
+ repo.git.add(Git.polish_url(file_b))
+ repo.git.commit(message="Removed file_a.txt. Added file_b.txt")
+
+ commit_a = repo.commit('HEAD')
+ commit_b = repo.commit('HEAD~1')
+
+ # check default diff command with renamed files enabled
+ diffs = commit_b.diff(commit_a)
+ self.assertEqual(1, len(diffs))
+ diff = diffs[0]
+ self.assertEqual(True, diff.renamed_file)
+ self.assertEqual('file_a.txt', diff.rename_from)
+ self.assertEqual('file_b.txt', diff.rename_to)
+
+ # check diff with rename files disabled
+ diffs = commit_b.diff(commit_a, no_renames=True)
+ self.assertEqual(2, len(diffs))
+
+ # check fileA.txt deleted
+ diff = diffs[0]
+ self.assertEqual(True, diff.deleted_file)
+ self.assertEqual('file_a.txt', diff.a_path)
+
+ # check fileB.txt added
+ diff = diffs[1]
+ self.assertEqual(True, diff.new_file)
+ self.assertEqual('file_b.txt', diff.a_path)
+
+ # check diff with high similarity index
+ diffs = commit_b.diff(commit_a, split_single_char_options=False, M='75%')
+ self.assertEqual(2, len(diffs))
+
+ # check fileA.txt deleted
+ diff = diffs[0]
+ self.assertEqual(True, diff.deleted_file)
+ self.assertEqual('file_a.txt', diff.a_path)
+
+ # check fileB.txt added
+ diff = diffs[1]
+ self.assertEqual(True, diff.new_file)
+ self.assertEqual('file_b.txt', diff.a_path)
+
+ # check diff with low similarity index
+ diffs = commit_b.diff(commit_a, split_single_char_options=False, M='40%')
+ self.assertEqual(1, len(diffs))
+ diff = diffs[0]
+ self.assertEqual(True, diff.renamed_file)
+ self.assertEqual('file_a.txt', diff.rename_from)
+ self.assertEqual('file_b.txt', diff.rename_to)
+
diff --git a/test/test_remote.py b/test/test_remote.py
index 3a47afab..9636ca48 100644
--- a/test/test_remote.py
+++ b/test/test_remote.py
@@ -694,259 +694,279 @@ class TestRemote(TestBase):
@with_rw_repo("HEAD")
def test_set_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- remote.set_url(url)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ remote.set_url(url)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_set_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- remote.set_url(url, allow_unsafe_protocols=True)
- assert list(remote.urls)[-1] == url
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ remote.set_url(url, allow_unsafe_protocols=True)
+ assert list(remote.urls)[-1] == url
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_add_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- remote.add_url(url)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ remote.add_url(url)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_add_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- remote.add_url(url, allow_unsafe_protocols=True)
- assert list(remote.urls)[-1] == url
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ remote.add_url(url, allow_unsafe_protocols=True)
+ assert list(remote.urls)[-1] == url
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_create_remote_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- Remote.create(rw_repo, "origin", url)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ Remote.create(rw_repo, "origin", url)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_create_remote_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for i, url in enumerate(urls):
- remote = Remote.create(rw_repo, f"origin{i}", url, allow_unsafe_protocols=True)
- assert remote.url == url
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for i, url in enumerate(urls):
+ remote = Remote.create(rw_repo, f"origin{i}", url, allow_unsafe_protocols=True)
+ assert remote.url == url
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_fetch_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- remote.fetch(url)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ remote.fetch(url)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_fetch_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- # The URL will be allowed into the command, but the command will
- # fail since we don't have that protocol enabled in the Git config file.
- with self.assertRaises(GitCommandError):
- remote.fetch(url, allow_unsafe_protocols=True)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ # The URL will be allowed into the command, but the command will
+ # fail since we don't have that protocol enabled in the Git config file.
+ with self.assertRaises(GitCommandError):
+ remote.fetch(url, allow_unsafe_protocols=True)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_fetch_unsafe_options(self, rw_repo):
- remote = rw_repo.remote("origin")
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
- for unsafe_option in unsafe_options:
- with self.assertRaises(UnsafeOptionError):
- remote.fetch(**unsafe_option)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ remote = rw_repo.remote("origin")
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(UnsafeOptionError):
+ remote.fetch(**unsafe_option)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_fetch_unsafe_options_allowed(self, rw_repo):
- remote = rw_repo.remote("origin")
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
- for unsafe_option in unsafe_options:
- # The options will be allowed, but the command will fail.
- assert not tmp_file.exists()
- with self.assertRaises(GitCommandError):
- remote.fetch(**unsafe_option, allow_unsafe_options=True)
- assert tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ remote = rw_repo.remote("origin")
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
+ for unsafe_option in unsafe_options:
+ # The options will be allowed, but the command will fail.
+ assert not tmp_file.exists()
+ with self.assertRaises(GitCommandError):
+ remote.fetch(**unsafe_option, allow_unsafe_options=True)
+ assert tmp_file.exists()
+ tmp_file.unlink()
@with_rw_repo("HEAD")
def test_pull_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- remote.pull(url)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ remote.pull(url)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_pull_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- # The URL will be allowed into the command, but the command will
- # fail since we don't have that protocol enabled in the Git config file.
- with self.assertRaises(GitCommandError):
- remote.pull(url, allow_unsafe_protocols=True)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ # The URL will be allowed into the command, but the command will
+ # fail since we don't have that protocol enabled in the Git config file.
+ with self.assertRaises(GitCommandError):
+ remote.pull(url, allow_unsafe_protocols=True)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_pull_unsafe_options(self, rw_repo):
- remote = rw_repo.remote("origin")
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
- for unsafe_option in unsafe_options:
- with self.assertRaises(UnsafeOptionError):
- remote.pull(**unsafe_option)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ remote = rw_repo.remote("origin")
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(UnsafeOptionError):
+ remote.pull(**unsafe_option)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_pull_unsafe_options_allowed(self, rw_repo):
- remote = rw_repo.remote("origin")
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
- for unsafe_option in unsafe_options:
- # The options will be allowed, but the command will fail.
- assert not tmp_file.exists()
- with self.assertRaises(GitCommandError):
- remote.pull(**unsafe_option, allow_unsafe_options=True)
- assert tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ remote = rw_repo.remote("origin")
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [{"upload-pack": f"touch {tmp_file}"}]
+ for unsafe_option in unsafe_options:
+ # The options will be allowed, but the command will fail.
+ assert not tmp_file.exists()
+ with self.assertRaises(GitCommandError):
+ remote.pull(**unsafe_option, allow_unsafe_options=True)
+ assert tmp_file.exists()
+ tmp_file.unlink()
@with_rw_repo("HEAD")
def test_push_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- remote.push(url)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ remote.push(url)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_push_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- remote = rw_repo.remote("origin")
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- # The URL will be allowed into the command, but the command will
- # fail since we don't have that protocol enabled in the Git config file.
- with self.assertRaises(GitCommandError):
- remote.push(url, allow_unsafe_protocols=True)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ remote = rw_repo.remote("origin")
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ # The URL will be allowed into the command, but the command will
+ # fail since we don't have that protocol enabled in the Git config file.
+ with self.assertRaises(GitCommandError):
+ remote.push(url, allow_unsafe_protocols=True)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_push_unsafe_options(self, rw_repo):
- remote = rw_repo.remote("origin")
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- {
- "receive-pack": f"touch {tmp_file}",
- "exec": f"touch {tmp_file}",
- }
- ]
- for unsafe_option in unsafe_options:
- assert not tmp_file.exists()
- with self.assertRaises(UnsafeOptionError):
- remote.push(**unsafe_option)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ remote = rw_repo.remote("origin")
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ {
+ "receive-pack": f"touch {tmp_file}",
+ "exec": f"touch {tmp_file}",
+ }
+ ]
+ for unsafe_option in unsafe_options:
+ assert not tmp_file.exists()
+ with self.assertRaises(UnsafeOptionError):
+ remote.push(**unsafe_option)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_push_unsafe_options_allowed(self, rw_repo):
- remote = rw_repo.remote("origin")
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- {
- "receive-pack": f"touch {tmp_file}",
- "exec": f"touch {tmp_file}",
- }
- ]
- for unsafe_option in unsafe_options:
- # The options will be allowed, but the command will fail.
- assert not tmp_file.exists()
- with self.assertRaises(GitCommandError):
- remote.push(**unsafe_option, allow_unsafe_options=True)
- assert tmp_file.exists()
- tmp_file.unlink()
+ with tempfile.TemporaryDirectory() as tdir:
+ remote = rw_repo.remote("origin")
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ {
+ "receive-pack": f"touch {tmp_file}",
+ "exec": f"touch {tmp_file}",
+ }
+ ]
+ for unsafe_option in unsafe_options:
+ # The options will be allowed, but the command will fail.
+ assert not tmp_file.exists()
+ with self.assertRaises(GitCommandError):
+ remote.push(**unsafe_option, allow_unsafe_options=True)
+ assert tmp_file.exists()
+ tmp_file.unlink()
class TestTimeouts(TestBase):
diff --git a/test/test_repo.py b/test/test_repo.py
index 5874dbe6..07c1e9ad 100644
--- a/test/test_repo.py
+++ b/test/test_repo.py
@@ -268,143 +268,176 @@ class TestRepo(TestBase):
@with_rw_repo("HEAD")
def test_clone_unsafe_options(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- for unsafe_option in unsafe_options:
- with self.assertRaises(UnsafeOptionError):
- rw_repo.clone(tmp_dir, multi_options=[unsafe_option])
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(UnsafeOptionError):
+ rw_repo.clone(tmp_dir, multi_options=[unsafe_option])
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_clone_unsafe_options_allowed(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- ]
- for i, unsafe_option in enumerate(unsafe_options):
- destination = tmp_dir / str(i)
- assert not tmp_file.exists()
- # The options will be allowed, but the command will fail.
- with self.assertRaises(GitCommandError):
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ ]
+ for i, unsafe_option in enumerate(unsafe_options):
+ destination = tmp_dir / str(i)
+ assert not tmp_file.exists()
+ # The options will be allowed, but the command will fail.
+ with self.assertRaises(GitCommandError):
+ rw_repo.clone(destination, multi_options=[unsafe_option], allow_unsafe_options=True)
+ assert tmp_file.exists()
+ tmp_file.unlink()
+
+ unsafe_options = [
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ for i, unsafe_option in enumerate(unsafe_options):
+ destination = tmp_dir / str(i)
+ assert not destination.exists()
rw_repo.clone(destination, multi_options=[unsafe_option], allow_unsafe_options=True)
- assert tmp_file.exists()
- tmp_file.unlink()
-
- unsafe_options = [
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- for i, unsafe_option in enumerate(unsafe_options):
- destination = tmp_dir / str(i)
- assert not destination.exists()
- rw_repo.clone(destination, multi_options=[unsafe_option], allow_unsafe_options=True)
- assert destination.exists()
+ assert destination.exists()
@with_rw_repo("HEAD")
def test_clone_safe_options(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- options = [
- "--depth=1",
- "--single-branch",
- "-q",
- ]
- for option in options:
- destination = tmp_dir / option
- assert not destination.exists()
- rw_repo.clone(destination, multi_options=[option])
- assert destination.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ options = [
+ "--depth=1",
+ "--single-branch",
+ "-q",
+ ]
+ for option in options:
+ destination = tmp_dir / option
+ assert not destination.exists()
+ rw_repo.clone(destination, multi_options=[option])
+ assert destination.exists()
@with_rw_repo("HEAD")
def test_clone_from_unsafe_options(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- for unsafe_option in unsafe_options:
- with self.assertRaises(UnsafeOptionError):
- Repo.clone_from(rw_repo.working_dir, tmp_dir, multi_options=[unsafe_option])
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(UnsafeOptionError):
+ Repo.clone_from(rw_repo.working_dir, tmp_dir, multi_options=[unsafe_option])
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_clone_from_unsafe_options_allowed(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- ]
- for i, unsafe_option in enumerate(unsafe_options):
- destination = tmp_dir / str(i)
- assert not tmp_file.exists()
- # The options will be allowed, but the command will fail.
- with self.assertRaises(GitCommandError):
- Repo.clone_from(
- rw_repo.working_dir, destination, multi_options=[unsafe_option], allow_unsafe_options=True
- )
- assert tmp_file.exists()
- tmp_file.unlink()
-
- unsafe_options = [
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- for i, unsafe_option in enumerate(unsafe_options):
- destination = tmp_dir / str(i)
- assert not destination.exists()
- Repo.clone_from(rw_repo.working_dir, destination, multi_options=[unsafe_option], allow_unsafe_options=True)
- assert destination.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ ]
+ for i, unsafe_option in enumerate(unsafe_options):
+ destination = tmp_dir / str(i)
+ assert not tmp_file.exists()
+ # The options will be allowed, but the command will fail.
+ with self.assertRaises(GitCommandError):
+ Repo.clone_from(
+ rw_repo.working_dir, destination, multi_options=[unsafe_option], allow_unsafe_options=True
+ )
+ assert tmp_file.exists()
+ tmp_file.unlink()
+
+ unsafe_options = [
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ for i, unsafe_option in enumerate(unsafe_options):
+ destination = tmp_dir / str(i)
+ assert not destination.exists()
+ Repo.clone_from(rw_repo.working_dir, destination, multi_options=[unsafe_option], allow_unsafe_options=True)
+ assert destination.exists()
@with_rw_repo("HEAD")
def test_clone_from_safe_options(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- options = [
- "--depth=1",
- "--single-branch",
- "-q",
- ]
- for option in options:
- destination = tmp_dir / option
- assert not destination.exists()
- Repo.clone_from(rw_repo.common_dir, destination, multi_options=[option])
- assert destination.exists()
-
- def test_clone_from_unsafe_procol(self):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::17/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- Repo.clone_from(url, tmp_dir)
- assert not tmp_file.exists()
-
- def test_clone_from_unsafe_procol_allowed(self):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- "ext::sh -c touch% /tmp/pwn",
- "fd::/foo",
- ]
- for url in urls:
- # The URL will be allowed into the command, but the command will
- # fail since we don't have that protocol enabled in the Git config file.
- with self.assertRaises(GitCommandError):
- Repo.clone_from(url, tmp_dir, allow_unsafe_protocols=True)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ options = [
+ "--depth=1",
+ "--single-branch",
+ "-q",
+ ]
+ for option in options:
+ destination = tmp_dir / option
+ assert not destination.exists()
+ Repo.clone_from(rw_repo.common_dir, destination, multi_options=[option])
+ assert destination.exists()
+
+ def test_clone_from_unsafe_protocol(self):
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::17/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ Repo.clone_from(url, tmp_dir / "repo")
+ assert not tmp_file.exists()
+
+ def test_clone_from_unsafe_protocol_allowed(self):
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::/foo",
+ ]
+ for url in urls:
+ # The URL will be allowed into the command, but the command will
+ # fail since we don't have that protocol enabled in the Git config file.
+ with self.assertRaises(GitCommandError):
+ Repo.clone_from(url, tmp_dir / "repo", allow_unsafe_protocols=True)
+ assert not tmp_file.exists()
+
+ def test_clone_from_unsafe_protocol_allowed_and_enabled(self):
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ ]
+ allow_ext = [
+ "--config=protocol.ext.allow=always",
+ ]
+ for url in urls:
+ # The URL will be allowed into the command, and the protocol is enabled,
+ # but the command will fail since it can't read from the remote repo.
+ assert not tmp_file.exists()
+ with self.assertRaises(GitCommandError):
+ Repo.clone_from(
+ url,
+ tmp_dir / "repo",
+ multi_options=allow_ext,
+ allow_unsafe_protocols=True,
+ allow_unsafe_options=True,
+ )
+ assert tmp_file.exists()
+ tmp_file.unlink()
@with_rw_repo("HEAD")
def test_max_chunk_size(self, repo):
@@ -1326,26 +1359,55 @@ class TestRepo(TestBase):
@with_rw_repo("HEAD")
def test_clone_command_injection(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- unexpected_file = tmp_dir / "pwn"
- assert not unexpected_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ unexpected_file = tmp_dir / "pwn"
+ assert not unexpected_file.exists()
- payload = f"--upload-pack=touch {unexpected_file}"
- rw_repo.clone(payload)
+ payload = f"--upload-pack=touch {unexpected_file}"
+ rw_repo.clone(payload)
- assert not unexpected_file.exists()
- # A repo was cloned with the payload as name
- assert pathlib.Path(payload).exists()
+ assert not unexpected_file.exists()
+ # A repo was cloned with the payload as name
+ assert pathlib.Path(payload).exists()
@with_rw_repo("HEAD")
def test_clone_from_command_injection(self, rw_repo):
- tmp_dir = pathlib.Path(tempfile.mkdtemp())
- temp_repo = Repo.init(tmp_dir / "repo")
- unexpected_file = tmp_dir / "pwn"
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ temp_repo = Repo.init(tmp_dir / "repo")
+ unexpected_file = tmp_dir / "pwn"
+
+ assert not unexpected_file.exists()
+ payload = f"--upload-pack=touch {unexpected_file}"
+ with self.assertRaises(GitCommandError):
+ rw_repo.clone_from(payload, temp_repo.common_dir)
+
+ assert not unexpected_file.exists()
+
+ def test_ignored_items_reported(self):
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ temp_repo = Repo.init(tmp_dir / "repo")
+
+ gi = tmp_dir / "repo" / ".gitignore"
+
+ with open(gi, 'w') as file:
+ file.write('ignored_file.txt\n')
+ file.write('ignored_dir/\n')
+
+ assert temp_repo.ignored(['included_file.txt', 'included_dir/file.txt']) == []
+ assert temp_repo.ignored(['ignored_file.txt']) == ['ignored_file.txt']
+ assert temp_repo.ignored(['included_file.txt', 'ignored_file.txt']) == ['ignored_file.txt']
+ assert temp_repo.ignored(['included_file.txt', 'ignored_file.txt', 'included_dir/file.txt', 'ignored_dir/file.txt']) == ['ignored_file.txt', 'ignored_dir/file.txt']
+
+ def test_ignored_raises_error_w_symlink(self):
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = pathlib.Path(tdir)
+ temp_repo = Repo.init(tmp_dir / "repo")
- assert not unexpected_file.exists()
- payload = f"--upload-pack=touch {unexpected_file}"
- with self.assertRaises(GitCommandError):
- rw_repo.clone_from(payload, temp_repo.common_dir)
+ os.mkdir(tmp_dir / "target")
+ os.symlink(tmp_dir / "target", tmp_dir / "symlink")
- assert not unexpected_file.exists()
+ with pytest.raises(GitCommandError):
+ temp_repo.ignored(tmp_dir / "symlink/file.txt") \ No newline at end of file
diff --git a/test/test_submodule.py b/test/test_submodule.py
index 13878df2..98222641 100644
--- a/test/test_submodule.py
+++ b/test/test_submodule.py
@@ -1101,139 +1101,147 @@ class TestSubmodule(TestBase):
@with_rw_repo("HEAD")
def test_submodule_add_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::/foo",
- ]
- for url in urls:
- with self.assertRaises(UnsafeProtocolError):
- Submodule.add(rw_repo, "new", "new", url)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::/foo",
+ ]
+ for url in urls:
+ with self.assertRaises(UnsafeProtocolError):
+ Submodule.add(rw_repo, "new", "new", url)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_submodule_add_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::/foo",
- ]
- for url in urls:
- # The URL will be allowed into the command, but the command will
- # fail since we don't have that protocol enabled in the Git config file.
- with self.assertRaises(GitCommandError):
- Submodule.add(rw_repo, "new", "new", url, allow_unsafe_protocols=True)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::/foo",
+ ]
+ for url in urls:
+ # The URL will be allowed into the command, but the command will
+ # fail since we don't have that protocol enabled in the Git config file.
+ with self.assertRaises(GitCommandError):
+ Submodule.add(rw_repo, "new", "new", url, allow_unsafe_protocols=True)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_submodule_add_unsafe_options(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- for unsafe_option in unsafe_options:
- with self.assertRaises(UnsafeOptionError):
- Submodule.add(rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option])
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(UnsafeOptionError):
+ Submodule.add(rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option])
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_submodule_add_unsafe_options_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- ]
- for unsafe_option in unsafe_options:
- # The options will be allowed, but the command will fail.
- with self.assertRaises(GitCommandError):
- Submodule.add(
- rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option], allow_unsafe_options=True
- )
- assert not tmp_file.exists()
-
- unsafe_options = [
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- for unsafe_option in unsafe_options:
- with self.assertRaises(GitCommandError):
- Submodule.add(
- rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option], allow_unsafe_options=True
- )
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ ]
+ for unsafe_option in unsafe_options:
+ # The options will be allowed, but the command will fail.
+ with self.assertRaises(GitCommandError):
+ Submodule.add(
+ rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option], allow_unsafe_options=True
+ )
+ assert not tmp_file.exists()
+
+ unsafe_options = [
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(GitCommandError):
+ Submodule.add(
+ rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option], allow_unsafe_options=True
+ )
@with_rw_repo("HEAD")
def test_submodule_update_unsafe_url(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::/foo",
- ]
- for url in urls:
- submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=url)
- with self.assertRaises(UnsafeProtocolError):
- submodule.update()
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::/foo",
+ ]
+ for url in urls:
+ submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=url)
+ with self.assertRaises(UnsafeProtocolError):
+ submodule.update()
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_submodule_update_unsafe_url_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- urls = [
- f"ext::sh -c touch% {tmp_file}",
- "fd::/foo",
- ]
- for url in urls:
- submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=url)
- # The URL will be allowed into the command, but the command will
- # fail since we don't have that protocol enabled in the Git config file.
- with self.assertRaises(GitCommandError):
- submodule.update(allow_unsafe_protocols=True)
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ urls = [
+ f"ext::sh -c touch% {tmp_file}",
+ "fd::/foo",
+ ]
+ for url in urls:
+ submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=url)
+ # The URL will be allowed into the command, but the command will
+ # fail since we don't have that protocol enabled in the Git config file.
+ with self.assertRaises(GitCommandError):
+ submodule.update(allow_unsafe_protocols=True)
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_submodule_update_unsafe_options(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))
- for unsafe_option in unsafe_options:
- with self.assertRaises(UnsafeOptionError):
- submodule.update(clone_multi_options=[unsafe_option])
- assert not tmp_file.exists()
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(UnsafeOptionError):
+ submodule.update(clone_multi_options=[unsafe_option])
+ assert not tmp_file.exists()
@with_rw_repo("HEAD")
def test_submodule_update_unsafe_options_allowed(self, rw_repo):
- tmp_dir = Path(tempfile.mkdtemp())
- tmp_file = tmp_dir / "pwn"
- unsafe_options = [
- f"--upload-pack='touch {tmp_file}'",
- f"-u 'touch {tmp_file}'",
- ]
- submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))
- for unsafe_option in unsafe_options:
- # The options will be allowed, but the command will fail.
- with self.assertRaises(GitCommandError):
- submodule.update(clone_multi_options=[unsafe_option], allow_unsafe_options=True)
- assert not tmp_file.exists()
-
- unsafe_options = [
- "--config=protocol.ext.allow=always",
- "-c protocol.ext.allow=always",
- ]
- submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))
- for unsafe_option in unsafe_options:
- with self.assertRaises(GitCommandError):
- submodule.update(clone_multi_options=[unsafe_option], allow_unsafe_options=True)
+ with tempfile.TemporaryDirectory() as tdir:
+ tmp_dir = Path(tdir)
+ tmp_file = tmp_dir / "pwn"
+ unsafe_options = [
+ f"--upload-pack='touch {tmp_file}'",
+ f"-u 'touch {tmp_file}'",
+ ]
+ submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))
+ for unsafe_option in unsafe_options:
+ # The options will be allowed, but the command will fail.
+ with self.assertRaises(GitCommandError):
+ submodule.update(clone_multi_options=[unsafe_option], allow_unsafe_options=True)
+ assert not tmp_file.exists()
+
+ unsafe_options = [
+ "--config=protocol.ext.allow=always",
+ "-c protocol.ext.allow=always",
+ ]
+ submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))
+ for unsafe_option in unsafe_options:
+ with self.assertRaises(GitCommandError):
+ submodule.update(clone_multi_options=[unsafe_option], allow_unsafe_options=True)
diff --git a/test/test_util.py b/test/test_util.py
index 90dd89a9..c17efce3 100644
--- a/test/test_util.py
+++ b/test/test_util.py
@@ -333,6 +333,27 @@ class TestUtils(TestBase):
self.assertRaises(IndexError, ilist.__delitem__, 0)
self.assertRaises(IndexError, ilist.__delitem__, "something")
+ def test_utctz_to_altz(self):
+ self.assertEqual(utctz_to_altz("+0000"), 0)
+ self.assertEqual(utctz_to_altz("+1400"), -(14 * 3600))
+ self.assertEqual(utctz_to_altz("-1200"), 12 * 3600)
+ self.assertEqual(utctz_to_altz("+0001"), -60)
+ self.assertEqual(utctz_to_altz("+0530"), -(5 * 3600 + 1800))
+ self.assertEqual(utctz_to_altz("-0930"), 9 * 3600 + 1800)
+
+ def test_altz_to_utctz_str(self):
+ self.assertEqual(altz_to_utctz_str(0), "+0000")
+ self.assertEqual(altz_to_utctz_str(-(14 * 3600)), "+1400")
+ self.assertEqual(altz_to_utctz_str(12 * 3600), "-1200")
+ self.assertEqual(altz_to_utctz_str(-60), "+0001")
+ self.assertEqual(altz_to_utctz_str(-(5 * 3600 + 1800)), "+0530")
+ self.assertEqual(altz_to_utctz_str(9 * 3600 + 1800), "-0930")
+
+ self.assertEqual(altz_to_utctz_str(1), "+0000")
+ self.assertEqual(altz_to_utctz_str(59), "+0000")
+ self.assertEqual(altz_to_utctz_str(-1), "+0000")
+ self.assertEqual(altz_to_utctz_str(-59), "+0000")
+
def test_from_timestamp(self):
# Correct offset: UTC+2, should return datetime + tzoffset(+2)
altz = utctz_to_altz("+0200")