<commit_before>#!/usr/bin/python

# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

""" This simple program takes changes from gerrit/gerrit-int and creates new
changes for them on the desired branch using your gerrit/ssh credentials. To
specify a change on gerrit-int, you must prefix the change with a *.

Note that this script is best used from within an existing checkout of
Chromium OS that already has the changes you want merged to the branch in it
i.e. if you want to push changes to crosutils.git, you must have src/scripts
checked out. If this isn't true e.g. you are running this script from a
minilayout or trying to upload an internal change from a non internal checkout,
you must specify some extra options: use the --nomirror option and use -e to
specify your email address. This tool will then checkout the git repo fresh
using the credentials for the -e/email you specified and upload the change. Note
you can always use this method but it's slower than the "mirrored" method and
requires more typing :(.

Examples:
  cros_merge_to_branch 32027 32030 32031 release-R22.2723.B

This will create changes for 32027, 32030 and 32031 on the R22 branch. To look
up the name of a branch, go into a git sub-dir and type 'git branch -a' and the
find the branch you want to merge to. If you want to upload internal changes
from gerrit-int, you must prefix the gerrit change number with a * e.g.

  cros_merge_to_branch *26108 release-R22.2723.B

For more information on how to do this yourself you can go here:
http://dev.chromium.org/chromium-os/how-tos-and-troubleshooting/working-on-a-br\
anch
"""

import logging
import os
import re
import shutil
import sys
import tempfile

from chromite.buildbot import constants
from chromite.buildbot import repository
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import gerrit
from chromite.lib import git
from chromite.lib import patch as cros_patch


_USAGE = """
cros_merge_to_branch [*]change_number1 [[*]change_number2 ...] branch\n\n %s
""" % __doc__


def _GetParser():
  """Returns the parser to use for this module."""
  parser = commandline.OptionParser(usage=_USAGE)
  parser.add_option('-d', '--draft', default=False, action='store_true',
                    help='Upload a draft to Gerrit rather than a change.')
  parser.add_option('-n', '--dry-run', default=False, action='store_true',
                    dest='dryrun',
                    help='Apply changes locally but do not upload them.')
  parser.add_option('-e', '--email',
                    help='If specified, use this email instead of '
                    'the email you would upload changes as. Must be set if '
                    'nomirror is set.')
  parser.add_option('--nomirror', default=True, dest='mirror',
                    action='store_false', help='Disable mirroring -- requires '
                    'email to be set.')
  parser.add_option('--nowipe', default=True, dest='wipe', action='store_false',
                    help='Do not wipe the work directory after finishing.')
  return parser


def _UploadChangeToBranch(work_dir, patch, branch, draft, dryrun):
  """Creates a new change from GerritPatch |patch| to |branch| from |work_dir|.

  Args:
    patch: Instance of GerritPatch to upload.
    branch: Branch to upload to.
    work_dir: Local directory where repository is checked out in.
    draft: If True, upload to refs/draft/|branch| rather than refs/for/|branch|.
    dryrun: Don't actually upload a change but go through all the steps up to
      and including git push --dry-run.
  """
  upload_type = 'drafts' if draft else 'for'
  # Download & setup the patch if need be.
  patch.Fetch(work_dir)
  # Apply the actual change.
  patch.CherryPick(work_dir, inflight=True, leave_dirty=True)

  # Get the new sha1 after apply.
  new_sha1 = git.GetGitRepoRevision(work_dir)

  # If the sha1 has changed, then rewrite the commit message.
  if patch.sha1 != new_sha1:
    msg = []
    reviewers = set()
    for line in patch.commit_message.splitlines():
      if line.startswith('Reviewed-on: '):
        line = 'Previous-' + line
      elif line.startswith('Commit-Ready: ') or \
           line.startswith('Reviewed-by: ') or \
           line.startswith('Tested-by: '):
        # If the tag is malformed, or the person lacks a name,
        # then that's just too bad -- throw it away.
        ele = re.split('[<>@]+', line)
        if len(ele) == 4:
          reviewers.add('@'.join(ele[-3:-1]))
        continue
      msg.append(line)<commit_msg>Define reviewers outside of conditional scope.<commit_after>#!/usr/bin/python

# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

""" This simple program takes changes from gerrit/gerrit-int and creates new
changes for them on the desired branch using your gerrit/ssh credentials. To
specify a change on gerrit-int, you must prefix the change with a *.

Note that this script is best used from within an existing checkout of
Chromium OS that already has the changes you want merged to the branch in it
i.e. if you want to push changes to crosutils.git, you must have src/scripts
checked out. If this isn't true e.g. you are running this script from a
minilayout or trying to upload an internal change from a non internal checkout,
you must specify some extra options: use the --nomirror option and use -e to
specify your email address. This tool will then checkout the git repo fresh
using the credentials for the -e/email you specified and upload the change. Note
you can always use this method but it's slower than the "mirrored" method and
requires more typing :(.

Examples:
  cros_merge_to_branch 32027 32030 32031 release-R22.2723.B

This will create changes for 32027, 32030 and 32031 on the R22 branch. To look
up the name of a branch, go into a git sub-dir and type 'git branch -a' and the
find the branch you want to merge to. If you want to upload internal changes
from gerrit-int, you must prefix the gerrit change number with a * e.g.

  cros_merge_to_branch *26108 release-R22.2723.B

For more information on how to do this yourself you can go here:
http://dev.chromium.org/chromium-os/how-tos-and-troubleshooting/working-on-a-br\
anch
"""

import logging
import os
import re
import shutil
import sys
import tempfile

from chromite.buildbot import constants
from chromite.buildbot import repository
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import gerrit
from chromite.lib import git
from chromite.lib import patch as cros_patch


_USAGE = """
cros_merge_to_branch [*]change_number1 [[*]change_number2 ...] branch\n\n %s
""" % __doc__


def _GetParser():
  """Returns the parser to use for this module."""
  parser = commandline.OptionParser(usage=_USAGE)
  parser.add_option('-d', '--draft', default=False, action='store_true',
                    help='Upload a draft to Gerrit rather than a change.')
  parser.add_option('-n', '--dry-run', default=False, action='store_true',
                    dest='dryrun',
                    help='Apply changes locally but do not upload them.')
  parser.add_option('-e', '--email',
                    help='If specified, use this email instead of '
                    'the email you would upload changes as. Must be set if '
                    'nomirror is set.')
  parser.add_option('--nomirror', default=True, dest='mirror',
                    action='store_false', help='Disable mirroring -- requires '
                    'email to be set.')
  parser.add_option('--nowipe', default=True, dest='wipe', action='store_false',
                    help='Do not wipe the work directory after finishing.')
  return parser


def _UploadChangeToBranch(work_dir, patch, branch, draft, dryrun):
  """Creates a new change from GerritPatch |patch| to |branch| from |work_dir|.

  Args:
    patch: Instance of GerritPatch to upload.
    branch: Branch to upload to.
    work_dir: Local directory where repository is checked out in.
    draft: If True, upload to refs/draft/|branch| rather than refs/for/|branch|.
    dryrun: Don't actually upload a change but go through all the steps up to
      and including git push --dry-run.
  """
  upload_type = 'drafts' if draft else 'for'
  # Download & setup the patch if need be.
  patch.Fetch(work_dir)
  # Apply the actual change.
  patch.CherryPick(work_dir, inflight=True, leave_dirty=True)

  # Get the new sha1 after apply.
  new_sha1 = git.GetGitRepoRevision(work_dir)
  reviewers = set()

  # If the sha1 has changed, then rewrite the commit message.
  if patch.sha1 != new_sha1:
    msg = []
    for line in patch.commit_message.splitlines():
      if line.startswith('Reviewed-on: '):
        line = 'Previous-' + line
      elif line.startswith('Commit-Ready: ') or \
           line.startswith('Reviewed-by: ') or \
           line.startswith('Tested-by: '):
        # If the tag is malformed, or the person lacks a name,
        # then that's just too bad -- throw it away.
        ele = re.split('[<>@]+', line)
        if len(ele) == 4:
          reviewers.add('@'.join(ele[-3:-1]))
        continue
      msg.append(line)
{'fraction_non_alphanumeric': 0.09052137754558055, 'fraction_numerical': 0.013434268045633862, 'mean_word_length': 3.1707425522454424, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7463762', 'n_tokens_mistral': 2885, 'n_tokens_neox': 2694, 'n_words': 1128}