Index: codereview/views.py |
=================================================================== |
--- a/codereview/views.py |
+++ b/codereview/views.py |
@@ -16,9 +16,11 @@ |
import binascii |
+import copy |
import datetime |
import email # see incoming_mail() |
import email.utils |
+import difflib |
import itertools |
import json |
import logging |
@@ -1743,6 +1745,10 @@ |
patchset = models.PatchSet(issue=issue, data=data, url=url, key=ps_key) |
patchset.put() |
+ commitPatch = _create_commit_message_patch(patchset, |
+ patchset.issue.description) |
+ commitPatch.put() |
+ |
if not separate_patches: |
try: |
patches = engine.ParsePatchSet(patchset) |
@@ -1828,6 +1834,24 @@ |
return show(request, issue.key().id(), form) |
return HttpResponseRedirect(reverse(show, args=[issue.key().id()])) |
+def _create_commit_message_patch(patchset, description): |
+ filename = "COMMIT_MSG" |
tfarina1
2013/07/26 00:55:56
Can you rename this to "Commit Message"? So it mat
Andi
2013/07/29 08:38:34
I'd also would like to see a module constant for t
jparent1
2013/08/14 20:16:52
Done.
jparent1
2013/08/14 20:16:52
Done.
|
+ |
+ diff = "" |
+ udiff = difflib.unified_diff("",description.splitlines(1), |
+ fromfile="\dev\\null",tofile=filename) |
+ for line in udiff: |
+ diff += line |
+ |
+ patch_key = db.Key.from_path( |
+ models.Patch.kind(), |
+ db.allocate_ids(db.Key.from_path(models.Patch.kind(), 1, |
+ parent=patchset.key()), 1)[0], |
+ parent=patchset.key()) |
+ commitPatch = models.Patch(patchset=patchset, text=utils.to_dbtext(diff), |
+ filename=filename, key=patch_key, |
+ no_base_file=True) |
+ return commitPatch |
def _add_patchset_from_form(request, issue, form, message_key='message', |
emails_add_only=False): |
@@ -1853,6 +1877,10 @@ |
key=ps_key) |
patchset.put() |
+ commitPatch = _create_commit_message_patch(patchset, |
+ patchset.issue.description) |
+ commitPatch.put() |
+ |
if not separate_patches: |
try: |
patches = engine.ParsePatchSet(patchset) |
@@ -2249,7 +2277,50 @@ |
was_closed = issue.closed |
issue.subject = cleaned_data['subject'] |
+ old_description = issue.description |
issue.description = cleaned_data['description'] |
+ |
+ # If the description was updated, it would get out of sync with the special |
+ # COMMIT_MSG file in the last pastchset. So we clone the last patchset, |
+ # modulo a new COMMIT_MSG patch. |
+ if issue.description != old_description: |
+ |
+ def clone_without_key(obj, **extra_args): |
+ """ Clones an object, without copying the key """ |
+ klass = obj.__class__ |
+ props = {} |
+ for k, v in klass.properties().iteritems(): |
+ if not (type(v) == db.DateTimeProperty and |
+ (getattr(v, 'auto_now') or getattr(v, 'auto_now_add'))): |
+ if type(v) == db.ReferenceProperty: |
+ value = getattr(klass, k).get_value_for_datastore(obj) |
+ else: |
+ value = v.__get__(obj, klass) |
+ props[k] = value |
+ props.update(extra_args) |
+ return klass(**props) |
+ |
+ # Create a new patchset from the last one. |
+ patchsets = list(issue.patchset_set.order('created')) |
+ last_patchset = patchsets[-1] |
+ new_patchset_msg = 'Auto-generated patchset by description update.' |
+ new_patchset = clone_without_key(last_patchset, parent=issue, |
+ message=new_patchset_msg) |
+ new_patchset.put() |
+ |
+ # Add the new commit message patch. |
+ commitPatch = _create_commit_message_patch(new_patchset, issue.description) |
+ commitPatch.put() |
+ |
+ # And copy all the patches over from last patchset. |
+ for patch in list(last_patchset.patch_set): |
+ # Skip the old commit message, since we just created a new one. |
+ if patch.filename == "COMMIT_MSG": |
+ continue |
+ new_patch = clone_without_key(patch, parent=new_patchset, |
+ patchset=new_patchset) |
+ new_patch.put() |
+ |
issue.closed = cleaned_data['closed'] |
issue.private = cleaned_data.get('private', False) |
base_changed = (issue.base != base) |