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

"""Gclient-specific SCM-specific operations."""

import logging
import os
import re
import subprocess

import scm
import gclient_utils


### SCM abstraction layer

# Factory Method for SCM wrapper creation

def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'):
  # TODO(maruel): Deduce the SCM from the url.
  scm_map = {
    'svn' : SVNWrapper,
    'git' : GitWrapper,
  }

  if url and (url.startswith('git:') or
              url.startswith('ssh:') or
              url.endswith('.git')):
    scm_name = 'git'

  if not scm_name in scm_map:
    raise gclient_utils.Error('Unsupported scm %s' % scm_name)
  return scm_map[scm_name](url, root_dir, relpath, scm_name)


# SCMWrapper base class

class SCMWrapper(object):
  """Add necessary glue between all the supported SCM.

  This is the abstraction layer to bind to different SCM. Since currently only
  subversion is supported, a lot of subersionism remains. This can be sorted out
  once another SCM is supported."""
  def __init__(self, url=None, root_dir=None, relpath=None,
               scm_name='svn'):
    self.scm_name = scm_name
    self.url = url
    self._root_dir = root_dir
    if self._root_dir:
      self._root_dir = self._root_dir.replace('/', os.sep)
    self.relpath = relpath
    if self.relpath:
      self.relpath = self.relpath.replace('/', os.sep)
    if self.relpath and self._root_dir:
      self.checkout_path = os.path.join(self._root_dir, self.relpath)

  def FullUrlForRelativeUrl(self, url):
    # Find the forth '/' and strip from there. A bit hackish.
    return '/'.join(self.url.split('/')[:4]) + url

  def RunCommand(self, command, options, args, file_list=None):
    # file_list will have all files that are modified appended to it.
    if file_list is None:
      file_list = []

    commands = ['cleanup', 'export', 'update', 'revert', 'revinfo',
                'status', 'diff', 'pack', 'runhooks']

    if not command in commands:
      raise gclient_utils.Error('Unknown command %s' % command)

    if not command in dir(self):
      raise gclient_utils.Error('Command %s not implemnted in %s wrapper' % (
          command, self.scm_name))

    return getattr(self, command)(options, args, file_list)


class GitWrapper(SCMWrapper, scm.GIT):
  """Wrapper for Git"""

  def cleanup(self, options, args, file_list):
    """Cleanup working copy."""
    __pychecker__ = 'unusednames=args,file_list,options'
    self._Run(['prune'], redirect_stdout=False)
    self._Run(['fsck'], redirect_stdout=False)
    self._Run(['gc'], redirect_stdout=False)

  def diff(self, options, args, file_list):
    __pychecker__ = 'unusednames=args,file_list,options'
    merge_base = self._Run(['merge-base', 'HEAD', 'origin'])
    self._Run(['diff', merge_base], redirect_stdout=False)

  def export(self, options, args, file_list):
    __pychecker__ = 'unusednames=file_list,options'
    assert len(args) == 1
    export_path = os.path.abspath(os.path.join(args[0], self.relpath))
    if not os.path.exists(export_path):
      os.makedirs(export_path)
    self._Run(['checkout-index', '-a', '--prefix=%s/' % export_path],
              redirect_stdout=False)

  def update(self, options, args, file_list):
    """Runs git to update or transparently checkout the working copy.

    All updated files will be appended to file_list.

    Raises:
      Error: if can't get URL for relative path.
    """

    if args:
      raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))

    url, revision = gclient_utils.SplitUrlRevision(self.url)
    rev_str = ""
    if options.revision:
      # Override the revision number.
      revision = str(options.revision)
    if revision:
      url = '%s@%s' % (url, revision)
      rev_str = ' at %s' % revision

    if options.verbose:
      print("\n_____ %s%s" % (self.relpath, rev_str))

    if not os.path.exists(self.checkout_path):
      self._Run(['clone', url, self.checkout_path],
                cwd=self._root_dir, redirect_stdout=False)
      if revision:
        self._Run(['reset', '--hard', revision], redirect_stdout=False)
      files = self._Run(['ls-files']).split()
      file_list.extend([os.path.join(self.checkout_path, f) for f in files])
      return<commit_msg>gclient: fix regression in revision handling code in GitWrapper::update<commit_after># Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Gclient-specific SCM-specific operations."""

import logging
import os
import re
import subprocess

import scm
import gclient_utils


### SCM abstraction layer

# Factory Method for SCM wrapper creation

def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'):
  # TODO(maruel): Deduce the SCM from the url.
  scm_map = {
    'svn' : SVNWrapper,
    'git' : GitWrapper,
  }

  if url and (url.startswith('git:') or
              url.startswith('ssh:') or
              url.endswith('.git')):
    scm_name = 'git'

  if not scm_name in scm_map:
    raise gclient_utils.Error('Unsupported scm %s' % scm_name)
  return scm_map[scm_name](url, root_dir, relpath, scm_name)


# SCMWrapper base class

class SCMWrapper(object):
  """Add necessary glue between all the supported SCM.

  This is the abstraction layer to bind to different SCM. Since currently only
  subversion is supported, a lot of subersionism remains. This can be sorted out
  once another SCM is supported."""
  def __init__(self, url=None, root_dir=None, relpath=None,
               scm_name='svn'):
    self.scm_name = scm_name
    self.url = url
    self._root_dir = root_dir
    if self._root_dir:
      self._root_dir = self._root_dir.replace('/', os.sep)
    self.relpath = relpath
    if self.relpath:
      self.relpath = self.relpath.replace('/', os.sep)
    if self.relpath and self._root_dir:
      self.checkout_path = os.path.join(self._root_dir, self.relpath)

  def FullUrlForRelativeUrl(self, url):
    # Find the forth '/' and strip from there. A bit hackish.
    return '/'.join(self.url.split('/')[:4]) + url

  def RunCommand(self, command, options, args, file_list=None):
    # file_list will have all files that are modified appended to it.
    if file_list is None:
      file_list = []

    commands = ['cleanup', 'export', 'update', 'revert', 'revinfo',
                'status', 'diff', 'pack', 'runhooks']

    if not command in commands:
      raise gclient_utils.Error('Unknown command %s' % command)

    if not command in dir(self):
      raise gclient_utils.Error('Command %s not implemnted in %s wrapper' % (
          command, self.scm_name))

    return getattr(self, command)(options, args, file_list)


class GitWrapper(SCMWrapper, scm.GIT):
  """Wrapper for Git"""

  def cleanup(self, options, args, file_list):
    """Cleanup working copy."""
    __pychecker__ = 'unusednames=args,file_list,options'
    self._Run(['prune'], redirect_stdout=False)
    self._Run(['fsck'], redirect_stdout=False)
    self._Run(['gc'], redirect_stdout=False)

  def diff(self, options, args, file_list):
    __pychecker__ = 'unusednames=args,file_list,options'
    merge_base = self._Run(['merge-base', 'HEAD', 'origin'])
    self._Run(['diff', merge_base], redirect_stdout=False)

  def export(self, options, args, file_list):
    __pychecker__ = 'unusednames=file_list,options'
    assert len(args) == 1
    export_path = os.path.abspath(os.path.join(args[0], self.relpath))
    if not os.path.exists(export_path):
      os.makedirs(export_path)
    self._Run(['checkout-index', '-a', '--prefix=%s/' % export_path],
              redirect_stdout=False)

  def update(self, options, args, file_list):
    """Runs git to update or transparently checkout the working copy.

    All updated files will be appended to file_list.

    Raises:
      Error: if can't get URL for relative path.
    """

    if args:
      raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))

    url, revision = gclient_utils.SplitUrlRevision(self.url)
    rev_str = ""
    if options.revision:
      # Override the revision number.
      revision = str(options.revision)
    if revision:
      rev_str = ' at %s' % revision

    if options.verbose:
      print("\n_____ %s%s" % (self.relpath, rev_str))

    if not os.path.exists(self.checkout_path):
      self._Run(['clone', url, self.checkout_path],
                cwd=self._root_dir, redirect_stdout=False)
      if revision:
        self._Run(['reset', '--hard', revision], redirect_stdout=False)
      files = self._Run(['ls-files']).split()
      file_list.extend([os.path.join(self.checkout_path, f) for f in files])
      return
{'fraction_non_alphanumeric': 0.12581809975174904, 'fraction_numerical': 0.001579778830963665, 'mean_word_length': 3.3985111662531016, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5472595', 'n_tokens_mistral': 2923, 'n_tokens_neox': 2849, 'n_words': 795}