@@ -136,6 +136,41 @@ def __init__(self, repo, binsha, tree=None, author=None, authored_date=None, aut
136136def _get_intermediate_items (cls ,commit ):
137137return commit .parents
138138
139+ @classmethod
140+ def _calculate_sha_ (cls ,repo ,commit ):
141+ '''Calculate the sha of a commit.
142+
143+ :param repo: Repo object the commit should be part of
144+ :param commit: Commit object for which to generate the sha
145+ '''
146+
147+ stream = BytesIO ()
148+ commit ._serialize (stream )
149+ streamlen = stream .tell ()
150+ stream .seek (0 )
151+
152+ istream = repo .odb .store (IStream (cls .type ,streamlen ,stream ))
153+ return istream .binsha
154+
155+ def replace (self ,** kwargs ):
156+ '''Create new commit object from existing commit object.
157+
158+ Any values provided as keyword arguments will replace the
159+ corresponding attribute in the new object.
160+ '''
161+
162+ attrs = {k :getattr (self ,k )for k in self .__slots__ }
163+
164+ for attrname in kwargs :
165+ if attrname not in self .__slots__ :
166+ raise ValueError ('invalid attribute name' )
167+
168+ attrs .update (kwargs )
169+ new_commit = self .__class__ (self .repo ,self .NULL_BIN_SHA ,** attrs )
170+ new_commit .binsha = self ._calculate_sha_ (self .repo ,new_commit )
171+
172+ return new_commit
173+
139174def _set_cache_ (self ,attr ):
140175if attr in Commit .__slots__ :
141176# read the data in a chunk, its faster - then provide a file wrapper
@@ -375,13 +410,7 @@ def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False,
375410committer ,committer_time ,committer_offset ,
376411message ,parent_commits ,conf_encoding )
377412
378- stream = BytesIO ()
379- new_commit ._serialize (stream )
380- streamlen = stream .tell ()
381- stream .seek (0 )
382-
383- istream = repo .odb .store (IStream (cls .type ,streamlen ,stream ))
384- new_commit .binsha = istream .binsha
413+ new_commit .binsha = cls ._calculate_sha_ (repo ,new_commit )
385414
386415if head :
387416# need late import here, importing git at the very beginning throws