コード例 #1
0
    def _NeedUpdate(self):
        Trace(': scan refs %s', self._gitdir)

        for name, mtime in self._mtime.items():
            try:
                if mtime != os.path.getmtime(os.path.join(self._gitdir, name)):
                    return True
            except OSError:
                return True
        return False
コード例 #2
0
ファイル: git_config.py プロジェクト: grouperenault/gitrepo
 def _ReadJson(self):
   try:
     if os.path.getmtime(self._json) <= os.path.getmtime(self.file):
       platform_utils.remove(self._json)
       return None
   except OSError:
     return None
   try:
     Trace(': parsing %s', self.file)
     with open(self._json) as fd:
       return json.load(fd)
   except (IOError, ValueError):
     platform_utils.remove(self._json)
     return None
コード例 #3
0
    def _LoadAll(self):
        Trace(': load refs %s', self._gitdir)

        self._phyref = {}
        self._symref = {}
        self._mtime = {}

        self._ReadPackedRefs()
        self._ReadLoose('refs/')
        self._ReadLoose1(os.path.join(self._gitdir, HEAD), HEAD)

        scan = self._symref
        attempts = 0
        while scan and attempts < 5:
            scan_next = {}
            for name, dest in scan.items():
                if dest in self._phyref:
                    self._phyref[name] = self._phyref[dest]
                else:
                    scan_next[name] = dest
            scan = scan_next
            attempts += 1
コード例 #4
0
  def __init__(self,
               project,
               cmdv,
               bare=False,
               input=None,
               capture_stdout=False,
               capture_stderr=False,
               merge_output=False,
               disable_editor=False,
               ssh_proxy=None,
               cwd=None,
               gitdir=None):
    env = self._GetBasicEnv()

    if disable_editor:
      env['GIT_EDITOR'] = ':'
    if ssh_proxy:
      env['REPO_SSH_SOCK'] = ssh_proxy.sock()
      env['GIT_SSH'] = ssh_proxy.proxy
      env['GIT_SSH_VARIANT'] = 'ssh'
    if 'http_proxy' in env and 'darwin' == sys.platform:
      s = "'http.proxy=%s'" % (env['http_proxy'],)
      p = env.get('GIT_CONFIG_PARAMETERS')
      if p is not None:
        s = p + ' ' + s
      env['GIT_CONFIG_PARAMETERS'] = s
    if 'GIT_ALLOW_PROTOCOL' not in env:
      env['GIT_ALLOW_PROTOCOL'] = (
          'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc')
    env['GIT_HTTP_USER_AGENT'] = user_agent.git

    if project:
      if not cwd:
        cwd = project.worktree
      if not gitdir:
        gitdir = project.gitdir

    command = [GIT]
    if bare:
      if gitdir:
        # Git on Windows wants its paths only using / for reliability.
        if platform_utils.isWindows():
          gitdir = gitdir.replace('\\', '/')
        env[GIT_DIR] = gitdir
      cwd = None
    command.append(cmdv[0])
    # Need to use the --progress flag for fetch/clone so output will be
    # displayed as by default git only does progress output if stderr is a TTY.
    if sys.stderr.isatty() and cmdv[0] in ('fetch', 'clone'):
      if '--progress' not in cmdv and '--quiet' not in cmdv:
        command.append('--progress')
    command.extend(cmdv[1:])

    stdin = subprocess.PIPE if input else None
    stdout = subprocess.PIPE if capture_stdout else None
    stderr = (subprocess.STDOUT if merge_output else
              (subprocess.PIPE if capture_stderr else None))

    if IsTrace():
      global LAST_CWD
      global LAST_GITDIR

      dbg = ''

      if cwd and LAST_CWD != cwd:
        if LAST_GITDIR or LAST_CWD:
          dbg += '\n'
        dbg += ': cd %s\n' % cwd
        LAST_CWD = cwd

      if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]:
        if LAST_GITDIR or LAST_CWD:
          dbg += '\n'
        dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR]
        LAST_GITDIR = env[GIT_DIR]

      dbg += ': '
      dbg += ' '.join(command)
      if stdin == subprocess.PIPE:
        dbg += ' 0<|'
      if stdout == subprocess.PIPE:
        dbg += ' 1>|'
      if stderr == subprocess.PIPE:
        dbg += ' 2>|'
      elif stderr == subprocess.STDOUT:
        dbg += ' 2>&1'
      Trace('%s', dbg)

    try:
      p = subprocess.Popen(command,
                           cwd=cwd,
                           env=env,
                           encoding='utf-8',
                           errors='backslashreplace',
                           stdin=stdin,
                           stdout=stdout,
                           stderr=stderr)
    except Exception as e:
      raise GitError('%s: %s' % (command[1], e))

    if ssh_proxy:
      ssh_proxy.add_client(p)

    self.process = p
    if input:
      if isinstance(input, str):
        input = input.encode('utf-8')
      p.stdin.write(input)
      p.stdin.close()

    try:
      self.stdout, self.stderr = p.communicate()
    finally:
      if ssh_proxy:
        ssh_proxy.remove_client(p)
    self.rc = p.wait()
コード例 #5
0
ファイル: ssh.py プロジェクト: grouperenault/gitrepo
    def _open_unlocked(self, host, port=None):
        """Make sure a ssh master session exists for |host| & |port|.

    If one doesn't exist already, we'll create it.

    We won't grab any locks, so the caller has to do that.  This helps keep the
    business logic of actually creating the master separate from grabbing locks.
    """
        # Check to see whether we already think that the master is running; if we
        # think it's already running, return right away.
        if port is not None:
            key = '%s:%s' % (host, port)
        else:
            key = host

        if key in self._master_keys:
            return True

        if self._master_broken.value or 'GIT_SSH' in os.environ:
            # Failed earlier, so don't retry.
            return False

        # We will make two calls to ssh; this is the common part of both calls.
        command_base = ['ssh', '-o', 'ControlPath %s' % self.sock(), host]
        if port is not None:
            command_base[1:1] = ['-p', str(port)]

        # Since the key wasn't in _master_keys, we think that master isn't running.
        # ...but before actually starting a master, we'll double-check.  This can
        # be important because we can't tell that that '*****@*****.**' is the same
        # as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file.
        check_command = command_base + ['-O', 'check']
        try:
            Trace(': %s', ' '.join(check_command))
            check_process = subprocess.Popen(check_command,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)
            check_process.communicate()  # read output, but ignore it...
            isnt_running = check_process.wait()

            if not isnt_running:
                # Our double-check found that the master _was_ infact running.  Add to
                # the list of keys.
                self._master_keys[key] = True
                return True
        except Exception:
            # Ignore excpetions.  We we will fall back to the normal command and print
            # to the log there.
            pass

        command = command_base[:1] + ['-M', '-N'] + command_base[1:]
        try:
            Trace(': %s', ' '.join(command))
            p = subprocess.Popen(command)
        except Exception as e:
            self._master_broken.value = True
            print('\nwarn: cannot enable ssh control master for %s:%s\n%s' %
                  (host, port, str(e)),
                  file=sys.stderr)
            return False

        time.sleep(1)
        ssh_died = (p.poll() is not None)
        if ssh_died:
            return False

        self.add_master(p)
        self._master_keys[key] = True
        return True
コード例 #6
0
def _open_ssh(host, port=None):
  global _ssh_master

  # Acquire the lock.  This is needed to prevent opening multiple masters for
  # the same host when we're running "repo sync -jN" (for N > 1) _and_ the
  # manifest <remote fetch="ssh://xyz"> specifies a different host from the
  # one that was passed to repo init.
  _master_keys_lock.acquire()
  try:

    # Check to see whether we already think that the master is running; if we
    # think it's already running, return right away.
    if port is not None:
      key = '%s:%s' % (host, port)
    else:
      key = host

    if key in _master_keys:
      return True

    if (not _ssh_master
            or 'GIT_SSH' in os.environ
            or sys.platform in ('win32', 'cygwin')):
      # failed earlier, or cygwin ssh can't do this
      #
      return False

    # We will make two calls to ssh; this is the common part of both calls.
    command_base = ['ssh',
                    '-o', 'ControlPath %s' % ssh_sock(),
                    host]
    if port is not None:
      command_base[1:1] = ['-p', str(port)]

    # Since the key wasn't in _master_keys, we think that master isn't running.
    # ...but before actually starting a master, we'll double-check.  This can
    # be important because we can't tell that that '*****@*****.**' is the same
    # as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file.
    check_command = command_base + ['-O', 'check']
    try:
      Trace(': %s', ' '.join(check_command))
      check_process = subprocess.Popen(check_command,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
      check_process.communicate()  # read output, but ignore it...
      isnt_running = check_process.wait()

      if not isnt_running:
        # Our double-check found that the master _was_ infact running.  Add to
        # the list of keys.
        _master_keys.add(key)
        return True
    except Exception:
      # Ignore excpetions.  We we will fall back to the normal command and print
      # to the log there.
      pass

    command = command_base[:1] + ['-M', '-N'] + command_base[1:]
    try:
      Trace(': %s', ' '.join(command))
      p = subprocess.Popen(command)
    except Exception as e:
      _ssh_master = False
      print('\nwarn: cannot enable ssh control master for %s:%s\n%s'
            % (host, port, str(e)), file=sys.stderr)
      return False

    time.sleep(1)
    ssh_died = (p.poll() is not None)
    if ssh_died:
      return False

    _master_processes.append(p)
    _master_keys.add(key)
    return True
  finally:
    _master_keys_lock.release()
コード例 #7
0
ファイル: git_command.py プロジェクト: oux/google-repo
    def __init__(self,
                 project,
                 cmdv,
                 bare=False,
                 provide_stdin=False,
                 capture_stdout=False,
                 capture_stderr=False,
                 merge_output=False,
                 disable_editor=False,
                 ssh_proxy=False,
                 cwd=None,
                 gitdir=None):
        env = self._GetBasicEnv()

        # If we are not capturing std* then need to print it.
        self.tee = {'stdout': not capture_stdout, 'stderr': not capture_stderr}

        if disable_editor:
            env['GIT_EDITOR'] = ':'
        if ssh_proxy:
            env['REPO_SSH_SOCK'] = ssh_sock()
            env['GIT_SSH'] = _ssh_proxy()
            env['GIT_SSH_VARIANT'] = 'ssh'
        if 'http_proxy' in env and 'darwin' == sys.platform:
            s = "'http.proxy=%s'" % (env['http_proxy'], )
            p = env.get('GIT_CONFIG_PARAMETERS')
            if p is not None:
                s = p + ' ' + s
            env['GIT_CONFIG_PARAMETERS'] = s
        if 'GIT_ALLOW_PROTOCOL' not in env:
            env['GIT_ALLOW_PROTOCOL'] = (
                'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc'
            )
        env['GIT_HTTP_USER_AGENT'] = user_agent.git

        if project:
            if not cwd:
                cwd = project.worktree
            if not gitdir:
                gitdir = project.gitdir

        command = [GIT]
        if bare:
            if gitdir:
                env[GIT_DIR] = gitdir
            cwd = None
        command.append(cmdv[0])
        # Need to use the --progress flag for fetch/clone so output will be
        # displayed as by default git only does progress output if stderr is a TTY.
        if sys.stderr.isatty() and cmdv[0] in ('fetch', 'clone'):
            if '--progress' not in cmdv and '--quiet' not in cmdv:
                command.append('--progress')
        command.extend(cmdv[1:])

        if provide_stdin:
            stdin = subprocess.PIPE
        else:
            stdin = None

        stdout = subprocess.PIPE
        stderr = subprocess.STDOUT if merge_output else subprocess.PIPE

        if IsTrace():
            global LAST_CWD
            global LAST_GITDIR

            dbg = ''

            if cwd and LAST_CWD != cwd:
                if LAST_GITDIR or LAST_CWD:
                    dbg += '\n'
                dbg += ': cd %s\n' % cwd
                LAST_CWD = cwd

            if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]:
                if LAST_GITDIR or LAST_CWD:
                    dbg += '\n'
                dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR]
                LAST_GITDIR = env[GIT_DIR]

            dbg += ': '
            dbg += ' '.join(command)
            if stdin == subprocess.PIPE:
                dbg += ' 0<|'
            if stdout == subprocess.PIPE:
                dbg += ' 1>|'
            if stderr == subprocess.PIPE:
                dbg += ' 2>|'
            elif stderr == subprocess.STDOUT:
                dbg += ' 2>&1'
            Trace('%s', dbg)

        try:
            p = subprocess.Popen(command,
                                 cwd=cwd,
                                 env=env,
                                 stdin=stdin,
                                 stdout=stdout,
                                 stderr=stderr)
        except Exception as e:
            raise GitError('%s: %s' % (command[1], e))

        if ssh_proxy:
            _add_ssh_client(p)

        self.process = p
        self.stdin = p.stdin