Beispiel #1
0
    def __init__(self, repodir):
        Manifest.__init__(self, repodir)

        gitdir = os.path.join(repodir, 'manifest.git')
        config = GitConfig.ForRepository(gitdir=gitdir)

        if config.GetBoolean('repo.mirror'):
            worktree = os.path.join(repodir, 'manifest')
            relpath = None
        else:
            worktree = self.topdir
            relpath = '.'

        self.manifestProject = MetaProject(self,
                                           '__manifest__',
                                           gitdir=gitdir,
                                           worktree=worktree,
                                           relpath=relpath)
        self._modules = GitConfig(os.path.join(worktree, '.gitmodules'),
                                  pickleFile=os.path.join(
                                      repodir, '.repopickle_gitmodules'))
        self._review = GitConfig(os.path.join(worktree, '.review'),
                                 pickleFile=os.path.join(
                                     repodir, '.repopickle_review'))
        self._Unload()
Beispiel #2
0
    def __init__(self, repodir):
        self.repodir = os.path.abspath(repodir)
        self.topdir = os.path.dirname(self.repodir)
        self.manifestFile = os.path.join(self.repodir, MANIFEST_FILE_NAME)
        self.globalConfig = GitConfig.ForUser()
        self.localManifestWarning = False
        self.isGitcClient = False
        self._load_local_manifests = True

        self.repoProject = MetaProject(self,
                                       'repo',
                                       gitdir=os.path.join(
                                           repodir, 'repo/.git'),
                                       worktree=os.path.join(repodir, 'repo'))

        mp = MetaProject(self,
                         'manifests',
                         gitdir=os.path.join(repodir, 'manifests.git'),
                         worktree=os.path.join(repodir, 'manifests'))
        self.manifestProject = mp

        # This is a bit hacky, but we're in a chicken & egg situation: all the
        # normal repo settings live in the manifestProject which we just setup
        # above, so we couldn't easily query before that.  We assume Project()
        # init doesn't care if this changes afterwards.
        if os.path.exists(mp.gitdir) and mp.config.GetBoolean('repo.worktree'):
            mp.use_git_worktrees = True

        self._Unload()
Beispiel #3
0
    def __init__(self, manifest, name, remote, gitdir, worktree, relpath,
                 revisionExpr, revisionId):
        self.manifest = manifest
        self.name = name
        self.remote = remote
        self.gitdir = gitdir.replace('\\', '/')
        if worktree:
            self.worktree = worktree.replace('\\', '/')
        else:
            self.worktree = None
        self.relpath = relpath
        self.revisionExpr = revisionExpr

        if   revisionId is None \
         and revisionExpr \
         and IsId(revisionExpr):
            self.revisionId = revisionExpr
        else:
            self.revisionId = revisionId

        self.snapshots = {}
        self.copyfiles = []
        self.config = GitConfig.ForRepository(
            gitdir=self.gitdir, defaults=self.manifest.globalConfig)

        if self.worktree:
            self.work_git = self._GitGetByExec(self, bare=False)
        else:
            self.work_git = None
        self.bare_git = self._GitGetByExec(self, bare=True)
        self.bare_ref = GitRefs(gitdir)
Beispiel #4
0
    def _SyncManifest(self, opt):
        m = self.manifest.manifestProject
        is_new = not m.Exists

        if is_new:
            if not opt.manifest_url:
                print >> sys.stderr, 'fatal: manifest url (-u) is required.'
                sys.exit(1)

            if not opt.quiet:
                print >>sys.stderr, 'Get %s' \
                  % GitConfig.ForUser().UrlInsteadOf(opt.manifest_url)
            m._InitGitDir()

            if opt.manifest_branch:
                m.revisionExpr = opt.manifest_branch
            else:
                m.revisionExpr = 'refs/heads/master'
        else:
            if opt.manifest_branch:
                m.revisionExpr = opt.manifest_branch
            else:
                m.PreSync()

        if opt.manifest_url:
            r = m.GetRemote(m.remote.name)
            r.url = opt.manifest_url
            r.ResetFetch()
            r.Save()

        if opt.reference:
            m.config.SetString('repo.reference', opt.reference)

        if opt.mirror:
            if is_new:
                m.config.SetString('repo.mirror', 'true')
            else:
                print >> sys.stderr, 'fatal: --mirror not supported on existing client'
                sys.exit(1)

        if not m.Sync_NetworkHalf(is_new=is_new):
            r = m.GetRemote(m.remote.name)
            print >> sys.stderr, 'fatal: cannot obtain manifest %s' % r.url

            # Better delete the manifest git dir if we created it; otherwise next
            # time (when user fixes problems) we won't go through the "is_new" logic.
            if is_new:
                shutil.rmtree(m.gitdir)
            sys.exit(1)

        syncbuf = SyncBuffer(m.config)
        m.Sync_LocalHalf(syncbuf)
        syncbuf.Finish()

        if is_new or m.CurrentBranch is None:
            if not m.StartBranch('default'):
                print >> sys.stderr, 'fatal: cannot create default in manifest'
                sys.exit(1)
Beispiel #5
0
  def __init__(self, repodir):
    self.repodir = os.path.abspath(repodir)
    self.topdir = os.path.dirname(self.repodir)
    self.globalConfig = GitConfig.ForUser()
    Editor.globalConfig = self.globalConfig

    self.repoProject = MetaProject(self, 'repo',
      gitdir   = os.path.join(repodir, 'repo/.git'),
      worktree = os.path.join(repodir, 'repo'))
Beispiel #6
0
def push(repo_dir, refs):
    root = repo_dir
    cfg = GitConfig(root)
    url = cfg.get_remote_url()
    fetch = cfg.get_fetch()
    transport = S3Transport(url)

    advertised_refs = transport.get_advertised_refs()

    if len(advertised_refs) == 0:
        transport.create_new_repo(refs)

    client = Gits3(root)
    tracking_ref = client.find_tracking_ref_names(fetch, refs)

    updated_objects = client.get_updates(refs, tracking_ref)

    if updated_objects == None:
        print 'Up to date'
    else:
        base = client.generate_pack_name(updated_objects)

        client.write_pack(base, updated_objects)

        pack_name = 'pack-' + base + '.pack'
        transport.upload_pack(pack_name)
        transport.upload_pack('pack-' + base + '.idx')

        packs = transport.get_pack_names()
        packs_str = 'P ' + pack_name + '\n'
        for pack in packs:
            packs_str = packs_str + 'P ' + pack + '\n'

        print packs_str

        transport.upload_string('objects/info/packs', packs_str)
        transport.upload_string(refs, client.get_id(refs))
        upload_string = "{0}\t{1}\n".format(client.get_id(refs), refs)
        transport.upload_string('info/refs', upload_string)
Beispiel #7
0
  def __init__(self, repodir):
    self.repodir = os.path.abspath(repodir)
    self.topdir = os.path.dirname(self.repodir)
    self.manifestFile = os.path.join(self.repodir, MANIFEST_FILE_NAME)
    self.globalConfig = GitConfig.ForUser()

    self.repoProject = MetaProject(self, 'repo',
      gitdir   = os.path.join(repodir, 'repo/.git'),
      worktree = os.path.join(repodir, 'repo'))

    self.manifestProject = MetaProject(self, 'manifests',
      gitdir   = os.path.join(repodir, 'manifests.git'),
      worktree = os.path.join(repodir, 'manifests'))

    self._Unload()
Beispiel #8
0
  def __init__(self, repodir, manifest_file, local_manifests=None):
    """Initialize.

    Args:
      repodir: Path to the .repo/ dir for holding all internal checkout state.
          It must be in the top directory of the repo client checkout.
      manifest_file: Full path to the manifest file to parse.  This will usually
          be |repodir|/|MANIFEST_FILE_NAME|.
      local_manifests: Full path to the directory of local override manifests.
          This will usually be |repodir|/|LOCAL_MANIFESTS_DIR_NAME|.
    """
    # TODO(vapier): Move this out of this class.
    self.globalConfig = GitConfig.ForUser()

    self.repodir = os.path.abspath(repodir)
    self.topdir = os.path.dirname(self.repodir)
    self.manifestFile = manifest_file
    self.local_manifests = local_manifests
    self._load_local_manifests = True

    self.repoProject = MetaProject(self, 'repo',
                                   gitdir=os.path.join(repodir, 'repo/.git'),
                                   worktree=os.path.join(repodir, 'repo'))

    mp = MetaProject(self, 'manifests',
                     gitdir=os.path.join(repodir, 'manifests.git'),
                     worktree=os.path.join(repodir, 'manifests'))
    self.manifestProject = mp

    # This is a bit hacky, but we're in a chicken & egg situation: all the
    # normal repo settings live in the manifestProject which we just setup
    # above, so we couldn't easily query before that.  We assume Project()
    # init doesn't care if this changes afterwards.
    if os.path.exists(mp.gitdir) and mp.config.GetBoolean('repo.worktree'):
      mp.use_git_worktrees = True

    self._Unload()
Beispiel #9
0
    def _SyncManifest(self, opt):
        m = self.manifest.manifestProject
        is_new = not m.Exists

        if is_new:
            if not opt.manifest_url:
                print >> sys.stderr, 'fatal: manifest url (-u) is required.'
                sys.exit(1)

            if not opt.quiet:
                print >>sys.stderr, 'Get %s' \
                  % GitConfig.ForUser().UrlInsteadOf(opt.manifest_url)
            m._InitGitDir()

            if opt.manifest_branch:
                m.revisionExpr = opt.manifest_branch
            else:
                m.revisionExpr = 'refs/heads/master'
        else:
            if opt.manifest_branch:
                m.revisionExpr = opt.manifest_branch
            else:
                m.PreSync()

        if opt.manifest_url:
            r = m.GetRemote(m.remote.name)
            r.url = opt.manifest_url
            r.ResetFetch()
            r.Save()

        groups = re.split('[,\s]+', opt.groups)
        all_platforms = ['linux', 'darwin']
        platformize = lambda x: 'platform-' + x
        if opt.platform == 'auto':
            if (not opt.mirror
                    and not m.config.GetString('repo.mirror') == 'true'):
                groups.append(platformize(platform.system().lower()))
        elif opt.platform == 'all':
            groups.extend(map(platformize, all_platforms))
        elif opt.platform in all_platforms:
            groups.extend(platformize(opt.platform))
        elif opt.platform != 'none':
            print >> sys.stderr, 'fatal: invalid platform flag'
            sys.exit(1)

        groups = [x for x in groups if x]
        groupstr = ','.join(groups)
        if opt.platform == 'auto' and groupstr == 'all,-notdefault,platform-' + platform.system(
        ).lower():
            groupstr = None
        m.config.SetString('manifest.groups', groupstr)

        if opt.reference:
            m.config.SetString('repo.reference', opt.reference)

        if opt.mirror:
            if is_new:
                m.config.SetString('repo.mirror', 'true')
            else:
                print >> sys.stderr, 'fatal: --mirror not supported on existing client'
                sys.exit(1)

        if not m.Sync_NetworkHalf(is_new=is_new):
            r = m.GetRemote(m.remote.name)
            print >> sys.stderr, 'fatal: cannot obtain manifest %s' % r.url

            # Better delete the manifest git dir if we created it; otherwise next
            # time (when user fixes problems) we won't go through the "is_new" logic.
            if is_new:
                shutil.rmtree(m.gitdir)
            sys.exit(1)

        if opt.manifest_branch:
            m.MetaBranchSwitch(opt.manifest_branch)

        syncbuf = SyncBuffer(m.config)
        m.Sync_LocalHalf(syncbuf)
        syncbuf.Finish()

        if is_new or m.CurrentBranch is None:
            if not m.StartBranch('default'):
                print >> sys.stderr, 'fatal: cannot create default in manifest'
                sys.exit(1)
Beispiel #10
0
    def _SyncManifest(self, opt):
        m = self.manifest.manifestProject
        is_new = not m.Exists

        if is_new:
            if not opt.manifest_url:
                print('fatal: manifest url (-u) is required.', file=sys.stderr)
                sys.exit(1)

            if not opt.quiet:
                print('Get %s' %
                      GitConfig.ForUser().UrlInsteadOf(opt.manifest_url),
                      file=sys.stderr)

            # The manifest project object doesn't keep track of the path on the
            # server where this git is located, so let's save that here.
            mirrored_manifest_git = None
            if opt.reference:
                manifest_git_path = urllib.parse.urlparse(
                    opt.manifest_url).path[1:]
                mirrored_manifest_git = os.path.join(opt.reference,
                                                     manifest_git_path)
                if not mirrored_manifest_git.endswith(".git"):
                    mirrored_manifest_git += ".git"
                if not os.path.exists(mirrored_manifest_git):
                    mirrored_manifest_git = os.path.join(
                        opt.reference + '/.repo/manifests.git')

            m._InitGitDir(mirror_git=mirrored_manifest_git)

            if opt.manifest_branch:
                m.revisionExpr = opt.manifest_branch
            else:
                m.revisionExpr = 'refs/heads/master'
        else:
            if opt.manifest_branch:
                m.revisionExpr = opt.manifest_branch
            else:
                m.PreSync()

        if opt.manifest_url:
            r = m.GetRemote(m.remote.name)
            r.url = opt.manifest_url
            r.ResetFetch()
            r.Save()

        groups = re.split(r'[,\s]+', opt.groups)
        all_platforms = ['linux', 'darwin', 'windows']
        platformize = lambda x: 'platform-' + x
        if opt.platform == 'auto':
            if (not opt.mirror
                    and not m.config.GetString('repo.mirror') == 'true'):
                groups.append(platformize(platform.system().lower()))
        elif opt.platform == 'all':
            groups.extend(map(platformize, all_platforms))
        elif opt.platform in all_platforms:
            groups.append(platformize(opt.platform))
        elif opt.platform != 'none':
            print('fatal: invalid platform flag', file=sys.stderr)
            sys.exit(1)

        groups = [x for x in groups if x]
        groupstr = ','.join(groups)
        if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system(
        ).lower():
            groupstr = None
        m.config.SetString('manifest.groups', groupstr)

        if opt.reference:
            m.config.SetString('repo.reference', opt.reference)

        if opt.archive:
            if is_new:
                m.config.SetString('repo.archive', 'true')
            else:
                print(
                    'fatal: --archive is only supported when initializing a new '
                    'workspace.',
                    file=sys.stderr)
                print(
                    'Either delete the .repo folder in this workspace, or initialize '
                    'in another location.',
                    file=sys.stderr)
                sys.exit(1)

        if opt.mirror:
            if is_new:
                m.config.SetString('repo.mirror', 'true')
            else:
                print(
                    'fatal: --mirror is only supported when initializing a new '
                    'workspace.',
                    file=sys.stderr)
                print(
                    'Either delete the .repo folder in this workspace, or initialize '
                    'in another location.',
                    file=sys.stderr)
                sys.exit(1)

        if not m.Sync_NetworkHalf(is_new=is_new,
                                  quiet=opt.quiet,
                                  clone_bundle=not opt.no_clone_bundle):
            r = m.GetRemote(m.remote.name)
            print('fatal: cannot obtain manifest %s' % r.url, file=sys.stderr)

            # Better delete the manifest git dir if we created it; otherwise next
            # time (when user fixes problems) we won't go through the "is_new" logic.
            if is_new:
                shutil.rmtree(m.gitdir)
            sys.exit(1)

        if opt.manifest_branch:
            m.MetaBranchSwitch()

        syncbuf = SyncBuffer(m.config)
        m.Sync_LocalHalf(syncbuf)
        syncbuf.Finish()

        if is_new or m.CurrentBranch is None:
            if not m.StartBranch('default'):
                print('fatal: cannot create default in manifest',
                      file=sys.stderr)
                sys.exit(1)
Beispiel #11
0
class SubmoduleManifest(Manifest):
    """manifest from .gitmodules file"""
    @classmethod
    def Is(cls, repodir):
        return _has_gitmodules(os.path.dirname(repodir)) \
            or _has_gitmodules(os.path.join(repodir, 'manifest')) \
            or _has_gitmodules(os.path.join(repodir, 'manifests'))

    @classmethod
    def IsBare(cls, p):
        try:
            p.bare_git.cat_file('-e', '%s:.gitmodules' % p.GetRevisionId())
        except GitError:
            return False
        return True

    def __init__(self, repodir):
        Manifest.__init__(self, repodir)

        gitdir = os.path.join(repodir, 'manifest.git')
        config = GitConfig.ForRepository(gitdir=gitdir)

        if config.GetBoolean('repo.mirror'):
            worktree = os.path.join(repodir, 'manifest')
            relpath = None
        else:
            worktree = self.topdir
            relpath = '.'

        self.manifestProject = MetaProject(self,
                                           '__manifest__',
                                           gitdir=gitdir,
                                           worktree=worktree,
                                           relpath=relpath)
        self._modules = GitConfig(os.path.join(worktree, '.gitmodules'),
                                  pickleFile=os.path.join(
                                      repodir, '.repopickle_gitmodules'))
        self._review = GitConfig(os.path.join(worktree, '.review'),
                                 pickleFile=os.path.join(
                                     repodir, '.repopickle_review'))
        self._Unload()

    @property
    def projects(self):
        self._Load()
        return self._projects

    @property
    def notice(self):
        return self._modules.GetString('repo.notice')

    def InitBranch(self):
        m = self.manifestProject
        if m.CurrentBranch is None:
            b = m.revisionExpr
            if b.startswith(R_HEADS):
                b = b[len(R_HEADS):]
            return m.StartBranch(b)
        return True

    def SetMRefs(self, project):
        if project.revisionId is None:
            # Special project, e.g. the manifest or repo executable.
            #
            return

        ref = 'refs/remotes/m'
        cur = project.bare_ref.get(ref)
        exp = project.revisionId
        if cur != exp:
            msg = 'manifest set to %s' % exp
            project.bare_git.UpdateRef(ref, exp, message=msg, detach=True)

        ref = 'refs/remotes/m-revision'
        cur = project.bare_ref.symref(ref)
        exp = project.revisionExpr
        if exp is None:
            if cur:
                _rmref(project.gitdir, ref)
        elif cur != exp:
            remote = project.GetRemote(project.remote.name)
            dst = remote.ToLocal(exp)
            msg = 'manifest set to %s (%s)' % (exp, dst)
            project.bare_git.symbolic_ref('-m', msg, ref, dst)

    def Upgrade_Local(self, old):
        if isinstance(old, manifest_xml.XmlManifest):
            self.FromXml_Local_1(old, checkout=True)
            self.FromXml_Local_2(old)
        else:
            raise ManifestParseError, 'cannot upgrade manifest'

    def FromXml_Local_1(self, old, checkout):
        os.rename(old.manifestProject.gitdir,
                  os.path.join(old.repodir, 'manifest.git'))

        oldmp = old.manifestProject
        oldBranch = oldmp.CurrentBranch
        b = oldmp.GetBranch(oldBranch).merge
        if not b:
            raise ManifestParseError, 'cannot upgrade manifest'
        if b.startswith(R_HEADS):
            b = b[len(R_HEADS):]

        newmp = self.manifestProject
        self._CleanOldMRefs(newmp)
        if oldBranch != b:
            newmp.bare_git.branch('-m', oldBranch, b)
            newmp.config.ClearCache()

        old_remote = newmp.GetBranch(b).remote.name
        act_remote = self._GuessRemoteName(old)
        if old_remote != act_remote:
            newmp.bare_git.remote('rename', old_remote, act_remote)
            newmp.config.ClearCache()
        newmp.remote.name = act_remote
        print >> sys.stderr, "Assuming remote named '%s'" % act_remote

        if checkout:
            for p in old.projects.values():
                for c in p.copyfiles:
                    if os.path.exists(c.abs_dest):
                        os.remove(c.abs_dest)
            newmp._InitWorkTree()
        else:
            newmp._LinkWorkTree()

        _lwrite(os.path.join(newmp.worktree, '.git', HEAD),
                'ref: refs/heads/%s\n' % b)

    def _GuessRemoteName(self, old):
        used = {}
        for p in old.projects.values():
            n = p.remote.name
            used[n] = used.get(n, 0) + 1

        remote_name = 'origin'
        remote_used = 0
        for n in used.keys():
            if remote_used < used[n]:
                remote_used = used[n]
                remote_name = n
        return remote_name

    def FromXml_Local_2(self, old):
        shutil.rmtree(old.manifestProject.worktree)
        os.remove(old._manifestFile)

        my_remote = self._Remote().name
        new_base = os.path.join(self.repodir, 'projects')
        old_base = os.path.join(self.repodir, 'projects.old')
        os.rename(new_base, old_base)
        os.makedirs(new_base)

        info = []
        pm = Progress('Converting projects', len(self.projects))
        for p in self.projects.values():
            pm.update()

            old_p = old.projects.get(p.name)
            old_gitdir = os.path.join(old_base, '%s.git' % p.relpath)
            if not os.path.isdir(old_gitdir):
                continue

            parent = os.path.dirname(p.gitdir)
            if not os.path.isdir(parent):
                os.makedirs(parent)
            os.rename(old_gitdir, p.gitdir)
            _rmdir(os.path.dirname(old_gitdir), self.repodir)

            if not os.path.isdir(p.worktree):
                os.makedirs(p.worktree)

            if os.path.isdir(os.path.join(p.worktree, '.git')):
                p._LinkWorkTree(relink=True)

            self._CleanOldMRefs(p)
            if old_p and old_p.remote.name != my_remote:
                info.append("%s/: renamed remote '%s' to '%s'" \
                            % (p.relpath, old_p.remote.name, my_remote))
                p.bare_git.remote('rename', old_p.remote.name, my_remote)
                p.config.ClearCache()

            self.SetMRefs(p)
        pm.end()
        for i in info:
            print >> sys.stderr, i

    def _CleanOldMRefs(self, p):
        all_refs = p._allrefs
        for ref in all_refs.keys():
            if ref.startswith(manifest_xml.R_M):
                if p.bare_ref.symref(ref) != '':
                    _rmref(p.gitdir, ref)
                else:
                    p.bare_git.DeleteRef(ref, all_refs[ref])

    def FromXml_Definition(self, old):
        """Convert another manifest representation to this one.
    """
        mp = self.manifestProject
        gm = self._modules
        gr = self._review

        fd = open(os.path.join(mp.worktree, '.gitignore'), 'ab')
        fd.write('/.repo\n')
        fd.close()

        sort_projects = list(old.projects.keys())
        sort_projects.sort()

        b = mp.GetBranch(mp.CurrentBranch).merge
        if b.startswith(R_HEADS):
            b = b[len(R_HEADS):]

        if old.notice:
            gm.SetString('repo.notice', old.notice)

        info = []
        pm = Progress('Converting manifest', len(sort_projects))
        for p in sort_projects:
            pm.update()
            p = old.projects[p]

            gm.SetString('submodule.%s.path' % p.name, p.relpath)
            gm.SetString('submodule.%s.url' % p.name, p.remote.url)

            if gr.GetString('review.url') is None:
                gr.SetString('review.url', p.remote.review)
            elif gr.GetString('review.url') != p.remote.review:
                gr.SetString('review.%s.url' % p.name, p.remote.review)

            r = p.revisionExpr
            if r and not IsId(r):
                if r.startswith(R_HEADS):
                    r = r[len(R_HEADS):]
                if r == b:
                    r = '.'
                gm.SetString('submodule.%s.revision' % p.name, r)

            for c in p.copyfiles:
                info.append('Moved %s out of %s' % (c.src, p.relpath))
                c._Copy()
                p.work_git.rm(c.src)
                mp.work_git.add(c.dest)

            self.SetRevisionId(p.relpath, p.GetRevisionId())
        mp.work_git.add('.gitignore', '.gitmodules', '.review')
        pm.end()
        for i in info:
            print >> sys.stderr, i

    def _Unload(self):
        self._loaded = False
        self._projects = {}
        self._revisionIds = None
        self.branch = None

    def _Load(self):
        if not self._loaded:
            f = os.path.join(self.repodir, manifest_xml.LOCAL_MANIFEST_NAME)
            if os.path.exists(f):
                print >> sys.stderr, 'warning: ignoring %s' % f

            m = self.manifestProject
            b = m.CurrentBranch
            if not b:
                raise ManifestParseError, 'manifest cannot be on detached HEAD'
            b = m.GetBranch(b).merge
            if b.startswith(R_HEADS):
                b = b[len(R_HEADS):]
            self.branch = b
            m.remote.name = self._Remote().name

            self._ParseModules()

            if self.IsMirror:
                self._AddMetaProjectMirror(self.repoProject)
                self._AddMetaProjectMirror(self.manifestProject)

            self._loaded = True

    def _ParseModules(self):
        byPath = dict()
        for name in self._modules.GetSubSections('submodule'):
            p = self._ParseProject(name)
            if self._projects.get(p.name):
                raise ManifestParseError, 'duplicate project "%s"' % p.name
            if byPath.get(p.relpath):
                raise ManifestParseError, 'duplicate path "%s"' % p.relpath
            self._projects[p.name] = p
            byPath[p.relpath] = p

        for relpath in self._allRevisionIds.keys():
            if relpath not in byPath:
                raise ManifestParseError, \
                  'project "%s" not in .gitmodules' \
                  % relpath

    def _Remote(self):
        m = self.manifestProject
        b = m.GetBranch(m.CurrentBranch)
        return b.remote

    def _ResolveUrl(self, url):
        if url.startswith('./') or url.startswith('../'):
            base = self._Remote().url
            try:
                base = base[:base.rindex('/') + 1]
            except ValueError:
                base = base[:base.rindex(':') + 1]
            if url.startswith('./'):
                url = url[2:]
            while '/' in base and url.startswith('../'):
                base = base[:base.rindex('/') + 1]
                url = url[3:]
            return base + url
        return url

    def _GetRevisionId(self, path):
        return self._allRevisionIds.get(path)

    @property
    def _allRevisionIds(self):
        if self._revisionIds is None:
            a = dict()
            p = GitCommand(self.manifestProject, ['ls-files', '-z', '--stage'],
                           capture_stdout=True)
            for line in p.process.stdout.read().split('\0')[:-1]:
                l_info, l_path = line.split('\t', 2)
                l_mode, l_id, l_stage = l_info.split(' ', 2)
                if l_mode == GITLINK and l_stage == '0':
                    a[l_path] = l_id
            p.Wait()
            self._revisionIds = a
        return self._revisionIds

    def SetRevisionId(self, path, id):
        self.manifestProject.work_git.update_index('--add', '--cacheinfo',
                                                   GITLINK, id, path)

    def _ParseProject(self, name):
        gm = self._modules
        gr = self._review

        path = gm.GetString('submodule.%s.path' % name)
        if not path:
            path = name

        revId = self._GetRevisionId(path)
        if not revId:
            raise ManifestParseError(
              'submodule "%s" has no revision at "%s"' \
              % (name, path))

        url = gm.GetString('submodule.%s.url' % name)
        if not url:
            url = name
        url = self._ResolveUrl(url)

        review = gr.GetString('review.%s.url' % name)
        if not review:
            review = gr.GetString('review.url')
        if not review:
            review = self._Remote().review

        remote = RemoteSpec(self._Remote().name, url, review)
        revExpr = gm.GetString('submodule.%s.revision' % name)
        if revExpr == '.':
            revExpr = self.branch

        if self.IsMirror:
            relpath = None
            worktree = None
            gitdir = os.path.join(self.topdir, '%s.git' % name)
        else:
            worktree = os.path.join(self.topdir, path)
            gitdir = os.path.join(self.repodir, 'projects/%s.git' % name)

        return Project(manifest=self,
                       name=name,
                       remote=remote,
                       gitdir=gitdir,
                       worktree=worktree,
                       relpath=path,
                       revisionExpr=revExpr,
                       revisionId=revId)

    def _AddMetaProjectMirror(self, m):
        m_url = m.GetRemote(m.remote.name).url
        if m_url.endswith('/.git'):
            raise ManifestParseError, 'refusing to mirror %s' % m_url

        name = self._GuessMetaName(m_url)
        if name.endswith('.git'):
            name = name[:-4]

        if name not in self._projects:
            m.PreSync()
            gitdir = os.path.join(self.topdir, '%s.git' % name)
            project = Project(manifest=self,
                              name=name,
                              remote=RemoteSpec(self._Remote().name, m_url),
                              gitdir=gitdir,
                              worktree=None,
                              relpath=None,
                              revisionExpr=m.revisionExpr,
                              revisionId=None)
            self._projects[project.name] = project

    def _GuessMetaName(self, m_url):
        parts = m_url.split('/')
        name = parts[-1]
        parts = parts[0:-1]
        s = len(parts) - 1
        while s > 0:
            l = '/'.join(parts[0:s]) + '/'
            r = '/'.join(parts[s:]) + '/'
            for p in self._projects.values():
                if p.name.startswith(r) and p.remote.url.startswith(l):
                    return r + name
            s -= 1
        return m_url[m_url.rindex('/') + 1:]
Beispiel #12
0
  def _SyncManifest(self, opt):
    m = self.manifest.manifestProject
    is_new = not m.Exists

    if is_new:
      if not opt.manifest_url:
        print('fatal: manifest url (-u) is required.', file=sys.stderr)
        sys.exit(1)

      if not opt.quiet:
        print('Downloading manifest from %s' %
              (GitConfig.ForUser().UrlInsteadOf(opt.manifest_url),),
              file=sys.stderr)

      # The manifest project object doesn't keep track of the path on the
      # server where this git is located, so let's save that here.
      mirrored_manifest_git = None
      if opt.reference:
        manifest_git_path = urllib.parse.urlparse(opt.manifest_url).path[1:]
        mirrored_manifest_git = os.path.join(opt.reference, manifest_git_path)
        if not mirrored_manifest_git.endswith(".git"):
          mirrored_manifest_git += ".git"
        if not os.path.exists(mirrored_manifest_git):
          mirrored_manifest_git = os.path.join(opt.reference,
                                               '.repo/manifests.git')

      m._InitGitDir(mirror_git=mirrored_manifest_git)

    self._ConfigureDepth(opt)

    # Set the remote URL before the remote branch as we might need it below.
    if opt.manifest_url:
      r = m.GetRemote(m.remote.name)
      r.url = opt.manifest_url
      r.ResetFetch()
      r.Save()

    if opt.manifest_branch:
      m.revisionExpr = opt.manifest_branch
    else:
      if is_new:
        default_branch = m.ResolveRemoteHead()
        if default_branch is None:
          # If the remote doesn't have HEAD configured, default to master.
          default_branch = 'refs/heads/master'
        m.revisionExpr = default_branch
      else:
        m.PreSync()

    groups = re.split(r'[,\s]+', opt.groups)
    all_platforms = ['linux', 'darwin', 'windows']
    platformize = lambda x: 'platform-' + x
    if opt.platform == 'auto':
      if (not opt.mirror and
              not m.config.GetString('repo.mirror') == 'true'):
        groups.append(platformize(platform.system().lower()))
    elif opt.platform == 'all':
      groups.extend(map(platformize, all_platforms))
    elif opt.platform in all_platforms:
      groups.append(platformize(opt.platform))
    elif opt.platform != 'none':
      print('fatal: invalid platform flag', file=sys.stderr)
      sys.exit(1)

    groups = [x for x in groups if x]
    groupstr = ','.join(groups)
    if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system().lower():
      groupstr = None
    m.config.SetString('manifest.groups', groupstr)

    if opt.reference:
      m.config.SetString('repo.reference', opt.reference)

    if opt.dissociate:
      m.config.SetString('repo.dissociate', 'true')

    if opt.worktree:
      if opt.mirror:
        print('fatal: --mirror and --worktree are incompatible',
              file=sys.stderr)
        sys.exit(1)
      if opt.submodules:
        print('fatal: --submodules and --worktree are incompatible',
              file=sys.stderr)
        sys.exit(1)
      m.config.SetString('repo.worktree', 'true')
      if is_new:
        m.use_git_worktrees = True
      print('warning: --worktree is experimental!', file=sys.stderr)

    if opt.archive:
      if is_new:
        m.config.SetString('repo.archive', 'true')
      else:
        print('fatal: --archive is only supported when initializing a new '
              'workspace.', file=sys.stderr)
        print('Either delete the .repo folder in this workspace, or initialize '
              'in another location.', file=sys.stderr)
        sys.exit(1)

    if opt.mirror:
      if is_new:
        m.config.SetString('repo.mirror', 'true')
      else:
        print('fatal: --mirror is only supported when initializing a new '
              'workspace.', file=sys.stderr)
        print('Either delete the .repo folder in this workspace, or initialize '
              'in another location.', file=sys.stderr)
        sys.exit(1)

    if opt.partial_clone:
      if opt.mirror:
        print('fatal: --mirror and --partial-clone are mutually exclusive',
              file=sys.stderr)
        sys.exit(1)
      m.config.SetString('repo.partialclone', 'true')
      if opt.clone_filter:
        m.config.SetString('repo.clonefilter', opt.clone_filter)
    else:
      opt.clone_filter = None

    if opt.clone_bundle is None:
      opt.clone_bundle = False if opt.partial_clone else True
    else:
      m.config.SetString('repo.clonebundle', 'true' if opt.clone_bundle else 'false')

    if opt.submodules:
      m.config.SetString('repo.submodules', 'true')

    if not m.Sync_NetworkHalf(is_new=is_new, quiet=opt.quiet, verbose=opt.verbose,
                              clone_bundle=opt.clone_bundle,
                              current_branch_only=opt.current_branch_only,
                              tags=opt.tags, submodules=opt.submodules,
                              clone_filter=opt.clone_filter):
      r = m.GetRemote(m.remote.name)
      print('fatal: cannot obtain manifest %s' % r.url, file=sys.stderr)

      # Better delete the manifest git dir if we created it; otherwise next
      # time (when user fixes problems) we won't go through the "is_new" logic.
      if is_new:
        platform_utils.rmtree(m.gitdir)
      sys.exit(1)

    if opt.manifest_branch:
      m.MetaBranchSwitch(submodules=opt.submodules)

    syncbuf = SyncBuffer(m.config)
    m.Sync_LocalHalf(syncbuf, submodules=opt.submodules)
    syncbuf.Finish()

    if is_new or m.CurrentBranch is None:
      if not m.StartBranch('default'):
        print('fatal: cannot create default in manifest', file=sys.stderr)
        sys.exit(1)
Beispiel #13
0
    def _SyncManifest(self, opt):
        m = self.manifest.manifestProject
        is_new = not m.Exists

        # If repo has already been initialized, we take -u with the absence of
        # --standalone-manifest to mean "transition to a standard repo set up",
        # which necessitates starting fresh.
        # If --standalone-manifest is set, we always tear everything down and start
        # anew.
        if not is_new:
            was_standalone_manifest = m.config.GetString('manifest.standalone')
            if was_standalone_manifest and not opt.manifest_url:
                print('fatal: repo was initialized with a standlone manifest, '
                      'cannot be re-initialized without --manifest-url/-u')
                sys.exit(1)

            if opt.standalone_manifest or (was_standalone_manifest
                                           and opt.manifest_url):
                m.config.ClearCache()
                if m.gitdir and os.path.exists(m.gitdir):
                    platform_utils.rmtree(m.gitdir)
                if m.worktree and os.path.exists(m.worktree):
                    platform_utils.rmtree(m.worktree)

        is_new = not m.Exists
        if is_new:
            if not opt.manifest_url:
                print('fatal: manifest url is required.', file=sys.stderr)
                sys.exit(1)

            if not opt.quiet:
                print('Downloading manifest from %s' %
                      (GitConfig.ForUser().UrlInsteadOf(opt.manifest_url), ),
                      file=sys.stderr)

            # The manifest project object doesn't keep track of the path on the
            # server where this git is located, so let's save that here.
            mirrored_manifest_git = None
            if opt.reference:
                manifest_git_path = urllib.parse.urlparse(
                    opt.manifest_url).path[1:]
                mirrored_manifest_git = os.path.join(opt.reference,
                                                     manifest_git_path)
                if not mirrored_manifest_git.endswith(".git"):
                    mirrored_manifest_git += ".git"
                if not os.path.exists(mirrored_manifest_git):
                    mirrored_manifest_git = os.path.join(
                        opt.reference, '.repo/manifests.git')

            m._InitGitDir(mirror_git=mirrored_manifest_git)

        # If standalone_manifest is set, mark the project as "standalone" -- we'll
        # still do much of the manifests.git set up, but will avoid actual syncs to
        # a remote.
        standalone_manifest = False
        if opt.standalone_manifest:
            standalone_manifest = True
            m.config.SetString('manifest.standalone', opt.manifest_url)
        elif not opt.manifest_url and not opt.manifest_branch:
            # If -u is set and --standalone-manifest is not, then we're not in
            # standalone mode. Otherwise, use config to infer what we were in the last
            # init.
            standalone_manifest = bool(
                m.config.GetString('manifest.standalone'))
        if not standalone_manifest:
            m.config.SetString('manifest.standalone', None)

        self._ConfigureDepth(opt)

        # Set the remote URL before the remote branch as we might need it below.
        if opt.manifest_url:
            r = m.GetRemote(m.remote.name)
            r.url = opt.manifest_url
            r.ResetFetch()
            r.Save()

        if not standalone_manifest:
            if opt.manifest_branch:
                if opt.manifest_branch == 'HEAD':
                    opt.manifest_branch = m.ResolveRemoteHead()
                    if opt.manifest_branch is None:
                        print('fatal: unable to resolve HEAD', file=sys.stderr)
                        sys.exit(1)
                m.revisionExpr = opt.manifest_branch
            else:
                if is_new:
                    default_branch = m.ResolveRemoteHead()
                    if default_branch is None:
                        # If the remote doesn't have HEAD configured, default to master.
                        default_branch = 'refs/heads/master'
                    m.revisionExpr = default_branch
                else:
                    m.PreSync()

        groups = re.split(r'[,\s]+', opt.groups)
        all_platforms = ['linux', 'darwin', 'windows']
        platformize = lambda x: 'platform-' + x
        if opt.platform == 'auto':
            if (not opt.mirror
                    and not m.config.GetString('repo.mirror') == 'true'):
                groups.append(platformize(platform.system().lower()))
        elif opt.platform == 'all':
            groups.extend(map(platformize, all_platforms))
        elif opt.platform in all_platforms:
            groups.append(platformize(opt.platform))
        elif opt.platform != 'none':
            print('fatal: invalid platform flag', file=sys.stderr)
            sys.exit(1)

        groups = [x for x in groups if x]
        groupstr = ','.join(groups)
        if opt.platform == 'auto' and groupstr == self.manifest.GetDefaultGroupsStr(
        ):
            groupstr = None
        m.config.SetString('manifest.groups', groupstr)

        if opt.reference:
            m.config.SetString('repo.reference', opt.reference)

        if opt.dissociate:
            m.config.SetBoolean('repo.dissociate', opt.dissociate)

        if opt.worktree:
            if opt.mirror:
                print('fatal: --mirror and --worktree are incompatible',
                      file=sys.stderr)
                sys.exit(1)
            if opt.submodules:
                print('fatal: --submodules and --worktree are incompatible',
                      file=sys.stderr)
                sys.exit(1)
            m.config.SetBoolean('repo.worktree', opt.worktree)
            if is_new:
                m.use_git_worktrees = True
            print('warning: --worktree is experimental!', file=sys.stderr)

        if opt.archive:
            if is_new:
                m.config.SetBoolean('repo.archive', opt.archive)
            else:
                print(
                    'fatal: --archive is only supported when initializing a new '
                    'workspace.',
                    file=sys.stderr)
                print(
                    'Either delete the .repo folder in this workspace, or initialize '
                    'in another location.',
                    file=sys.stderr)
                sys.exit(1)

        if opt.mirror:
            if is_new:
                m.config.SetBoolean('repo.mirror', opt.mirror)
            else:
                print(
                    'fatal: --mirror is only supported when initializing a new '
                    'workspace.',
                    file=sys.stderr)
                print(
                    'Either delete the .repo folder in this workspace, or initialize '
                    'in another location.',
                    file=sys.stderr)
                sys.exit(1)

        if opt.partial_clone is not None:
            if opt.mirror:
                print(
                    'fatal: --mirror and --partial-clone are mutually exclusive',
                    file=sys.stderr)
                sys.exit(1)
            m.config.SetBoolean('repo.partialclone', opt.partial_clone)
            if opt.clone_filter:
                m.config.SetString('repo.clonefilter', opt.clone_filter)
        elif m.config.GetBoolean('repo.partialclone'):
            opt.clone_filter = m.config.GetString('repo.clonefilter')
        else:
            opt.clone_filter = None

        if opt.partial_clone_exclude is not None:
            m.config.SetString('repo.partialcloneexclude',
                               opt.partial_clone_exclude)

        if opt.clone_bundle is None:
            opt.clone_bundle = False if opt.partial_clone else True
        else:
            m.config.SetBoolean('repo.clonebundle', opt.clone_bundle)

        if opt.submodules:
            m.config.SetBoolean('repo.submodules', opt.submodules)

        if opt.use_superproject is not None:
            m.config.SetBoolean('repo.superproject', opt.use_superproject)

        if standalone_manifest:
            if is_new:
                manifest_name = 'default.xml'
                manifest_data = fetch.fetch_file(opt.manifest_url,
                                                 verbose=opt.verbose)
                dest = os.path.join(m.worktree, manifest_name)
                os.makedirs(os.path.dirname(dest), exist_ok=True)
                with open(dest, 'wb') as f:
                    f.write(manifest_data)
            return

        if not m.Sync_NetworkHalf(
                is_new=is_new,
                quiet=opt.quiet,
                verbose=opt.verbose,
                clone_bundle=opt.clone_bundle,
                current_branch_only=opt.current_branch_only,
                tags=opt.tags,
                submodules=opt.submodules,
                clone_filter=opt.clone_filter,
                partial_clone_exclude=self.manifest.PartialCloneExclude):
            r = m.GetRemote(m.remote.name)
            print('fatal: cannot obtain manifest %s' % r.url, file=sys.stderr)

            # Better delete the manifest git dir if we created it; otherwise next
            # time (when user fixes problems) we won't go through the "is_new" logic.
            if is_new:
                platform_utils.rmtree(m.gitdir)
            sys.exit(1)

        if opt.manifest_branch:
            m.MetaBranchSwitch(submodules=opt.submodules)

        syncbuf = SyncBuffer(m.config)
        m.Sync_LocalHalf(syncbuf, submodules=opt.submodules)
        syncbuf.Finish()

        if is_new or m.CurrentBranch is None:
            if not m.StartBranch('default'):
                print('fatal: cannot create default in manifest',
                      file=sys.stderr)
                sys.exit(1)
Beispiel #14
0
        
    if len(args) < 3:
        usage()
        sys.exit(2)
    if args[0] != 'push':
        usage()
        sys.exit(2)    
    
    refs = args[2]
    print 'Local Refs: ',refs 
        
        
    root = get_root()
    
    
    cfg = GitConfig(root)
    url = cfg.get_remote_url()
    fetch = cfg.get_fetch()
    transport = S3Transport(url)

    
    advertised_refs = transport.get_advertised_refs()

    if len(advertised_refs) == 0:
        transport.create_new_repo(refs)
    
    client = Gits3(root)
    tracking_ref = client.find_tracking_ref_names(fetch, refs)
    
    updated_objects = client.get_updates(refs, tracking_ref)