summaryrefslogtreecommitdiff
path: root/git
diff options
context:
space:
mode:
authorLars Kellogg-Stedman <lars@oddbit.com>2021-02-15 18:24:28 -0500
committerLars Kellogg-Stedman <lars@oddbit.com>2021-02-15 19:50:12 -0500
commit36811a2edc410589b5fde4d47d8d3a8a69d995ae (patch)
tree29ae8aba585cad35926f7cf812418e2d83b9bfba /git
parente1cd58ba862cce9cd9293933acd70b1a12feb5a8 (diff)
downloadgitpython-36811a2edc410589b5fde4d47d8d3a8a69d995ae.tar.gz
add replace method to git.Commit
This adds a replace method to git.Commit. The replace method returns a copy of the Commit object with attributes replaced from keyword arguments. For example: >>> old = repo.head.commit >>> new = old.replace(message='This is a test') closes #1123
Diffstat (limited to 'git')
-rw-r--r--git/objects/commit.py43
1 files changed, 36 insertions, 7 deletions
diff --git a/git/objects/commit.py b/git/objects/commit.py
index 302798cb..45e6d772 100644
--- a/git/objects/commit.py
+++ b/git/objects/commit.py
@@ -136,6 +136,41 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
def _get_intermediate_items(cls, commit):
return commit.parents
+ @classmethod
+ def _calculate_sha_(cls, repo, commit):
+ '''Calculate the sha of a commit.
+
+ :param repo: Repo object the commit should be part of
+ :param commit: Commit object for which to generate the sha
+ '''
+
+ stream = BytesIO()
+ commit._serialize(stream)
+ streamlen = stream.tell()
+ stream.seek(0)
+
+ istream = repo.odb.store(IStream(cls.type, streamlen, stream))
+ return istream.binsha
+
+ def replace(self, **kwargs):
+ '''Create new commit object from existing commit object.
+
+ Any values provided as keyword arguments will replace the
+ corresponding attribute in the new object.
+ '''
+
+ attrs = {k: getattr(self, k) for k in self.__slots__}
+
+ for attrname in kwargs:
+ if attrname not in self.__slots__:
+ raise ValueError('invalid attribute name')
+
+ attrs.update(kwargs)
+ new_commit = self.__class__(self.repo, self.NULL_BIN_SHA, **attrs)
+ new_commit.binsha = self._calculate_sha_(self.repo, new_commit)
+
+ return new_commit
+
def _set_cache_(self, attr):
if attr in Commit.__slots__:
# read the data in a chunk, its faster - then provide a file wrapper
@@ -375,13 +410,7 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
committer, committer_time, committer_offset,
message, parent_commits, conf_encoding)
- stream = BytesIO()
- new_commit._serialize(stream)
- streamlen = stream.tell()
- stream.seek(0)
-
- istream = repo.odb.store(IStream(cls.type, streamlen, stream))
- new_commit.binsha = istream.binsha
+ new_commit.binsha = cls._calculate_sha_(repo, new_commit)
if head:
# need late import here, importing git at the very beginning throws