| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -4,7 +4,7 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				# found in the LICENSE file.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				"""Manages a project checkout.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Includes support for svn, git-svn and git.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Includes support only for git.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				"""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import fnmatch
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -161,403 +161,6 @@ class CheckoutBase(object):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    raise NotImplementedError()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class RawCheckout(CheckoutBase):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Used to apply a patch locally without any intent to commit it.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  To be used by the try server.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def prepare(self, revision):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Stubbed out."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def apply_patch(self, patches, post_processors=None, verbose=False):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Ignores svn properties."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    post_processors = post_processors or self.post_processors or []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for p in patches:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      stdout = []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        filepath = os.path.join(self.project_path, p.filename)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if p.is_delete:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          os.remove(filepath)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          assert(not os.path.exists(filepath))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          stdout.append('Deleted.')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          dirname = os.path.dirname(p.filename)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          full_dir = os.path.join(self.project_path, dirname)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if dirname and not os.path.isdir(full_dir):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            os.makedirs(full_dir)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append('Created missing directory %s.' % dirname)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if p.is_binary:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            content = p.get()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            with open(filepath, 'wb') as f:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              f.write(content)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append('Added binary file %d bytes.' % len(content))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if p.source_filename:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              if not p.is_new:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                raise PatchApplicationFailed(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    p,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    'File has a source filename specified but is not new')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              # Copy the file first.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              if os.path.isfile(filepath):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                raise PatchApplicationFailed(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    p, 'File exist but was about to be overwriten')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              shutil.copy2(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  os.path.join(self.project_path, p.source_filename), filepath)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append('Copied %s -> %s' % (p.source_filename, p.filename))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if p.diff_hunks:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              cmd = ['patch', '-u', '--binary', '-p%s' % p.patchlevel]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              if verbose:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                cmd.append('--verbose')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              env = os.environ.copy()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              env['TMPDIR'] = tempfile.mkdtemp(prefix='crpatch')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    subprocess2.check_output(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        cmd,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        stdin=p.get(False),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        stderr=subprocess2.STDOUT,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        cwd=self.project_path,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        timeout=GLOBAL_TIMEOUT,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        env=env))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              finally:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                shutil.rmtree(env['TMPDIR'])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            elif p.is_new and not os.path.exists(filepath):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              # There is only a header. Just create the file.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              open(filepath, 'w').close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append('Created an empty file.')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for post in post_processors:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          post(self, p)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if verbose:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          print p.filename
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          print align_stdout(stdout)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      except OSError, e:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise PatchApplicationFailed(p, '%s%s' % (align_stdout(stdout), e))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      except subprocess.CalledProcessError, e:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise PatchApplicationFailed(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            p,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            'While running %s;\n%s%s' % (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              ' '.join(e.cmd),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              align_stdout(stdout),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              align_stdout([getattr(e, 'stdout', '')])))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def commit(self, commit_message, user):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Stubbed out."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    raise NotImplementedError('RawCheckout can\'t commit')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def revisions(self, _rev1, _rev2):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class SvnConfig(object):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Parses a svn configuration file."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def __init__(self, svn_config_dir=None):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    super(SvnConfig, self).__init__()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.svn_config_dir = svn_config_dir
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.default = not bool(self.svn_config_dir)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not self.svn_config_dir:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if sys.platform == 'win32':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.svn_config_dir = os.path.join(os.environ['APPDATA'], 'Subversion')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.svn_config_dir = os.path.expanduser(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            os.path.join('~', '.subversion'))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    svn_config_file = os.path.join(self.svn_config_dir, 'config')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    parser = configparser.SafeConfigParser()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if os.path.isfile(svn_config_file):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      parser.read(svn_config_file)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      parser.add_section('auto-props')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.auto_props = dict(parser.items('auto-props'))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class SvnMixIn(object):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """MixIn class to add svn commands common to both svn and git-svn clients."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # These members need to be set by the subclass.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  commit_user = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  commit_pwd = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  svn_url = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  project_path = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # Override at class level when necessary. If used, --non-interactive is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # implied.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  svn_config = SvnConfig()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # Set to True when non-interactivity is necessary but a custom subversion
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  # configuration directory is not necessary.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  non_interactive = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def _add_svn_flags(self, args, non_interactive, credentials=True):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    args = ['svn'] + args
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not self.svn_config.default:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      args.extend(['--config-dir', self.svn_config.svn_config_dir])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not self.svn_config.default or self.non_interactive or non_interactive:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      args.append('--non-interactive')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if credentials:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if self.commit_user:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        args.extend(['--username', self.commit_user])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if self.commit_pwd:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        args.extend(['--password', self.commit_pwd])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return args
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def _check_call_svn(self, args, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Runs svn and throws an exception if the command failed."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    kwargs.setdefault('cwd', self.project_path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    kwargs.setdefault('stdout', self.VOID)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    kwargs.setdefault('timeout', GLOBAL_TIMEOUT)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return subprocess2.check_call_out(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self._add_svn_flags(args, False), **kwargs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def _check_output_svn(self, args, credentials=True, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Runs svn and throws an exception if the command failed.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     Returns the output.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    kwargs.setdefault('cwd', self.project_path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return subprocess2.check_output(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self._add_svn_flags(args, True, credentials),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        stderr=subprocess2.STDOUT,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        timeout=GLOBAL_TIMEOUT,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        **kwargs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  @staticmethod
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def _parse_svn_info(output, key):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Returns value for key from svn info output.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Case insensitive.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    values = {}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    key = key.lower()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for line in output.splitlines(False):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if not line:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        continue
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      k, v = line.split(':', 1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      k = k.strip().lower()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      v = v.strip()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      assert not k in values
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      values[k] = v
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return values.get(key, None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class SvnCheckout(CheckoutBase, SvnMixIn):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Manages a subversion checkout."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def __init__(self, root_dir, project_name, commit_user, commit_pwd, svn_url,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      post_processors=None):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    CheckoutBase.__init__(self, root_dir, project_name, post_processors)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SvnMixIn.__init__(self)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.commit_user = commit_user
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.commit_pwd = commit_pwd
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    self.svn_url = svn_url
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    assert bool(self.commit_user) >= bool(self.commit_pwd)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def prepare(self, revision):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # Will checkout if the directory is not present.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    assert self.svn_url
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not os.path.isdir(self.project_path):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      logging.info('Checking out %s in %s' %
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          (self.project_name, self.project_path))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return self._revert(revision)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def apply_patch(self, patches, post_processors=None, verbose=False):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    post_processors = post_processors or self.post_processors or []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    for p in patches:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      stdout = []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        filepath = os.path.join(self.project_path, p.filename)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # It is important to use credentials=False otherwise credentials could
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # leak in the error message. Credentials are not necessary here for the
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # following commands anyway.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if p.is_delete:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          stdout.append(self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              ['delete', p.filename, '--force'], credentials=False))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          assert(not os.path.exists(filepath))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          stdout.append('Deleted.')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          # svn add while creating directories otherwise svn add on the
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          # contained files will silently fail.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          # First, find the root directory that exists.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          dirname = os.path.dirname(p.filename)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          dirs_to_create = []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          while (dirname and
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              not os.path.isdir(os.path.join(self.project_path, dirname))):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            dirs_to_create.append(dirname)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            dirname = os.path.dirname(dirname)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          for dir_to_create in reversed(dirs_to_create):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            os.mkdir(os.path.join(self.project_path, dir_to_create))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  ['add', dir_to_create, '--force'], credentials=False))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append('Created missing directory %s.' % dir_to_create)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if p.is_binary:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            content = p.get()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            with open(filepath, 'wb') as f:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              f.write(content)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append('Added binary file %d bytes.' % len(content))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if p.source_filename:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              if not p.is_new:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                raise PatchApplicationFailed(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    p,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    'File has a source filename specified but is not new')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              # Copy the file first.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              if os.path.isfile(filepath):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                raise PatchApplicationFailed(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    p, 'File exist but was about to be overwriten')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    ['copy', p.source_filename, p.filename]))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append('Copied %s -> %s' % (p.source_filename, p.filename))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if p.diff_hunks:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              cmd = [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                'patch',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                '-p%s' % p.patchlevel,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                '--forward',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                '--force',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                '--no-backup-if-mismatch',
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              env = os.environ.copy()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              env['TMPDIR'] = tempfile.mkdtemp(prefix='crpatch')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    subprocess2.check_output(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                      cmd,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                      stdin=p.get(False),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                      cwd=self.project_path,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                      timeout=GLOBAL_TIMEOUT,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                      env=env))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              finally:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                shutil.rmtree(env['TMPDIR'])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            elif p.is_new and not os.path.exists(filepath):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              # There is only a header. Just create the file if it doesn't
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              # exist.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              open(filepath, 'w').close()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append('Created an empty file.')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if p.is_new and not p.source_filename:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # Do not run it if p.source_filename is defined, since svn copy was
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # using above.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  ['add', p.filename, '--force'], credentials=False))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          for name, value in p.svn_properties:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if value is None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    ['propdel', '--quiet', name, p.filename],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    credentials=False))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append('Property %s deleted.' % name)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    ['propset', name, value, p.filename], credentials=False))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              stdout.append('Property %s=%s' % (name, value))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          for prop, values in self.svn_config.auto_props.iteritems():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if fnmatch.fnmatch(p.filename, prop):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              for value in values.split(';'):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if '=' not in value:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  params = [value, '.']
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  params = value.split('=', 1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if params[1] == '*':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  # Works around crbug.com/150960 on Windows.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  params[1] = '.'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                stdout.append(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                      ['propset'] + params + [p.filename], credentials=False))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                stdout.append('Property (auto) %s' % '='.join(params))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for post in post_processors:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          post(self, p)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if verbose:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          print p.filename
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          print align_stdout(stdout)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      except OSError, e:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise PatchApplicationFailed(p, '%s%s' % (align_stdout(stdout), e))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      except subprocess.CalledProcessError, e:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        raise PatchApplicationFailed(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            p,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            'While running %s;\n%s%s' % (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              ' '.join(e.cmd),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              align_stdout(stdout),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              align_stdout([getattr(e, 'stdout', '')])))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def commit(self, commit_message, user):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    logging.info('Committing patch for %s' % user)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    assert self.commit_user
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    assert isinstance(commit_message, unicode)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    handle, commit_filename = tempfile.mkstemp(text=True)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # Shouldn't assume default encoding is UTF-8. But really, if you are using
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # anything else, you are living in another world.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      os.write(handle, commit_message.encode('utf-8'))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      os.close(handle)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # When committing, svn won't update the Revision metadata of the checkout,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # so if svn commit returns "Committed revision 3.", svn info will still
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # return "Revision: 2". Since running svn update right after svn commit
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # creates a race condition with other committers, this code _must_ parse
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # the output of svn commit and use a regexp to grab the revision number.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # Note that "Committed revision N." is localized but subprocess2 forces
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # LANGUAGE=en.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      args = ['commit', '--file', commit_filename]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # realauthor is parsed by a server-side hook.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if user and user != self.commit_user:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        args.extend(['--with-revprop', 'realauthor=%s' % user])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      out = self._check_output_svn(args)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    finally:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      os.remove(commit_filename)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    lines = filter(None, out.splitlines())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    match = re.match(r'^Committed revision (\d+).$', lines[-1])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if not match:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      raise PatchApplicationFailed(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          None,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          'Couldn\'t make sense out of svn commit message:\n' + out)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return int(match.group(1))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def _revert(self, revision):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Reverts local modifications or checks out if the directory is not
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    present. Use depot_tools's functionality to do this.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    flags = ['--ignore-externals']
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if revision:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      flags.extend(['--revision', str(revision)])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if os.path.isdir(self.project_path):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # This may remove any part (or all) of the checkout.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      scm.SVN.Revert(self.project_path, no_ignore=True)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if os.path.isdir(self.project_path):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      # Revive files that were deleted in scm.SVN.Revert().
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      self._check_call_svn(['update', '--force'] + flags,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                           timeout=FETCH_TIMEOUT)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      logging.info(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          'Directory %s is not present, checking it out.' % self.project_path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      self._check_call_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          ['checkout', self.svn_url, self.project_path] + flags, cwd=None,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          timeout=FETCH_TIMEOUT)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return self._get_revision()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def _get_revision(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    out = self._check_output_svn(['info', '.'])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    revision = int(self._parse_svn_info(out, 'revision'))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if revision != self._last_seen_revision:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      logging.info('Updated to revision %d' % revision)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      self._last_seen_revision = revision
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return revision
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def revisions(self, rev1, rev2):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Returns the number of actual commits, not just the difference between
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    numbers.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    rev2 = rev2 or 'HEAD'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # Revision range is inclusive and ordering doesn't matter, they'll appear in
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # the order specified.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      out = self._check_output_svn(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          ['log', '-q', self.svn_url, '-r', '%s:%s' % (rev1, rev2)])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    except subprocess.CalledProcessError:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      return None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # Ignore the '----' lines.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return len([l for l in out.splitlines() if l.startswith('r')]) - 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class GitCheckout(CheckoutBase):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  """Manages a git checkout."""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  def __init__(self, root_dir, project_name, remote_branch, git_url,
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -639,8 +242,6 @@ class GitCheckout(CheckoutBase):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """Applies a patch on 'working_branch' and switches to it.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    The changes remain staged on the current branch.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Ignores svn properties and raise an exception on unexpected ones.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    """
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    post_processors = post_processors or self.post_processors or []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    # It this throws, the checkout is corrupted. Maybe worth deleting it and
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -686,19 +287,6 @@ class GitCheckout(CheckoutBase):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if verbose:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              cmd.append('--verbose')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append(self._check_output_git(cmd, stdin=p.get(True)))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          for key, value in p.svn_properties:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # Ignore some known auto-props flags through .subversion/config,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # bails out on the other ones.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # TODO(maruel): Read ~/.subversion/config and detect the rules that
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # applies here to figure out if the property will be correctly
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # handled.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            stdout.append('Property %s=%s' % (key, value))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if not key in (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                'svn:eol-style', 'svn:executable', 'svn:mime-type'):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              raise patch.UnsupportedPatchFormat(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  p.filename,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                  'Cannot apply svn property %s to file %s.' % (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        key, p.filename))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for post in post_processors:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          post(self, p)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if verbose:
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |