| Index: git_cl.py
 | 
| diff --git a/git_cl.py b/git_cl.py
 | 
| index c24fdb6afc47926c51765b472da152e3b0018de4..0718b35df4cc3e451ab41f27adb3c29f12dbde21 100755
 | 
| --- a/git_cl.py
 | 
| +++ b/git_cl.py
 | 
| @@ -639,47 +639,42 @@ def GetCodereviewSettingsInteractively():
 | 
|  
 | 
|  class ChangeDescription(object):
 | 
|    """Contains a parsed form of the change description."""
 | 
| -  def __init__(self, subject, log_desc, reviewers):
 | 
| -    self.subject = subject
 | 
| +  def __init__(self, log_desc, reviewers):
 | 
|      self.log_desc = log_desc
 | 
|      self.reviewers = reviewers
 | 
|      self.description = self.log_desc
 | 
|  
 | 
| -  def Update(self):
 | 
| -    initial_text = """# Enter a description of the change.
 | 
| +  def Prompt(self):
 | 
| +    content = """# Enter a description of the change.
 | 
|  # This will displayed on the codereview site.
 | 
|  # The first line will also be used as the subject of the review.
 | 
|  """
 | 
| -    initial_text += self.description
 | 
| +    content += self.description
 | 
|      if ('\nR=' not in self.description and
 | 
|          '\nTBR=' not in self.description and
 | 
|          self.reviewers):
 | 
| -      initial_text += '\nR=' + self.reviewers
 | 
| +      content += '\nR=' + self.reviewers
 | 
|      if '\nBUG=' not in self.description:
 | 
| -      initial_text += '\nBUG='
 | 
| +      content += '\nBUG='
 | 
|      if '\nTEST=' not in self.description:
 | 
| -      initial_text += '\nTEST='
 | 
| -    initial_text = initial_text.rstrip('\n') + '\n'
 | 
| -    content = gclient_utils.RunEditor(initial_text, True)
 | 
| +      content += '\nTEST='
 | 
| +    content = content.rstrip('\n') + '\n'
 | 
| +    content = gclient_utils.RunEditor(content, True)
 | 
|      if not content:
 | 
|        DieWithError('Running editor failed')
 | 
|      content = re.compile(r'^#.*$', re.MULTILINE).sub('', content).strip()
 | 
|      if not content:
 | 
|        DieWithError('No CL description, aborting')
 | 
| -    self._ParseDescription(content)
 | 
| +    self.description = content.strip('\n') + '\n'
 | 
|  
 | 
| -  def _ParseDescription(self, description):
 | 
| -    """Updates the list of reviewers and subject from the description."""
 | 
| -    if not description:
 | 
| -      self.description = description
 | 
| -      return
 | 
| -
 | 
| -    self.description = description.strip('\n') + '\n'
 | 
| -    self.subject = description.split('\n', 1)[0]
 | 
| +  def ParseDescription(self):
 | 
| +    """Updates the list of reviewers."""
 | 
|      # Retrieves all reviewer lines
 | 
|      regexp = re.compile(r'^\s*(TBR|R)=(.+)$', re.MULTILINE)
 | 
| -    self.reviewers = ','.join(
 | 
| +    reviewers = ','.join(
 | 
|          i.group(2).strip() for i in regexp.finditer(self.description))
 | 
| +    if reviewers:
 | 
| +      self.reviewers = reviewers
 | 
|  
 | 
|    def IsEmpty(self):
 | 
|      return not self.description
 | 
| @@ -925,9 +920,6 @@ def CMDupload(parser, args):
 | 
|    upload_args.extend(['--server', cl.GetRietveldServer()])
 | 
|    if options.emulate_svn_auto_props:
 | 
|      upload_args.append('--emulate_svn_auto_props')
 | 
| -  if options.from_logs and not options.message:
 | 
| -    print 'Must set message for subject line if using desc_from_logs'
 | 
| -    return 1
 | 
|  
 | 
|    change_desc = None
 | 
|  
 | 
| @@ -938,18 +930,17 @@ def CMDupload(parser, args):
 | 
|      print ("This branch is associated with issue %s. "
 | 
|             "Adding patch to that issue." % cl.GetIssue())
 | 
|    else:
 | 
| -    log_desc = CreateDescriptionFromLog(args)
 | 
| -    change_desc = ChangeDescription(options.message, log_desc,
 | 
| -                                    options.reviewers)
 | 
| -    if not options.from_logs:
 | 
| -      change_desc.Update()
 | 
| +    message = options.message or CreateDescriptionFromLog(args)
 | 
| +    change_desc = ChangeDescription(message, options.reviewers)
 | 
| +    if not options.force:
 | 
| +      change_desc.Prompt()
 | 
| +    change_desc.ParseDescription()
 | 
|  
 | 
|      if change_desc.IsEmpty():
 | 
|        print "Description is empty; aborting."
 | 
|        return 1
 | 
|  
 | 
| -    upload_args.extend(['--message', change_desc.subject])
 | 
| -    upload_args.extend(['--description', change_desc.description])
 | 
| +    upload_args.extend(['--message', change_desc.description])
 | 
|      if change_desc.reviewers:
 | 
|        upload_args.extend(['--reviewers', change_desc.reviewers])
 | 
|      if options.send_mail:
 | 
| 
 |