summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>2012-07-13 10:06:23 +0300
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>2013-04-03 09:13:50 +0300
commitc49f51548e78b78b35c6e86c395784f82c5c51c3 (patch)
treeca6f5b7487359cd201179baac59b37a15d1c5a8b
parentea352511b6bf49029777ab4d033f4d5cf0c7a29f (diff)
downloadgit-buildpackage-c49f51548e78b78b35c6e86c395784f82c5c51c3.tar.gz
git-buildpackage-c49f51548e78b78b35c6e86c395784f82c5c51c3.tar.bz2
git-buildpackage-c49f51548e78b78b35c6e86c395784f82c5c51c3.zip
GitRepository: add format_patch method
A method for generating one patch, with the possibility to filter the git patch through a python function. Always generates textual diffs as the 'patch' utility doesn't support git binary diffs. Ignore changes to submodules in patch generation as these diffs cannot be applied by the patch utility when building packages. TODO: convert all code to use the new format_patch() and get rid of the format_patches() method. Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
-rw-r--r--gbp/git/repository.py43
-rw-r--r--tests/test_GitRepository.py28
2 files changed, 71 insertions, 0 deletions
diff --git a/gbp/git/repository.py b/gbp/git/repository.py
index c57f81ff..a1369f14 100644
--- a/gbp/git/repository.py
+++ b/gbp/git/repository.py
@@ -1481,6 +1481,49 @@ class GitRepository(object):
output, ret = self._git_getoutput('format-patch', options.args)
return [ line.strip() for line in output ]
+ def format_patch(self, commit, output, signature=True, paths=None,
+ filter_fn=None, filter_args={}):
+ """
+ Create patch of a single commit
+
+ @param commit: commit to create patch from
+ @type commit: C{str}
+ @param output: path/filename of the patch file to be generated
+ @type output: C{str}
+ @param signature: add signature to the end of patch
+ @type signature: C{bool}
+ @param paths: only list commits touching paths
+ @type paths: C{list} of C{str}
+ @return: patch path/filename or None if no patch was generated
+ @param filter_fn: python function for filtering the stdout
+ @type filter_fn: C{function}
+ @param filter_args: arguments to pass to the filter fn
+ @type filter_args: C{dict}
+ @rtype: C{str}
+ """
+ args = GitArgs('-k', '--stdout', '-a', '--ignore-submodules')
+ args.add_cond(not signature, '--no-signature')
+ args.add('%s^!' % commit)
+ if paths:
+ args.add('--', paths)
+
+ try:
+ output_dir = os.path.dirname(output)
+ if output_dir and not os.path.exists(output_dir):
+ os.mkdir(output_dir)
+ except OSError as err:
+ raise GitRepositoryError("Unable to create patch directory" % err)
+
+ with open(output, 'w') as f_out:
+ dummy, stderr, ret = self._git_inout('format-patch', args.args,
+ output_f=f_out,
+ filter_fn=filter_fn,
+ filter_kwargs=filter_args)
+ if os.path.getsize(output) == 0:
+ os.unlink(output)
+ output = None
+ return output
+
def apply_patch(self, patch, index=True, context=None, strip=None):
"""Apply a patch using git apply"""
args = []
diff --git a/tests/test_GitRepository.py b/tests/test_GitRepository.py
index 3cacf897..bc9d87a3 100644
--- a/tests/test_GitRepository.py
+++ b/tests/test_GitRepository.py
@@ -430,6 +430,34 @@ def test_get_commit_info():
defaultdict(<type 'list'>, {'M': ['testfile']})
"""
+def test_format_patch():
+ """
+ Test generating of single patch
+
+ Methods tested:
+ - L{gbp.git.GitRepository.format_patch}
+
+ >>> import os
+ >>> import filecmp
+ >>> import gbp.git
+ >>> repo = gbp.git.GitRepository(repo_dir)
+ >>> repo.format_patch("HEAD", "foo.patch", signature=False)
+ 'foo.patch'
+ >>> repo.format_patch("HEAD", "foo2.patch", signature=False, paths="testfile")
+ 'foo2.patch'
+ >>> repo.format_patch("HEAD", "foo3.patch", signature=False, paths="filenotexists")
+ >>> os.path.getsize("foo.patch") > 300
+ True
+ >>> os.path.getsize("foo2.patch") > 300
+ True
+ >>> filecmp.cmp("foo.patch", "foo2.patch")
+ True
+ >>> os.path.exists("foo3.patch")
+ False
+ >>> os.unlink("foo.patch")
+ >>> os.unlink("foo2.patch")
+ """
+
def test_diff():
"""
Test git-diff