diff options
author | Vincent Driessen <me@nvie.com> | 2016-04-19 21:35:39 +0200 |
---|---|---|
committer | Vincent Driessen <me@nvie.com> | 2016-04-19 21:35:39 +0200 |
commit | 4adafc5a99947301ca0ce40511991d6d54c57a41 (patch) | |
tree | e7cf8a66b178baf8fa4fcfddc46f2134c48042ab | |
parent | 76e19e4221684f24ef881415ec6ccb6bab6eb8e8 (diff) | |
parent | 3297fe50067da728eb6f3f47764efb223e0d6ea4 (diff) | |
download | gitpython-4adafc5a99947301ca0ce40511991d6d54c57a41.tar.gz |
Merge pull request #408 from nvie/master
Add support for diffing against root commit
-rw-r--r-- | doc/source/changes.rst | 3 | ||||
-rw-r--r-- | git/compat.py | 14 | ||||
-rw-r--r-- | git/diff.py | 21 | ||||
-rw-r--r-- | git/repo/base.py | 2 | ||||
-rw-r--r-- | git/test/fixtures/diff_initial | 10 | ||||
-rw-r--r-- | git/test/test_diff.py | 20 | ||||
-rw-r--r-- | tox.ini | 3 |
7 files changed, 55 insertions, 18 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 23954c7f..4fdf39ca 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -4,6 +4,9 @@ Changelog 1.0.3 - Fixes ============= + +* `Commit.diff()` now supports diffing the root commit via `Commit.diff(NULL_TREE)`. +* `Repo.blame()` now respects `incremental=True`, supporting incremental blames. Incremental blames are slightly faster since they don't include the file's contents in them. * IMPORTANT: This release drops support for python 2.6, which is officially deprecated by the python maintainers. 1.0.2 - Fixes diff --git a/git/compat.py b/git/compat.py index 146bfd4b..7bd8e494 100644 --- a/git/compat.py +++ b/git/compat.py @@ -8,7 +8,6 @@ # flake8: noqa import sys -import six from gitdb.utils.compat import ( PY3, @@ -34,6 +33,7 @@ if PY3: return bytes([n]) def mviter(d): return d.values() + range = xrange unicode = str else: FileType = file @@ -44,21 +44,17 @@ else: byte_ord = ord bchr = chr unicode = unicode + range = xrange def mviter(d): return d.itervalues() -PRE_PY27 = sys.version_info < (2, 7) - def safe_decode(s): """Safely decodes a binary string to unicode""" - if isinstance(s, six.text_type): + if isinstance(s, unicode): return s - elif isinstance(s, six.binary_type): - if PRE_PY27: - return s.decode(defenc) # we're screwed - else: - return s.decode(defenc, errors='replace') + elif isinstance(s, bytes): + return s.decode(defenc, errors='replace') raise TypeError('Expected bytes or text, but got %r' % (s,)) diff --git a/git/diff.py b/git/diff.py index 062220df..de3aa1e8 100644 --- a/git/diff.py +++ b/git/diff.py @@ -16,7 +16,10 @@ from git.compat import ( ) -__all__ = ('Diffable', 'DiffIndex', 'Diff') +__all__ = ('Diffable', 'DiffIndex', 'Diff', 'NULL_TREE') + +# Special object to compare against the empty tree in diffs +NULL_TREE = object() class Diffable(object): @@ -49,6 +52,7 @@ class Diffable(object): If None, we will be compared to the working tree. If Treeish, it will be compared against the respective tree If Index ( type ), it will be compared against the index. + If git.NULL_TREE, it will compare against the empty tree. It defaults to Index to assure the method will not by-default fail on bare repositories. @@ -87,10 +91,17 @@ class Diffable(object): if paths is not None and not isinstance(paths, (tuple, list)): paths = [paths] - if other is not None and other is not self.Index: - args.insert(0, other) + diff_cmd = self.repo.git.diff if other is self.Index: - args.insert(0, "--cached") + args.insert(0, '--cached') + elif other is NULL_TREE: + args.insert(0, '-r') # recursive diff-tree + args.insert(0, '--root') + diff_cmd = self.repo.git.diff_tree + elif other is not None: + args.insert(0, '-r') # recursive diff-tree + args.insert(0, other) + diff_cmd = self.repo.git.diff_tree args.insert(0, self) @@ -101,7 +112,7 @@ class Diffable(object): # END paths handling kwargs['as_process'] = True - proc = self.repo.git.diff(*self._process_diff_args(args), **kwargs) + proc = diff_cmd(*self._process_diff_args(args), **kwargs) diff_method = Diff._index_from_raw_format if create_patch: diff --git a/git/repo/base.py b/git/repo/base.py index 9d013230..f74e0b59 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -54,12 +54,12 @@ from git.compat import ( defenc, PY3, safe_decode, + range, ) import os import sys import re -from six.moves import range DefaultDBType = GitCmdObjectDB if sys.version_info[:2] < (2, 5): # python 2.4 compatiblity diff --git a/git/test/fixtures/diff_initial b/git/test/fixtures/diff_initial new file mode 100644 index 00000000..6037c677 --- /dev/null +++ b/git/test/fixtures/diff_initial @@ -0,0 +1,10 @@ +--- /dev/null ++++ b/CHANGES +@@ -0,0 +1,7 @@ ++======= ++CHANGES ++======= ++ ++0.1.0 ++===== ++initial release diff --git a/git/test/test_diff.py b/git/test/test_diff.py index b0d98248..56e395fd 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -21,7 +21,8 @@ from git import ( Repo, GitCommandError, Diff, - DiffIndex + DiffIndex, + NULL_TREE, ) @@ -128,6 +129,21 @@ class TestDiff(TestBase): assert res[0].deleted_file assert res[0].b_path == '' + def test_diff_initial_commit(self): + initial_commit = self.rorepo.commit('33ebe7acec14b25c5f84f35a664803fcab2f7781') + + # Without creating a patch... + diff_index = initial_commit.diff(NULL_TREE) + assert diff_index[0].b_path == 'CHANGES' + assert diff_index[0].new_file + assert diff_index[0].diff == '' + + # ...and with creating a patch + diff_index = initial_commit.diff(NULL_TREE, create_patch=True) + assert diff_index[0].b_path == 'CHANGES' + assert diff_index[0].new_file + assert diff_index[0].diff == fixture('diff_initial') + def test_diff_patch_format(self): # test all of the 'old' format diffs for completness - it should at least # be able to deal with it @@ -149,7 +165,7 @@ class TestDiff(TestBase): diff_item = commit.tree # END use tree every second item - for other in (None, commit.Index, commit.parents[0]): + for other in (None, NULL_TREE, commit.Index, commit.parents[0]): for paths in (None, "CHANGES", ("CHANGES", "lib")): for create_patch in range(2): diff_index = diff_item.diff(other=other, paths=paths, create_patch=create_patch) @@ -1,10 +1,11 @@ [tox] -envlist = py26,py27,py33,py34,flake8 +envlist = py26,py27,py33,py34,py35,flake8 [testenv] commands = nosetests {posargs} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt +passenv = HOME [testenv:cover] commands = nosetests --with-coverage {posargs} |