diff --git a/git_cl.py b/git_cl.py index 204777543..1c3323bd7 100755 --- a/git_cl.py +++ b/git_cl.py @@ -27,6 +27,7 @@ import re import shutil import stat import sys +import tempfile import textwrap import urllib import urllib2 @@ -3004,8 +3005,12 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase): parent = self._ComputeParent(remote, upstream_branch, custom_cl_base, options.force, change_desc) tree = RunGit(['rev-parse', 'HEAD:']).strip() - ref_to_push = RunGit(['commit-tree', tree, '-p', parent, - '-m', change_desc.description]).strip() + with tempfile.NamedTemporaryFile(delete=False) as desc_tempfile: + desc_tempfile.write(change_desc.description) + desc_tempfile.close() + ref_to_push = RunGit(['commit-tree', tree, '-p', parent, + '-F', desc_tempfile.name]).strip() + os.remove(desc_tempfile.name) else: change_desc = ChangeDescription( options.message or CreateDescriptionFromLog(git_diff_args)) diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py index af33313ca..54aadfa70 100755 --- a/tests/git_cl_test.py +++ b/tests/git_cl_test.py @@ -12,6 +12,7 @@ import logging import os import StringIO import sys +import tempfile import unittest import urlparse @@ -31,6 +32,28 @@ def callError(code=1, cmd='', cwd='', stdout='', stderr=''): CERR1 = callError(1) +def MakeNamedTemporaryFileMock(expected_content): + class NamedTemporaryFileMock(object): + def __init__(self, *args, **kwargs): + self.name = '/tmp/named' + self.expected_content = expected_content + + def __enter__(self): + return self + + def __exit__(self, _type, _value, _tb): + pass + + def write(self, content): + if self.expected_content: + assert content == self.expected_content + + def close(self): + pass + + return NamedTemporaryFileMock + + class ChangelistMock(object): # A class variable so we can access it when we don't have access to the # instance that's being set. @@ -92,8 +115,6 @@ class RietveldMock(object): return 'Commented' - - class GitCheckoutMock(object): def __init__(self, *args, **kwargs): pass @@ -161,6 +182,7 @@ def CookiesAuthenticatorMockFactory(hosts_with_creds=None, same_auth=False): return (hosts_with_creds or {}).get(host) return CookiesAuthenticatorMock + class MockChangelistWithBranchAndIssue(): def __init__(self, branch, issue): self.branch = branch @@ -1541,7 +1563,7 @@ class TestGitCl(TestCase): ((['git', 'rev-parse', 'HEAD:'],), # `HEAD:` means HEAD's tree hash. '0123456789abcdef'), ((['git', 'commit-tree', '0123456789abcdef', '-p', parent, - '-m', description],), + '-F', '/tmp/named'],), ref_to_push), ] else: @@ -1693,6 +1715,9 @@ class TestGitCl(TestCase): other_cl_owner=other_cl_owner, custom_cl_base=custom_cl_base) if fetched_status != 'ABANDONED': + self.mock(tempfile, 'NamedTemporaryFile', MakeNamedTemporaryFileMock( + expected_content=description)) + self.mock(os, 'remove', lambda _: True) self.calls += self._gerrit_upload_calls( description, reviewers, squash, squash_mode=squash_mode,