From 200d3c6cb436097eaee7c951a0c9921bfcb75c7f Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Mon, 6 Jun 2016 12:13:37 +0200 Subject: Don't choke on (legitimately) invalidly encoded Unicode paths --- git/test/fixtures/diff_patch_unsafe_paths | 7 +++++++ git/test/test_diff.py | 13 +++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'git/test') diff --git a/git/test/fixtures/diff_patch_unsafe_paths b/git/test/fixtures/diff_patch_unsafe_paths index 9ee6b834..1aad6754 100644 --- a/git/test/fixtures/diff_patch_unsafe_paths +++ b/git/test/fixtures/diff_patch_unsafe_paths @@ -68,6 +68,13 @@ index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94 +++ "b/path/\360\237\222\251.txt" @@ -0,0 +1 @@ +dummy content +diff --git "a/path/\200-invalid-unicode-path.txt" "b/path/\200-invalid-unicode-path.txt" +new file mode 100644 +index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54 +--- /dev/null ++++ "b/path/\200-invalid-unicode-path.txt" +@@ -0,0 +1 @@ ++dummy content diff --git a/a/with spaces b/b/with some spaces similarity index 100% rename from a/with spaces diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 8966351a..8d189b12 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -162,16 +162,17 @@ class TestDiff(TestBase): self.assertEqual(res[7].b_path, u'path/with-question-mark?') self.assertEqual(res[8].b_path, u'path/¯\\_(ツ)_|¯') self.assertEqual(res[9].b_path, u'path/💩.txt') + self.assertEqual(res[10].b_path, u'path/�-invalid-unicode-path.txt') # The "Moves" # NOTE: The path prefixes a/ and b/ here are legit! We're actually # verifying that it's not "a/a/" that shows up, see the fixture data. - self.assertEqual(res[10].a_path, u'a/with spaces') # NOTE: path a/ here legit! - self.assertEqual(res[10].b_path, u'b/with some spaces') # NOTE: path b/ here legit! - self.assertEqual(res[11].a_path, u'a/ending in a space ') - self.assertEqual(res[11].b_path, u'b/ending with space ') - self.assertEqual(res[12].a_path, u'a/"with-quotes"') - self.assertEqual(res[12].b_path, u'b/"with even more quotes"') + self.assertEqual(res[11].a_path, u'a/with spaces') # NOTE: path a/ here legit! + self.assertEqual(res[11].b_path, u'b/with some spaces') # NOTE: path b/ here legit! + self.assertEqual(res[12].a_path, u'a/ending in a space ') + self.assertEqual(res[12].b_path, u'b/ending with space ') + self.assertEqual(res[13].a_path, u'a/"with-quotes"') + self.assertEqual(res[13].b_path, u'b/"with even more quotes"') def test_diff_patch_format(self): # test all of the 'old' format diffs for completness - it should at least -- cgit v1.2.1 From b366d3fabd79e921e30b44448cb357a05730c42f Mon Sep 17 00:00:00 2001 From: Guyzmo Date: Thu, 26 May 2016 20:43:28 +0200 Subject: Adding support for git remote set-url/get-url API to Remote MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both commands enable handling of a little known feature of git, which is to support multiple URL for one remote. You can add multiple url using the `set_url` subcommand of `git remote`. As listing them is also handy, there's a nice method to do it, using `get_url`. * adding set_url method that maps to the git remote set-url command¶ * can be used to set an URL, or replace an URL with optional positional arg¶ * can be used to add, delete URL with kwargs (matching set-url options)¶ * adding add_url, delete_url methods that wraps around set_url for conveniency¶ * adding urls property that yields an iterator over the setup urls for a remote¶ * adding a test suite that checks all use case scenarii of this added API.¶ Signed-off-by: Guyzmo --- git/test/test_remote.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'git/test') diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 9ca2f207..3c2e622d 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -9,7 +9,8 @@ from git.test.lib import ( with_rw_repo, with_rw_and_rw_remote_repo, fixture, - GIT_DAEMON_PORT + GIT_DAEMON_PORT, + assert_raises ) from git import ( RemoteProgress, @@ -62,7 +63,7 @@ class TestRemoteProgress(RemoteProgress): # check each stage only comes once op_id = op_code & self.OP_MASK assert op_id in (self.COUNTING, self.COMPRESSING, self.WRITING) - + if op_code & self.WRITING > 0: if op_code & self.BEGIN > 0: assert not message, 'should not have message when remote begins writing' @@ -568,3 +569,47 @@ class TestRemote(TestBase): assert res[0].remote_ref_path == 'refs/pull/1/head' assert res[0].ref.path == 'refs/heads/pull/1/head' assert isinstance(res[0].ref, Head) + + @with_rw_repo('HEAD', bare=False) + def test_multiple_urls(self, rw_repo): + # test addresses + test1 = 'https://github.com/gitpython-developers/GitPython' + test2 = 'https://github.com/gitpython-developers/gitdb' + test3 = 'https://github.com/gitpython-developers/smmap' + + remote = rw_repo.remotes[0] + # Testing setting a single URL + remote.set_url(test1) + assert list(remote.urls) == [test1] + + # Testing replacing that single URL + remote.set_url(test1) + assert list(remote.urls) == [test1] + # Testing adding new URLs + remote.set_url(test2, add=True) + assert list(remote.urls) == [test1, test2] + remote.set_url(test3, add=True) + assert list(remote.urls) == [test1, test2, test3] + # Testing removing an URL + remote.set_url(test2, delete=True) + assert list(remote.urls) == [test1, test3] + # Testing changing an URL + remote.set_url(test3, test2) + assert list(remote.urls) == [test1, test2] + + # will raise: fatal: --add --delete doesn't make sense + assert_raises(GitCommandError, remote.set_url, test2, add=True, delete=True) + + # Testing on another remote, with the add/delete URL + remote = rw_repo.create_remote('another', url=test1) + remote.add_url(test2) + assert list(remote.urls) == [test1, test2] + remote.add_url(test3) + assert list(remote.urls) == [test1, test2, test3] + # Testing removing all the URLs + remote.delete_url(test2) + assert list(remote.urls) == [test1, test3] + remote.delete_url(test1) + assert list(remote.urls) == [test3] + # will raise fatal: Will not delete all non-push URLs + assert_raises(GitCommandError, remote.delete_url, test3) -- cgit v1.2.1 From 27f394a58b7795303926cd2f7463fc7187e1cce4 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 14 Jun 2016 07:41:59 +0200 Subject: fix(test_docs): skip master-dependent assertion It usually fails on branches, which doesn't help assessing PRs. --- git/test/test_docs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'git/test') diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 8dc08559..a4604c58 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -64,7 +64,9 @@ class Tutorials(TestBase): assert repo.head.ref == repo.heads.master # head is a symbolic reference pointing to master assert repo.tags['0.3.5'] == repo.tag('refs/tags/0.3.5') # you can access tags in various ways too assert repo.refs.master == repo.heads['master'] # .refs provides access to all refs, i.e. heads ... - assert repo.refs['origin/master'] == repo.remotes.origin.refs.master # ... remotes ... + + if 'TRAVIS' not in os.environ: + assert repo.refs['origin/master'] == repo.remotes.origin.refs.master # ... remotes ... assert repo.refs['0.3.5'] == repo.tags['0.3.5'] # ... and tags # ![8-test_init_repo_object] -- cgit v1.2.1 From 3ee291c469fc7ea6065ed22f344ed3f2792aa2ca Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Tue, 14 Jun 2016 22:44:11 +0200 Subject: Store raw path bytes in Diff instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the following fields on Diff instances were assumed to be passed in as unicode strings: - `a_path` - `b_path` - `rename_from` - `rename_to` However, since Git natively records paths as bytes, these may potentially not have a valid unicode representation. This patch changes the Diff instance to instead take the following equivalent fields that should be raw bytes instead: - `a_rawpath` - `b_rawpath` - `raw_rename_from` - `raw_rename_to` NOTE ON BACKWARD COMPATIBILITY: The original `a_path`, `b_path`, etc. fields are still available as properties (rather than slots). These properties now dynamically decode the raw bytes into a unicode string (performing the potentially destructive operation of replacing invalid unicode chars by "�"'s). This means that all code using Diffs should remain backward compatible. The only exception is when people would manually construct Diff instances by calling the constructor directly, in which case they should now pass in bytes rather than unicode strings. See also the discussion on https://github.com/gitpython-developers/GitPython/pull/467 --- git/test/test_diff.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'git/test') diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 8d189b12..ba0d2d13 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -90,6 +90,8 @@ class TestDiff(TestBase): assert_true(diff.renamed) assert_equal(diff.rename_from, u'Jérôme') assert_equal(diff.rename_to, u'müller') + assert_equal(diff.raw_rename_from, b'J\xc3\xa9r\xc3\xb4me') + assert_equal(diff.raw_rename_to, b'm\xc3\xbcller') assert isinstance(str(diff), str) output = StringProcessAdapter(fixture('diff_rename_raw')) @@ -129,7 +131,7 @@ class TestDiff(TestBase): output = StringProcessAdapter(fixture('diff_index_raw')) res = Diff._index_from_raw_format(None, output.stdout) assert res[0].deleted_file - assert res[0].b_path == '' + assert res[0].b_path is None def test_diff_initial_commit(self): initial_commit = self.rorepo.commit('33ebe7acec14b25c5f84f35a664803fcab2f7781') @@ -162,7 +164,9 @@ class TestDiff(TestBase): self.assertEqual(res[7].b_path, u'path/with-question-mark?') self.assertEqual(res[8].b_path, u'path/¯\\_(ツ)_|¯') self.assertEqual(res[9].b_path, u'path/💩.txt') + self.assertEqual(res[9].b_rawpath, b'path/\xf0\x9f\x92\xa9.txt') self.assertEqual(res[10].b_path, u'path/�-invalid-unicode-path.txt') + self.assertEqual(res[10].b_rawpath, b'path/\x80-invalid-unicode-path.txt') # The "Moves" # NOTE: The path prefixes a/ and b/ here are legit! We're actually -- cgit v1.2.1