예제 #1
0
 def test_push_two_revs_different_local_branch(self):
     def filectxfn(repo, memctx, path):
         return context.memfilectx(path=path,
                                   data=path,
                                   islink=False,
                                   isexec=False,
                                   copied=False)
     oldtiphash = self.repo['default'].node()
     ctx = context.memctx(self.repo,
                          (self.repo[0].node(), revlog.nullid, ),
                          'automated test',
                          ['gamma', ],
                          filectxfn,
                          'testy',
                          '2008-12-21 16:32:00 -0500',
                          {'branch': 'localbranch', })
     newhash = self.repo.commitctx(ctx)
     ctx = context.memctx(self.repo,
                          (newhash, revlog.nullid),
                          'automated test2',
                          ['delta', ],
                          filectxfn,
                          'testy',
                          '2008-12-21 16:32:00 -0500',
                          {'branch': 'localbranch', })
     newhash = self.repo.commitctx(ctx)
     repo = self.repo
     hg.update(repo, newhash)
     commands.push(repo.ui, repo)
     self.assertEqual(self.repo['tip'].parents()[0].parents()[0].node(), oldtiphash)
     self.assertEqual(self.repo['tip'].files(), ['delta', ])
     self.assertEqual(self.repo['tip'].manifest().keys(),
                      ['alpha', 'beta', 'gamma', 'delta'])
예제 #2
0
    def test_push_single_dir_at_subdir(self):
        repo = self._load_fixture_and_fetch('branch_from_tag.svndump',
                                            layout='single',
                                            subdir='trunk')

        def filectxfn(repo, memctx, path):
            return compathacks.makememfilectx(repo,
                                              memctx=memctx,
                                              path=path,
                                              data='contents of %s' % path,
                                              islink=False,
                                              isexec=False,
                                              copied=False)

        ctx = context.memctx(repo, (repo['tip'].node(), node.nullid),
                             'automated test', ['bogus'], filectxfn,
                             'an_author', '2009-10-19 18:49:30 -0500', {
                                 'branch': 'localhacking',
                             })
        n = repo.commitctx(ctx)
        self.assertEqual(self.repo['tip']['bogus'].data(), 'contents of bogus')
        before = repo['tip'].hex()
        hg.update(repo, self.repo['tip'].hex())
        self.pushrevisions()
        self.assertNotEqual(before, self.repo['tip'].hex())
        self.assertEqual(self.repo['tip']['bogus'].data(), 'contents of bogus')
예제 #3
0
    def test_push_single_dir_renamed_branch(self):
        # Tests pulling and pushing with a renamed branch
        # Based on test_push_single_dir
        repo_path = self.load_svndump('branch_from_tag.svndump')
        cmd = ['clone', '--quiet', '--layout=single', '--branch=flaf']
        if self.stupid:
            cmd.append('--stupid')
        cmd += [test_util.fileurl(repo_path), self.wc_path]
        test_util.dispatch(cmd)

        def file_callback(repo, memctx, path):
            if path == 'adding_file':
                return compathacks.makememfilectx(repo,
                                                  memctx=memctx,
                                                  path=path,
                                                  data='foo',
                                                  islink=False,
                                                  isexec=False,
                                                  copied=False)
            raise IOError(errno.EINVAL, 'Invalid operation: ' + path)

        lr = self.repo
        ctx = context.memctx(lr, (lr['tip'].node(), node.nullid),
                             'automated test', ['adding_file'], file_callback,
                             'an_author', '2009-10-19 18:49:30 -0500', {
                                 'branch': 'default',
                             })
        lr.commitctx(ctx)
        hg.update(self.repo, self.repo['tip'].node())
        self.pushrevisions()
        self.assertTrue('adding_file' in test_util.svnls(repo_path, ''))

        self.assertEquals(set(['flaf']),
                          set(self.repo[i].branch() for i in self.repo))
예제 #4
0
    def putcommit(self, files, copies, parents, commit, source, revmap):

        files = dict(files)
        def getfilectx(repo, memctx, f):
            v = files[f]
            data, mode = source.getfile(f, v)
            if f == '.hgtags':
                data = self._rewritetags(source, revmap, data)
            return context.memfilectx(f, data, 'l' in mode, 'x' in mode,
                                      copies.get(f))

        pl = []
        for p in parents:
            if p not in pl:
                pl.append(p)
        parents = pl
        nparents = len(parents)
        if self.filemapmode and nparents == 1:
            m1node = self.repo.changelog.read(bin(parents[0]))[0]
            parent = parents[0]

        if len(parents) < 2:
            parents.append(nullid)
        if len(parents) < 2:
            parents.append(nullid)
        p2 = parents.pop(0)

        text = commit.desc

        sha1s = re.findall(sha1re, text)
        for sha1 in sha1s:
            oldrev = source.lookuprev(sha1)
            newrev = revmap.get(oldrev)
            if newrev is not None:
                text = text.replace(sha1, newrev[:len(sha1)])

        extra = commit.extra.copy()
        if self.branchnames and commit.branch:
            extra['branch'] = commit.branch
        if commit.rev:
            extra['convert_revision'] = commit.rev

        while parents:
            p1 = p2
            p2 = parents.pop(0)
            ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
                                 getfilectx, commit.author, commit.date, extra)
            self.repo.commitctx(ctx)
            text = "(octopus merge fixup)\n"
            p2 = hex(self.repo.changelog.tip())

        if self.filemapmode and nparents == 1:
            man = self.repo.manifest
            mnode = self.repo.changelog.read(bin(p2))[0]
            closed = 'close' in commit.extra
            if not closed and not man.cmp(m1node, man.revision(mnode)):
                self.ui.status(_("filtering out empty revision\n"))
                self.repo.rollback(force=True)
                return parent
        return p2
예제 #5
0
    def test_push_single_dir_one_incoming_and_two_outgoing(self):
        # Tests simple pushing from default branch to a single dir repo
        # Pushes two outgoing over one incoming svn rev
        # (used to cause an "unknown revision")
        # This can happen if someone committed to svn since our last pull (race).
        repo, repo_path = self.load_and_fetch('branch_from_tag.svndump',
                                              layout='single',
                                              subdir='trunk')
        self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed'})

        def file_callback(repo, memctx, path):
            return compathacks.makememfilectx(repo,
                                              memctx=memctx,
                                              path=path,
                                              data='data of %s' % path,
                                              islink=False,
                                              isexec=False,
                                              copied=False)

        for fn in ['one', 'two']:
            ctx = context.memctx(repo, (repo['tip'].node(), node.nullid),
                                 'automated test', [fn], file_callback,
                                 'an_author', '2009-10-19 18:49:30 -0500', {
                                     'branch': 'default',
                                 })
            repo.commitctx(ctx)
        hg.update(repo, repo['tip'].node())
        self.pushrevisions(expected_extra_back=1)
        self.assertTrue('trunk/one' in test_util.svnls(repo_path, ''))
        self.assertTrue('trunk/two' in test_util.svnls(repo_path, ''))
예제 #6
0
    def test_rebase(self):
        self._load_fixture_and_fetch('two_revs.svndump')
        parents = (
            self.repo[0].node(),
            revlog.nullid,
        )

        def filectxfn(repo, memctx, path):
            return compathacks.makememfilectx(repo,
                                              memctx=memctx,
                                              path=path,
                                              data='added',
                                              islink=False,
                                              isexec=False,
                                              copied=False)

        lr = self.repo
        ctx = context.memctx(lr, parents, 'automated test', [
            'added_bogus_file',
            'other_added_file',
        ], filectxfn, 'testy', '2008-12-21 16:32:00 -0500', {
            'branch': 'localbranch',
        })
        lr.commitctx(ctx)
        self.assertEqual(self.repo['tip'].branch(), 'localbranch')
        beforerebasehash = self.repo['tip'].node()
        hg.update(self.repo, 'tip')
        wrappers.rebase(rebase.rebase, self.ui(), self.repo, svn=True)
        self.assertEqual(self.repo['tip'].branch(), 'localbranch')
        self.assertEqual(self.repo['tip'].parents()[0].parents()[0],
                         self.repo[0])
        self.assertNotEqual(beforerebasehash, self.repo['tip'].node())
예제 #7
0
    def commit(self, items):
        def file_callback(repo, memctx, path):
            return context.memfilectx(
                path=path,
                data=items[path],
                islink=False,
                isexec=False,
                copied=False,
            )

        local_repo = self._local_repo
        remote_repo = self._remote_repo

        lock = local_repo.lock()
        try:
            if remote_repo:
                local_repo.pull(self._remote_repo)

            ctx = context.memctx(
                repo=local_repo,
                parents=('tip', None),
                text=revision.message,
                files=items.keys(),
                filectxfn=file_callback,
                user=str(revision.user.id),
            )
            version = node.hex(local_repo.commitctx(ctx))
            # TODO: if we want the working copy of the repository to be updated as well add logic to enable this.
            # hg.update(local_repo, local_repo['tip'].node())
            if remote_repo:
                local_repo.push(remote_repo)

            return version
        finally:
            lock.release()
예제 #8
0
 def test_cant_push_empty_ctx(self):
     repo = self.repo
     def file_callback(repo, memctx, path):
         if path == 'adding_file':
             return compathacks.makememfilectx(repo,
                                               path=path,
                                               data='foo',
                                               islink=False,
                                               isexec=False,
                                               copied=False)
         raise IOError()
     ctx = context.memctx(repo,
                          (repo['default'].node(), node.nullid),
                          'automated test',
                          [],
                          file_callback,
                          'an_author',
                          '2008-10-07 20:59:48 -0500',
                          {'branch': 'default', })
     new_hash = repo.commitctx(ctx)
     hg.update(repo, repo['tip'].node())
     old_tip = repo['tip'].node()
     self.pushrevisions()
     tip = self.repo['tip']
     self.assertEqual(tip.node(), old_tip)
예제 #9
0
 def test_cant_push_with_changes(self):
     repo = self.repo
     def file_callback(repo, memctx, path):
         return compathacks.makememfilectx(repo,
                                           path=path,
                                           data='foo',
                                           islink=False,
                                           isexec=False,
                                           copied=False)
     ctx = context.memctx(repo,
                          (repo['default'].node(), node.nullid),
                          'automated test',
                          ['adding_file'],
                          file_callback,
                          'an_author',
                          '2008-10-07 20:59:48 -0500',
                          {'branch': 'default', })
     new_hash = repo.commitctx(ctx)
     hg.update(repo, repo['tip'].node())
     # Touch an existing file
     repo.wwrite('beta', 'something else', '')
     try:
         self.pushrevisions()
     except hgutil.Abort:
         pass
     tip = self.repo['tip']
     self.assertEqual(new_hash, tip.node())
예제 #10
0
파일: absorb.py 프로젝트: CJX32/my_blog
def overlaycontext(memworkingcopy, ctx, parents=None, extra=None):
    """({path: content}, ctx, (p1node, p2node)?, {}?) -> memctx
    memworkingcopy overrides file contents.
    """
    # parents must contain 2 items: (node1, node2)
    if parents is None:
        parents = ctx.repo().changelog.parents(ctx.node())
    if extra is None:
        extra = ctx.extra()
    date = ctx.date()
    desc = ctx.description()
    user = ctx.user()
    files = set(ctx.files()).union(memworkingcopy)
    store = overlaystore(ctx, memworkingcopy)
    return context.memctx(
        repo=ctx.repo(),
        parents=parents,
        text=desc,
        files=files,
        filectxfn=store,
        user=user,
        date=date,
        branch=None,
        extra=extra,
    )
예제 #11
0
파일: hg.py 프로젝트: MezzLabs/mercurial
    def puttags(self, tags):
        try:
            parentctx = self.repo[self.tagsbranch]
            tagparent = parentctx.node()
        except error.RepoError:
            parentctx = None
            tagparent = nullid

        try:
            oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
        except:
            oldlines = []

        newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
        if newlines == oldlines:
            return None, None
        data = "".join(newlines)
        def getfilectx(repo, memctx, f):
            return context.memfilectx(f, data, False, False, None)

        self.ui.status(_("updating tags\n"))
        date = "%s 0" % int(time.mktime(time.gmtime()))
        extra = {'branch': self.tagsbranch}
        ctx = context.memctx(self.repo, (tagparent, None), "update tags",
                             [".hgtags"], getfilectx, "convert-repo", date,
                             extra)
        self.repo.commitctx(ctx)
        return hex(self.repo.changelog.tip()), hex(tagparent)
예제 #12
0
 def test_push_to_default(self, commit=True):
     repo = self.repo
     old_tip = repo['tip'].node()
     expected_parent = repo['default'].node()
     def file_callback(repo, memctx, path):
         if path == 'adding_file':
             return context.memfilectx(path=path,
                                       data='foo',
                                       islink=False,
                                       isexec=False,
                                       copied=False)
         raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
     ctx = context.memctx(repo,
                          (repo['default'].node(), node.nullid),
                          'automated test',
                          ['adding_file'],
                          file_callback,
                          'an_author',
                          '2008-10-07 20:59:48 -0500',
                          {'branch': 'default',})
     new_hash = repo.commitctx(ctx)
     if not commit:
         return # some tests use this test as an extended setup.
     hg.update(repo, repo['tip'].node())
     self.pushrevisions()
     tip = self.repo['tip']
     self.assertNotEqual(tip.node(), old_tip)
     self.assertEqual(node.hex(tip.parents()[0].node()),
                      node.hex(expected_parent))
     self.assertEqual(tip['adding_file'].data(), 'foo')
     self.assertEqual(tip.branch(), 'default')
예제 #13
0
def _graft(repo, rev, mapping):
    '''duplicate changeset "rev" with parents from "mapping"'''
    oldp1 = rev.p1().node()
    oldp2 = rev.p2().node()
    newp1 = mapping.get(oldp1, oldp1)
    newp2 = mapping.get(oldp2, oldp2)
    m = rev.manifest()
    def getfilectx(repo, memctx, path):
        if path in m:
            fctx = rev[path]
            flags = fctx.flags()
            copied = fctx.renamed()
            if copied:
                copied = copied[0]
            return context.memfilectx(repo, fctx.path(), fctx.data(),
                              islink='l' in flags,
                              isexec='x' in flags,
                              copied=copied)
        else:
            return None


    # If the incoming commit has no parents, but requested a rebase,
    # allow it only for the first commit. The null/null commit will always
    # be the first commit since we only allow a nullid->nonnullid mapping if the
    # incoming commits are a completely distinct history (see `sharedparents` in
    # getrevs()), so there's no risk of commits with a single null parent
    # accidentally getting translated first.
    if oldp1 == nullid and oldp2 == nullid:
        if newp1 != nullid:
            newp2 = nullid
            del mapping[nullid]

    if oldp1 != nullid and oldp2 != nullid:
        # If it's a merge commit, Mercurial's rev.files() only returns the files
        # that are different from both p1 and p2, so it would not capture all of
        # the incoming changes from p2 (for instance, new files in p2). The fix
        # is to manually diff the rev manifest and it's p1 to get the list of
        # files that have changed. We only need to diff against p1, and not p2,
        # because Mercurial constructs new commits by applying our specified
        # files on top of a copy of the p1 manifest, so we only need the diff
        # against p1.
        bundlerepo = rev._repo
        files = rev.manifest().diff(bundlerepo[oldp1].manifest()).keys()
    else:
        files = rev.files()


    date = rev.date()
    if repo.ui.configbool('pushrebase', 'rewritedates'):
        date = (time.time(), date[1])
    return context.memctx(repo,
                          [newp1, newp2],
                          rev.description(),
                          files,
                          getfilectx,
                          rev.user(),
                          date,
                          rev.extra(),
                         ).commit()
예제 #14
0
파일: hgimport.py 프로젝트: gktomar/gaurav
    def putcommit(self, files, modes, copies, commit):
        def getfilectx(repo, memctx, name):
            fileid = files[name]
            if fileid is None:  # deleted file
                raise IOError
            data = self.getblob(fileid)
            ctx = context.memfilectx(name, data, 'l' in modes, 'x' in modes,
                                     copies.get(name))
            return ctx

        parents = list(set(commit.parents))
        nparents = len(parents)

        if len(parents) < 2:
            parents.append(nullid)
        if len(parents) < 2:
            parents.append(nullid)
        p2 = parents.pop(0)

        text = commit.desc
        extra = commit.extra.copy()
        if self.branchnames and commit.branch:
            extra['branch'] = commit.branch

        while parents:
            p1 = p2
            p2 = parents.pop(0)
            ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
                                 getfilectx, commit.author, commit.date, extra)
            self.repo.commitctx(ctx)
            text = "(octopus merge fixup)\n"
            p2 = hex(self.repo.changelog.tip())

        return p2
예제 #15
0
    def test_push_single_dir_renamed_branch(self, stupid=False):
        # Tests pulling and pushing with a renamed branch
        # Based on test_push_single_dir
        test_util.load_svndump_fixture(self.repo_path,
                                       'branch_from_tag.svndump')
        cmd = ['clone', '--layout=single', '--branch=flaf']
        if stupid:
            cmd.append('--stupid')
        cmd += [test_util.fileurl(self.repo_path), self.wc_path]
        dispatch.dispatch(cmd)

        def file_callback(repo, memctx, path):
            if path == 'adding_file':
                return context.memfilectx(path=path,
                                          data='foo',
                                          islink=False,
                                          isexec=False,
                                          copied=False)
            raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
        ctx = context.memctx(self.repo,
                             (self.repo['tip'].node(), node.nullid),
                             'automated test',
                             ['adding_file'],
                             file_callback,
                             'an_author',
                             '2009-10-19 18:49:30 -0500',
                             {'branch': 'default',})
        self.repo.commitctx(ctx)
        hg.update(self.repo, self.repo['tip'].node())
        self.pushrevisions()
        self.assertTrue('adding_file' in self.svnls(''))

        self.assertEquals(set(['flaf']),
                          set(self.repo[i].branch() for i in self.repo))
예제 #16
0
 def test_push_single_dir_one_incoming_and_two_outgoing(self):
     # Tests simple pushing from default branch to a single dir repo
     # Pushes two outgoing over one incoming svn rev
     # (used to cause an "unknown revision")
     # This can happen if someone committed to svn since our last pull (race).
     repo = self._load_fixture_and_fetch('branch_from_tag.svndump',
                                         stupid=False,
                                         layout='single',
                                         subdir='trunk')
     self._add_svn_rev({'trunk/alpha': 'Changed'})
     def file_callback(repo, memctx, path):
         return context.memfilectx(path=path,
                                   data='data of %s' % path,
                                   islink=False,
                                   isexec=False,
                                   copied=False)
     for fn in ['one', 'two']:
         ctx = context.memctx(repo,
                              (repo['tip'].node(), node.nullid),
                              'automated test',
                              [fn],
                              file_callback,
                              'an_author',
                              '2009-10-19 18:49:30 -0500',
                              {'branch': 'default',})
         repo.commitctx(ctx)
     hg.update(repo, repo['tip'].node())
     self.pushrevisions(expected_extra_back=1)
     self.assertTrue('trunk/one' in self.svnls(''))
     self.assertTrue('trunk/two' in self.svnls(''))
예제 #17
0
 def test_push_single_dir_at_subdir(self):
     repo = self._load_fixture_and_fetch('branch_from_tag.svndump',
                                         stupid=False,
                                         layout='single',
                                         subdir='trunk')
     def filectxfn(repo, memctx, path):
         return context.memfilectx(path=path,
                                   data='contents of %s' % path,
                                   islink=False,
                                   isexec=False,
                                   copied=False)
     ctx = context.memctx(repo,
                          (repo['tip'].node(), node.nullid),
                          'automated test',
                          ['bogus'],
                          filectxfn,
                          'an_author',
                          '2009-10-19 18:49:30 -0500',
                          {'branch': 'localhacking',})
     n = repo.commitctx(ctx)
     self.assertEqual(self.repo['tip']['bogus'].data(),
                      'contents of bogus')
     before = repo['tip'].hex()
     hg.update(repo, self.repo['tip'].hex())
     self.pushrevisions()
     self.assertNotEqual(before, self.repo['tip'].hex())
     self.assertEqual(self.repo['tip']['bogus'].data(),
                      'contents of bogus')
예제 #18
0
파일: hgimport.py 프로젝트: Grahack/git
    def putcommit(self, files, modes, copies, commit):

        def getfilectx(repo, memctx, name):
            fileid = files[name]
            if fileid is None:  # deleted file
                raise IOError
            data = self.getblob(fileid)
            ctx = context.memfilectx(name, data, 'l' in modes,
                                     'x' in modes, copies.get(name))
            return ctx

        parents = list(set(commit.parents))
        nparents = len(parents)

        if len(parents) < 2:
            parents.append(nullid)
        if len(parents) < 2:
            parents.append(nullid)
        p2 = parents.pop(0)

        text = commit.desc
        extra = commit.extra.copy()
        if self.branchnames and commit.branch:
            extra['branch'] = commit.branch

        while parents:
            p1 = p2
            p2 = parents.pop(0)
            ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
                                 getfilectx, commit.author, commit.date, extra)
            self.repo.commitctx(ctx)
            text = "(octopus merge fixup)\n"
            p2 = hex(self.repo.changelog.tip())

        return p2
예제 #19
0
 def test_push_single_dir(self):
     # Tests simple pushing from default branch to a single dir repo
     repo = self._load_fixture_and_fetch('branch_from_tag.svndump',
                                         stupid=False,
                                         layout='single',
                                         subdir='')
     def file_callback(repo, memctx, path):
         if path == 'adding_file':
             return context.memfilectx(path=path,
                                       data='foo',
                                       islink=False,
                                       isexec=False,
                                       copied=False)
         raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
     ctx = context.memctx(repo,
                          (repo['tip'].node(), node.nullid),
                          'automated test',
                          ['adding_file'],
                          file_callback,
                          'an_author',
                          '2009-10-19 18:49:30 -0500',
                          {'branch': 'default',})
     repo.commitctx(ctx)
     hg.update(repo, repo['tip'].node())
     self.pushrevisions()
     self.assertTrue('adding_file' in self.svnls(''))
예제 #20
0
def harvest(ui, repo, branch, dest="default", **opts):
    """Close and merge a named branch into the destination branch"""
    if branch not in repo.branchtags():
        ui.warn("Branch %s does not exist! (use 'hg branches' to get a list of branches)\n" % branch)
        return

    if dest not in repo.branchtags():
        ui.warn("Destination branch %s does not exist! (use 'hg branches' to get a list of branches)\n" % branch)
        return

    heads = repo.branchheads(branch)
    if len(heads) == 0:
        ui.warn("Cannot harvest branch %s because it is currently closed. \nUse 'hg merge' to merge it manually.\n" % branch)
        return

    if len(heads) > 1:
        ui.warn("Branch %s has multiple heads. \nUse 'hg merge' to merge it manually.\n" % branch)
        return

    rev = repo.branchtip(branch)
    newrev = context.memctx(repo, [rev, None], "Closed branch %s" % branch, [], None, opts.get('user'), opts.get('date'), extra={'close':1, 'branch':branch})
    newrev.commit()

    #don't need to switch if already on destination branch
    curr = repo[None].branch()
    if dest != curr:
        hg.clean(repo, dest, False)
        ui.status("Switched to branch %s before merging\n" % dest)

    failed = hg.merge(repo, branch, remind = False)
    if not failed:
        repo.commit("Merged %s" % branch, opts.get('user'), opts.get('date'), None)
        ui.status("Completed merge of %s into %s\n" % (branch, dest))
예제 #21
0
    def commit(self, items):
        def file_callback(repo, memctx, path):
            return context.memfilectx(
                path=path,
                data=items[path],
                islink=False,
                isexec=False,
                copied=False,
                )
        local_repo = self._local_repo
        remote_repo = self._remote_repo

        lock = local_repo.lock()
        try:
            if remote_repo:
                local_repo.pull(self._remote_repo)

            ctx = context.memctx(
                repo=local_repo,
                parents=('tip', None),
                text=revision.message,
                files=items.keys(),
                filectxfn=file_callback,
                user=str(revision.user.id),
                )
            version = node.hex(local_repo.commitctx(ctx))
            # TODO: if we want the working copy of the repository to be updated as well add logic to enable this.
            # hg.update(local_repo, local_repo['tip'].node())
            if remote_repo:
                local_repo.push(remote_repo)

            return version
        finally:
            lock.release()
예제 #22
0
    def test_push_to_default(self, commit=True):
        repo = self.repo
        old_tip = revsymbol(repo, 'tip').node()
        expected_parent = revsymbol(repo, 'default').node()

        def file_callback(repo, memctx, path):
            if path == 'adding_file':
                return compathacks.makememfilectx(repo,
                                                  memctx=memctx,
                                                  path=path,
                                                  data='foo',
                                                  islink=False,
                                                  isexec=False,
                                                  copied=False)
            raise IOError(errno.EINVAL, 'Invalid operation: ' + path)

        ctx = context.memctx(repo,
                             (revsymbol(repo, 'default').node(), node.nullid),
                             'automated test', ['adding_file'], file_callback,
                             'an_author', '2008-10-07 20:59:48 -0500', {
                                 'branch': 'default',
                             })
        new_hash = repo.commitctx(ctx)
        if not commit:
            return  # some tests use this test as an extended setup.
        hg.update(repo, revsymbol(repo, 'tip').node())
        self.pushrevisions()
        tip = revsymbol(self.repo, 'tip')
        self.assertNotEqual(tip.node(), old_tip)
        self.assertEqual(node.hex(tip.parents()[0].node()),
                         node.hex(expected_parent))
        self.assertEqual(tip['adding_file'].data(), 'foo')
        self.assertEqual(tip.branch(), 'default')
예제 #23
0
    def test_push_to_branch(self, push=True):
        repo = self.repo

        def file_callback(repo, memctx, path):
            if path == 'adding_file':
                return compathacks.makememfilectx(repo,
                                                  memctx=memctx,
                                                  path=path,
                                                  data='foo',
                                                  islink=False,
                                                  isexec=False,
                                                  copied=False)
            raise IOError(errno.EINVAL, 'Invalid operation: ' + path)

        ctx = context.memctx(
            repo, (revsymbol(repo, 'the_branch').node(), node.nullid),
            'automated test', ['adding_file'], file_callback, 'an_author',
            '2008-10-07 20:59:48 -0500', {
                'branch': 'the_branch',
            })
        new_hash = repo.commitctx(ctx)
        hg.update(repo, revsymbol(repo, 'tip').node())
        if push:
            self.pushrevisions()
            tip = revsymbol(self.repo, 'tip')
            self.assertNotEqual(tip.node(), new_hash)
            self.assertEqual(tip['adding_file'].data(), 'foo')
            self.assertEqual(tip.branch(), 'the_branch')
 def test_outgoing_output(self):
     self._load_fixture_and_fetch('two_heads.svndump')
     u = self.ui()
     parents = (self.repo['the_branch'].node(), revlog.nullid, )
     def filectxfn(repo, memctx, path):
         return context.memfilectx(path=path,
                                   data='added',
                                   islink=False,
                                   isexec=False,
                                   copied=False)
     ctx = context.memctx(self.repo,
                          parents,
                          'automated test',
                          ['added_bogus_file', 'other_added_file', ],
                          filectxfn,
                          'testy',
                          '2008-12-21 16:32:00 -0500',
                          {'branch': 'localbranch', })
     new = self.repo.commitctx(ctx)
     hg.update(self.repo, new)
     u.pushbuffer()
     commands.outgoing(u, self.repo, self.repourl)
     actual = u.popbuffer()
     self.assertTrue(node.hex(self.repo['localbranch'].node())[:8] in actual)
     self.assertEqual(actual.strip(), '5:6de15430fa20')
     hg.update(self.repo, 'default')
     u.pushbuffer()
     commands.outgoing(u, self.repo, self.repourl)
     actual = u.popbuffer()
     self.assertEqual(actual, '')
예제 #25
0
    def test_cant_push_with_changes(self):
        repo = self.repo

        def file_callback(repo, memctx, path):
            return compathacks.makememfilectx(repo,
                                              memctx=memctx,
                                              path=path,
                                              data='foo',
                                              islink=False,
                                              isexec=False,
                                              copied=False)

        ctx = context.memctx(repo,
                             (revsymbol(repo, 'default').node(), node.nullid),
                             'automated test', ['adding_file'], file_callback,
                             'an_author', '2008-10-07 20:59:48 -0500', {
                                 'branch': 'default',
                             })
        new_hash = repo.commitctx(ctx)
        hg.update(repo, revsymbol(repo, 'tip').node())
        # Touch an existing file
        repo.wwrite('beta', 'something else', '')
        try:
            self.pushrevisions()
        except hgerror.Abort:
            pass
        tip = revsymbol(self.repo, 'tip')
        self.assertEqual(new_hash, tip.node())
    def createfn(repo, ctx, revmap, filectxfn):
        parents = newparents(repo, ctx, revmap)
        description = ctx.description()
        if not opts['unmodified']:
            description += b'\n%d' % offset[0]
        memctx = context.memctx(repo,
                                parents,
                                description,
                                ctx.files(),
                                filectxfn,
                                user=ctx.user(),
                                date=ctx.date(),
                                extra=ctx.extra())
        status = ctx.p1().status(ctx)
        # TRACKING hg53 - status is an object instead of a tuple
        if util.versiontuple(n=2) >= (5, 3):
            memctx.modified = lambda: status.modified
            memctx.added = lambda: status.added
            memctx.removed = lambda: status.removed
        else:
            memctx.modified = lambda: status[0]
            memctx.added = lambda: status[1]
            memctx.removed = lambda: status[2]
        offset[0] += 1

        return memctx
예제 #27
0
def copy_commit(repo, ctx, parent, date):
    mf = ctx.manifest()
    copied = copies.pathcopies(ctx.p1(), ctx)

    def _filectxfn(repo, memctx, path):
        if path in mf:
            fctx = ctx[path]
            flags = fctx.flags()
            return context.memfilectx(
                fctx.path(),
                fctx.data(),
                islink='l' in flags,
                isexec='x' in flags,
                copied=copied.get(path))
        raise IOError

    new = context.memctx(
        repo,
        parents=(parent.node(), repo[-1].node()),
        text=ctx.description(),
        files=ctx.files(),
        filectxfn=_filectxfn,
        user=ctx.user(),
        date=date,
        extra=ctx.extra())
    return repo.commitctx(new)
예제 #28
0
def _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap):
    mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
                          getfilectx, ctx.user(), ctx.date(), ctx.extra())
    ret = rdst.commitctx(mctx)
    lfutil.copyalltostore(rdst, ret)
    rdst.setparents(ret)
    revmap[ctx.node()] = rdst.changelog.tip()
def _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap):
    mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
                          getfilectx, ctx.user(), ctx.date(), ctx.extra())
    ret = rdst.commitctx(mctx)
    lfutil.copyalltostore(rdst, ret)
    rdst.setparents(ret)
    revmap[ctx.node()] = rdst.changelog.tip()
예제 #30
0
    def puttags(self, tags):
        try:
            parentctx = self.repo[self.tagsbranch]
            tagparent = parentctx.node()
        except error.RepoError:
            parentctx = None
            tagparent = nullid

        try:
            oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
        except:
            oldlines = []

        newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
        if newlines == oldlines:
            return None
        data = "".join(newlines)

        def getfilectx(repo, memctx, f):
            return context.memfilectx(f, data, False, False, None)

        self.ui.status(_("updating tags\n"))
        date = "%s 0" % int(time.mktime(time.gmtime()))
        extra = {'branch': self.tagsbranch}
        ctx = context.memctx(self.repo, (tagparent, None), "update tags",
                             [".hgtags"], getfilectx, "convert-repo", date,
                             extra)
        self.repo.commitctx(ctx)
        return hex(self.repo.changelog.tip())
 def test_rebase(self):
     self._load_fixture_and_fetch('two_revs.svndump')
     parents = (self.repo[0].node(), revlog.nullid, )
     def filectxfn(repo, memctx, path):
         return context.memfilectx(path=path,
                                   data='added',
                                   islink=False,
                                   isexec=False,
                                   copied=False)
     ctx = context.memctx(self.repo,
                          parents,
                          'automated test',
                          ['added_bogus_file', 'other_added_file', ],
                          filectxfn,
                          'testy',
                          '2008-12-21 16:32:00 -0500',
                          {'branch': 'localbranch', })
     self.repo.commitctx(ctx)
     self.assertEqual(self.repo['tip'].branch(), 'localbranch')
     beforerebasehash = self.repo['tip'].node()
     hg.update(self.repo, 'tip')
     wrappers.rebase(rebase.rebase, self.ui(), self.repo, svn=True)
     self.assertEqual(self.repo['tip'].branch(), 'localbranch')
     self.assertEqual(self.repo['tip'].parents()[0].parents()[0], self.repo[0])
     self.assertNotEqual(beforerebasehash, self.repo['tip'].node())
예제 #32
0
 def test_push_to_branch(self, push=True):
     repo = self.repo
     def file_callback(repo, memctx, path):
         if path == 'adding_file':
             return context.memfilectx(path=path,
                                       data='foo',
                                       islink=False,
                                       isexec=False,
                                       copied=False)
         raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
     ctx = context.memctx(repo,
                          (repo['the_branch'].node(), node.nullid),
                          'automated test',
                          ['adding_file'],
                          file_callback,
                          'an_author',
                          '2008-10-07 20:59:48 -0500',
                          {'branch': 'the_branch',})
     new_hash = repo.commitctx(ctx)
     hg.update(repo, repo['tip'].node())
     if push:
         self.pushrevisions()
         tip = self.repo['tip']
         self.assertNotEqual(tip.node(), new_hash)
         self.assertEqual(tip['adding_file'].data(), 'foo')
         self.assertEqual(tip.branch(), 'the_branch')
예제 #33
0
 def test_push_symlink_file(self):
     self.test_push_to_default(commit=True)
     repo = self.repo
     def file_callback(repo, memctx, path):
         if path == 'gamma':
             return context.memfilectx(path=path,
                                       data='foo',
                                       islink=True,
                                       isexec=False,
                                       copied=False)
         raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
     ctx = context.memctx(repo,
                          (repo['tip'].node(), node.nullid),
                          'message',
                          ['gamma', ],
                          file_callback,
                          'author',
                          '2008-10-29 21:26:00 -0500',
                          {'branch': 'default', })
     new_hash = repo.commitctx(ctx)
     hg.update(repo, repo['tip'].node())
     self.pushrevisions()
     tip = self.repo['tip']
     self.assertNotEqual(tip.node(), new_hash)
     self.assertEqual(tip['gamma'].flags(), 'l')
     self.assertEqual(tip['gamma'].data(), 'foo')
     self.assertEqual([x for x in tip.manifest().keys() if 'l' not in
                       tip[x].flags()], ['alpha', 'beta', 'adding_file', ])
예제 #34
0
    def test_cant_push_empty_ctx(self):
        repo = self.repo

        def file_callback(repo, memctx, path):
            if path == 'adding_file':
                return compathacks.makememfilectx(repo,
                                                  memctx=memctx,
                                                  path=path,
                                                  data='foo',
                                                  islink=False,
                                                  isexec=False,
                                                  copied=False)
            raise IOError()

        ctx = context.memctx(repo,
                             (revsymbol(repo, 'default').node(), node.nullid),
                             'automated test', [], file_callback, 'an_author',
                             '2008-10-07 20:59:48 -0500', {
                                 'branch': 'default',
                             })
        new_hash = repo.commitctx(ctx)
        hg.update(repo, revsymbol(repo, 'tip').node())
        old_tip = revsymbol(repo, 'tip').node()
        self.pushrevisions()
        tip = revsymbol(self.repo, 'tip')
        self.assertEqual(tip.node(), old_tip)
예제 #35
0
    def committags(self, rev, endbranches):
        if not self.addedtags and not self.deletedtags:
            return
        date = self.fixdate(rev.date)
        # determine additions/deletions per branch
        branches = {}
        for tags in (self.addedtags, self.deletedtags):
            for tag, (branch, srcrev) in tags.iteritems():
                op = srcrev is None and 'rm' or 'add'
                branches.setdefault(branch, []).append((op, tag, srcrev))

        for b, tags in branches.iteritems():
            fromtag = self.get_path_tag(self.remotename(b))
            # modify parent's .hgtags source
            parent = self.repo[self.get_parent_revision(rev.revnum, b)]
            if '.hgtags' not in parent:
                src = ''
            else:
                src = parent['.hgtags'].data()
            for op, tag, r in sorted(tags, reverse=True):
                if op == 'add':
                    if fromtag:
                        if fromtag in self.tags:
                            tagged = node.hex(self.tags[fromtag])
                    else:
                        tagged = node.hex(self.revmap[
                            self.get_parent_svn_branch_and_rev(r, b)])
                else:
                    tagged = node.hex(node.nullid)
                src += '%s %s\n' % (tagged, tag)
                self.tags[tag] = node.bin(tagged), rev.revnum

            # add new changeset containing updated .hgtags
            def fctxfun(repo, memctx, path):
                return context.memfilectx(path='.hgtags', data=src,
                                          islink=False, isexec=False,
                                          copied=None)

            extra = self.genextra(rev.revnum, b)
            if fromtag:
                extra['branch'] = parent.extra().get('branch', 'default')
            self.mapbranch(extra, b in endbranches or fromtag)

            ctx = context.memctx(self.repo,
                                 (parent.node(), node.nullid),
                                 rev.message or ' ',
                                 ['.hgtags'],
                                 fctxfun,
                                 self.authors[rev.author],
                                 date,
                                 extra)
            new = self.repo.commitctx(ctx)

            if not fromtag and (rev.revnum, b) not in self.revmap:
                self.revmap[rev.revnum, b] = new
            if b in endbranches:
                endbranches.pop(b)
                bname = b or 'default'
                self.ui.status('Marked branch %s as closed.\n' % bname)
예제 #36
0
def push_to_try(ui, repo, server, message=None):

    nodate = ui.configbool('push-to-try', 'nodate')

    if not message or 'try:' not in message:
        ui.status("STOP! A commit message with try syntax is required.\n")
        return

    cctx = context.workingctx(repo)
    status = repo.status()

    if status.modified + status.added + status.removed:
        ui.status('The following will be pushed to %s:\n' % server)
        # TODO: Achieve this by re-using the status call above to avoid the
        # cost of running it twice.
        commands.status(ui, repo)

    preserve_ctx = preservefilectx(cctx)

    def mk_memfilectx(repo, memctx, path):
        if path not in status.removed:
            return preserve_ctx(repo, memctx, path)
        return None

    # Invent a temporary commit with our message.
    ui.status("Creating temporary commit for remote...\n")
    mctx = context.memctx(repo,
                          repo.dirstate.parents(),
                          message,
                          cctx.files(),
                          mk_memfilectx,
                          date="0 0" if nodate else None)

    # These messages are expected when we abort our transaction, but aren't
    # helpful to a user and may be misleading so we surpress them here.
    filtered_phrases = {_("transaction abort!\n"), _("rollback completed\n")}

    def filtered_warn(*msgs, **opts):
        if msgs:
            filtered = [m for m in msgs if m not in filtered_phrases]
        if filtered:
            ui.warn(*filtered, **opts)

    lock = tr = None
    try:
        lock = repo.lock()
        tr = repo.transaction('push-to-try', report=filtered_warn)
        m = mctx.commit()
        # Push to try.
        commands.push(ui, repo, server, force=True, rev=[repo[m].rev()])
        ui.status('push complete\n')
        # And rollback to the previous state.
        tr.abort()
    finally:
        if tr:
            tr.release()
        if lock:
            lock.release()
        ui.status("temporary commit removed, repository restored\n")
예제 #37
0
    def internal_push_over_svnserve(self, subdir='', commit=True):
        test_util.load_svndump_fixture(self.repo_path, 'simple_branch.svndump')
        open(os.path.join(self.repo_path, 'conf', 'svnserve.conf'),
             'w').write('[general]\nanon-access=write\n[sasl]\n')
        self.port = random.randint(socket.IPPORT_USERRESERVED, 65535)
        self.host = 'localhost'
        args = ['svnserve', '--daemon', '--foreground',
                '--listen-port=%d' % self.port,
                '--listen-host=%s' % self.host,
                '--root=%s' % self.repo_path]

        svnserve = subprocess.Popen(args, stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
        self.svnserve_pid = svnserve.pid
        try:
            time.sleep(2)
            import shutil
            shutil.rmtree(self.wc_path)
            commands.clone(self.ui(),
                           'svn://%s:%d/%s' % (self.host, self.port, subdir),
                           self.wc_path, noupdate=True)

            repo = self.repo
            old_tip = repo['tip'].node()
            expected_parent = repo['default'].node()
            def file_callback(repo, memctx, path):
                if path == 'adding_file':
                    return context.memfilectx(path=path,
                                              data='foo',
                                              islink=False,
                                              isexec=False,
                                              copied=False)
                raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
            ctx = context.memctx(repo,
                                 parents=(repo['default'].node(), node.nullid),
                                 text='automated test',
                                 files=['adding_file'],
                                 filectxfn=file_callback,
                                 user='******',
                                 date='2008-10-07 20:59:48 -0500',
                                 extra={'branch': 'default',})
            new_hash = repo.commitctx(ctx)
            if not commit:
                return # some tests use this test as an extended setup.
            hg.update(repo, repo['tip'].node())
            oldauthor = repo['tip'].user()
            commands.push(repo.ui, repo)
            tip = self.repo['tip']
            self.assertNotEqual(oldauthor, tip.user())
            self.assertNotEqual(tip.node(), old_tip)
            self.assertEqual(tip.parents()[0].node(), expected_parent)
            self.assertEqual(tip['adding_file'].data(), 'foo')
            self.assertEqual(tip.branch(), 'default')
            # unintended behaviour:
            self.assertNotEqual('an_author', tip.user())
            self.assertEqual('(no author)', tip.user().rsplit('@', 1)[0])
        finally:
            # TODO: use svnserve.kill() in Python >2.5
            test_util.kill_process(svnserve)
예제 #38
0
 def commit_to_branch(name, parent):
     repo.commitctx(
         context.memctx(repo, (parent, node.nullid),
                        'automated test (%s)' % name, [name],
                        file_callback(name), 'an_author',
                        '2009-10-19 18:49:30 -0500', {
                            'branch': name,
                        }))
예제 #39
0
    def test_push_add_of_added_upstream_gives_sane_error(self):
        repo = self.repo
        def file_callback(repo, memctx, path):
            if path == 'adding_file':
                return compathacks.makememfilectx(repo,
                                                  path=path,
                                                  data='foo',
                                                  islink=False,
                                                  isexec=False,
                                                  copied=False)
            raise IOError()
        p1 = repo['default'].node()
        ctx = context.memctx(repo,
                             (p1, node.nullid),
                             'automated test',
                             ['adding_file'],
                             file_callback,
                             'an_author',
                             '2008-10-07 20:59:48 -0500',
                             {'branch': 'default', })
        new_hash = repo.commitctx(ctx)
        hg.update(repo, repo['tip'].node())
        old_tip = repo['tip'].node()
        self.pushrevisions()
        tip = self.repo['tip']
        self.assertNotEqual(tip.node(), old_tip)

        # This node adds the same file as the first one we added, and
        # will be refused by the server for adding a file that already
        # exists. We should respond with an error suggesting the user
        # rebase.
        ctx = context.memctx(repo,
                             (p1, node.nullid),
                             'automated test',
                             ['adding_file'],
                             file_callback,
                             'an_author',
                             '2008-10-07 20:59:48 -0500',
                             {'branch': 'default', })
        new_hash = repo.commitctx(ctx)
        hg.update(repo, repo['tip'].node())
        old_tip = repo['tip'].node()
        try:
          self.pushrevisions()
        except hgutil.Abort, e:
          assert "pull again and rebase" in str(e)
예제 #40
0
파일: uncommit.py 프로젝트: CJX32/my_blog
def unamend(ui, repo, **opts):
    """undo the most recent amend operation on a current changeset

    This command will roll back to the previous version of a changeset,
    leaving working directory in state in which it was before running
    `hg amend` (e.g. files modified as part of an amend will be
    marked as modified `hg status`)
    """

    unfi = repo.unfiltered()
    with repo.wlock(), repo.lock(), repo.transaction(b'unamend'):

        # identify the commit from which to unamend
        curctx = repo[b'.']

        rewriteutil.precheck(repo, [curctx.rev()], b'unamend')

        # identify the commit to which to unamend
        markers = list(predecessormarkers(curctx))
        if len(markers) != 1:
            e = _(
                b"changeset must have one predecessor, found %i predecessors")
            raise error.Abort(e % len(markers))

        prednode = markers[0].prednode()
        predctx = unfi[prednode]

        # add an extra so that we get a new hash
        # note: allowing unamend to undo an unamend is an intentional feature
        extras = predctx.extra()
        extras[b'unamend_source'] = curctx.hex()

        def filectxfn(repo, ctx_, path):
            try:
                return predctx.filectx(path)
            except KeyError:
                return None

        # Make a new commit same as predctx
        newctx = context.memctx(
            repo,
            parents=(predctx.p1(), predctx.p2()),
            text=predctx.description(),
            files=predctx.files(),
            filectxfn=filectxfn,
            user=predctx.user(),
            date=predctx.date(),
            extra=extras,
        )
        newprednode = repo.commitctx(newctx)
        newpredctx = repo[newprednode]
        dirstate = repo.dirstate

        with dirstate.parentchange():
            scmutil.movedirstate(repo, newpredctx)

        mapping = {curctx.node(): (newprednode, )}
        scmutil.cleanupnodes(repo, mapping, b'unamend', fixphase=True)
예제 #41
0
def replacerev(ui, repo, ctx, filedata, replacements):
    """Commit a new revision like the given one, but with file content changes

    "ctx" is the original revision to be replaced by a modified one.

    "filedata" is a dict that maps paths to their new file content. All other
    paths will be recreated from the original revision without changes.
    "filedata" may contain paths that didn't exist in the original revision;
    they will be added.

    "replacements" is a dict that maps a single node to a single node, and it is
    updated to indicate the original revision is replaced by the newly created
    one. No entry is added if the replacement's node already exists.

    The new revision has the same parents as the old one, unless those parents
    have already been replaced, in which case those replacements are the parents
    of this new revision. Thus, if revisions are replaced in topological order,
    there is no need to rebase them into the original topology later.
    """

    p1rev, p2rev = repo.changelog.parentrevs(ctx.rev())
    p1ctx, p2ctx = repo[p1rev], repo[p2rev]
    newp1node = replacements.get(p1ctx.node(), p1ctx.node())
    newp2node = replacements.get(p2ctx.node(), p2ctx.node())

    def filectxfn(repo, memctx, path):
        if path not in ctx:
            return None
        fctx = ctx[path]
        copied = fctx.renamed()
        if copied:
            copied = copied[0]
        return context.memfilectx(
            repo,
            memctx,
            path=fctx.path(),
            data=filedata.get(path, fctx.data()),
            islink=fctx.islink(),
            isexec=fctx.isexec(),
            copied=copied)

    memctx = context.memctx(
        repo,
        parents=(newp1node, newp2node),
        text=ctx.description(),
        files=set(ctx.files()) | set(filedata.keys()),
        filectxfn=filectxfn,
        user=ctx.user(),
        date=ctx.date(),
        extra=ctx.extra(),
        branch=ctx.branch(),
        editor=None)
    sucnode = memctx.commit()
    prenode = ctx.node()
    if prenode == sucnode:
        ui.debug('node %s already existed\n' % (ctx.hex()))
    else:
        replacements[ctx.node()] = sucnode
예제 #42
0
def push_to_try(ui, repo, server, message=None):

    nodate = ui.configbool('push-to-try', 'nodate')

    if not message or 'try:' not in message:
        ui.status("STOP! A commit message with try syntax is required.\n")
        return

    cctx = context.workingctx(repo)
    status = repo.status()

    if status.modified + status.added + status.removed:
        ui.status('The following will be pushed to %s:\n' % server)
        # TODO: Achieve this by re-using the status call above to avoid the
        # cost of running it twice.
        commands.status(ui, repo)

    preserve_ctx = preservefilectx(cctx)
    def mk_memfilectx(repo, memctx, path):
        if path not in status.removed:
            return preserve_ctx(repo, memctx, path)
        return None

    # Invent a temporary commit with our message.
    ui.status("Creating temporary commit for remote...\n")
    mctx = context.memctx(repo,
                          repo.dirstate.parents(),
                          message,
                          cctx.files(),
                          mk_memfilectx,
                          date="0 0" if nodate else None)

    # These messages are expected when we abort our transaction, but aren't
    # helpful to a user and may be misleading so we surpress them here.
    filtered_phrases = {_("transaction abort!\n"),
                        _("rollback completed\n")}
    def filtered_warn(*msgs, **opts):
        if msgs:
            filtered = [m for m in msgs if m not in filtered_phrases]
        if filtered:
            ui.warn(*filtered, **opts)

    lock = tr = None
    try:
        lock = repo.lock()
        tr = repo.transaction('push-to-try', report=filtered_warn)
        m = mctx.commit()
        # Push to try.
        commands.push(ui, repo, server, force=True, rev=[repo[m].rev()])
        ui.status('push complete\n')
        # And rollback to the previous state.
        tr.abort()
    finally:
        if tr:
            tr.release()
        if lock:
            lock.release()
        ui.status("temporary commit removed, repository restored\n")
예제 #43
0
def _overlayrev(sourcerepo, sourceurl, sourcectx, destrepo, destctx, prefix):
    """Overlay a single commit into another repo."""
    assert prefix.endswith(b'/')
    assert len(sourcectx.parents()) < 2

    sourceman = sourcectx.manifest()

    def filectxfn(repo, memctx, path):
        sourcepath = path[len(prefix):]
        if sourcepath not in sourceman:
            return None

        node, flags = sourceman.find(sourcepath)
        sourcefl = sourcerepo.file(sourcepath)
        data = sourcefl.read(node)

        islink = b'l' in flags
        isexec = b'x' in flags

        copied = None
        renamed = sourcefl.renamed(node)
        if renamed:
            copied = b'%s%s' % (prefix, renamed[0])

        # TRACKING hg50 - `copied` renamed to `copysource`
        if util.versiontuple(n=2) >= (5, 0):
            return context.memfilectx(repo,
                                      memctx,
                                      path,
                                      data,
                                      islink=islink,
                                      isexec=isexec,
                                      copysource=copied)
        else:
            return context.memfilectx(repo,
                                      memctx,
                                      path,
                                      data,
                                      islink=islink,
                                      isexec=isexec,
                                      copied=copied)

    parents = [destctx.node(), None]
    files = [b'%s%s' % (prefix, f) for f in sourcectx.files()]
    extra = dict(sourcectx.extra())
    extra[REVISION_KEY] = sourcectx.hex()
    extra[SOURCE_KEY] = sourceurl

    memctx = context.memctx(destrepo,
                            parents,
                            sourcectx.description(),
                            files,
                            filectxfn,
                            user=sourcectx.user(),
                            date=sourcectx.date(),
                            extra=extra)

    return memctx.commit()
예제 #44
0
    def test_parent_output(self):
        self._load_fixture_and_fetch('two_heads.svndump')
        u = self.ui()
        u.pushbuffer()
        parents = (
            revsymbol(self.repo, 'the_branch').node(),
            revlog.nullid,
        )

        def filectxfn(repo, memctx, path):
            return compathacks.makememfilectx(repo,
                                              memctx=memctx,
                                              path=path,
                                              data='added',
                                              islink=False,
                                              isexec=False,
                                              copied=False)

        lr = self.repo
        ctx = context.memctx(lr, parents, 'automated test', [
            'added_bogus_file',
            'other_added_file',
        ], filectxfn, 'testy', '2008-12-21 16:32:00 -0500', {
            'branch': 'localbranch',
        })
        new = lr.commitctx(ctx)
        hg.update(self.repo, new)
        wrappers.parents(lambda x, y: None, u, self.repo, svn=True)
        actual = u.popbuffer()
        # two hashes becaure in hg > 4.8 we try hard to reuse the manifest
        self.assertTrue(actual in ('3:4e256962fc5d\n', '3:13c5dc1514ad\n'))

        hg.update(self.repo, revsymbol(self.repo, 'default'))

        # Make sure styles work
        u.pushbuffer()
        wrappers.parents(lambda x, y: None,
                         u,
                         self.repo,
                         svn=True,
                         style='compact')
        actual = u.popbuffer()
        self.assertEqual(actual, '4:1083037b18d8\n')

        # custom templates too
        u.pushbuffer()
        wrappers.parents(lambda x, y: None,
                         u,
                         self.repo,
                         svn=True,
                         template='{node}\n')
        actual = u.popbuffer()
        self.assertEqual(actual, '1083037b18d85cd84fa211c5adbaeff0fea2cd9f\n')

        u.pushbuffer()
        wrappers.parents(lambda x, y: None, u, self.repo, svn=True)
        actual = u.popbuffer()
        self.assertEqual(actual, '4:1083037b18d8\n')
예제 #45
0
 def commit_to_branch(name, parent):
     repo.commitctx(context.memctx(repo,
                                   (parent, node.nullid),
                                   'automated test (%s)' % name,
                                   [name],
                                   file_callback(name),
                                   'an_author',
                                   '2009-10-19 18:49:30 -0500',
                                   {'branch': name,}))
예제 #46
0
 def delbranch(self, branch, node, rev):
     extra = self.genextra(rev.revnum, branch)
     self.mapbranch(extra, True)
     ctx = context.memctx(self.repo, (node, revlog.nullid),
                          self.getmessage(rev), [], lambda x, y, z: None,
                          util.forceutf8(self.authors[rev.author]),
                          self.fixdate(rev.date), extra)
     self.repo.svn_commitctx(ctx)
     self.ui.status('Marked branch %s as closed.\n' % (branch or 'default'))
예제 #47
0
 def test_push_in_subdir(self, commit=True):
     repo = self.repo
     old_tip = repo['tip'].node()
     def file_callback(repo, memctx, path):
         if path == 'adding_file' or path == 'newdir/new_file':
             testData = 'fooFirstFile'
             if path == 'newdir/new_file':
                 testData = 'fooNewFile'
             return compathacks.makememfilectx(repo,
                                               path=path,
                                               data=testData,
                                               islink=False,
                                               isexec=False,
                                               copied=False)
         raise IOError(errno.EINVAL, 'Invalid operation: ' + path)
     ctx = context.memctx(repo,
                          (repo['default'].node(), node.nullid),
                          'automated test',
                          ['adding_file'],
                          file_callback,
                          'an_author',
                          '2012-12-13 20:59:48 -0500',
                          {'branch': 'default', })
     new_hash = repo.commitctx(ctx)
     p = os.path.join(repo.root, "newdir")
     os.mkdir(p)
     ctx = context.memctx(repo,
                          (repo['default'].node(), node.nullid),
                          'automated test',
                          ['newdir/new_file'],
                          file_callback,
                          'an_author',
                          '2012-12-13 20:59:48 -0500',
                          {'branch': 'default', })
     os.chdir(p)
     new_hash = repo.commitctx(ctx)
     hg.update(repo, repo['tip'].node())
     self.pushrevisions()
     tip = self.repo['tip']
     self.assertNotEqual(tip.node(), old_tip)
     self.assertEqual(p, os.getcwd())
     self.assertEqual(tip['adding_file'].data(), 'fooFirstFile')
     self.assertEqual(tip['newdir/new_file'].data(), 'fooNewFile')
     self.assertEqual(tip.branch(), 'default')
예제 #48
0
    def test_push_in_subdir(self, commit=True):
        repo = self.repo
        old_tip = revsymbol(repo, 'tip').node()

        def file_callback(repo, memctx, path):
            if path == 'adding_file' or path == 'newdir/new_file':
                testData = 'fooFirstFile'
                if path == 'newdir/new_file':
                    testData = 'fooNewFile'
                return compathacks.makememfilectx(repo,
                                                  memctx=memctx,
                                                  path=path,
                                                  data=testData,
                                                  islink=False,
                                                  isexec=False,
                                                  copied=False)
            raise IOError(errno.EINVAL, 'Invalid operation: ' + path)

        ctx = context.memctx(repo,
                             (revsymbol(repo, 'default').node(), node.nullid),
                             'automated test', ['adding_file'], file_callback,
                             'an_author', '2012-12-13 20:59:48 -0500', {
                                 'branch': 'default',
                             })
        new_hash = repo.commitctx(ctx)
        p = os.path.join(repo.root, "newdir")
        os.mkdir(p)
        ctx = context.memctx(repo,
                             (revsymbol(repo, 'default').node(), node.nullid),
                             'automated test', ['newdir/new_file'],
                             file_callback, 'an_author',
                             '2012-12-13 20:59:48 -0500', {
                                 'branch': 'default',
                             })
        os.chdir(p)
        new_hash = repo.commitctx(ctx)
        hg.update(repo, revsymbol(repo, 'tip').node())
        self.pushrevisions()
        tip = revsymbol(self.repo, 'tip')
        self.assertNotEqual(tip.node(), old_tip)
        self.assertEqual(p, os.getcwd())
        self.assertEqual(tip['adding_file'].data(), 'fooFirstFile')
        self.assertEqual(tip['newdir/new_file'].data(), 'fooNewFile')
        self.assertEqual(tip.branch(), 'default')
예제 #49
0
    def commit(self):
        repo = self.repo.repo

        def get_file(repo, ctx, path):
            # XXX: copy sources
            # XXX: renames
            # XXX: deletes
            if path in rn and path not in self.contents:
                raise IOError()
            if path in rrn:
                assert base is not None
                parent = self.base_commit.rev[rrn[path]]
                if path in self.contents:
                    data = self.contents[path]
                else:
                    data = parent.data()
                copied = rrn[path]
            else:
                data = self.contents[path]
                copied = False
            # XXX: real flags
            islink = False
            isexec = False

            return context.memfilectx(
                repo=self.repo,
                path=path,
                data=data,
                islink=islink,
                isexec=isexec,
                copied=copied,
            )

        rn = dict(
            (k, v) for k, v in self.renames if self.base_commit.exists(k))
        rrn = dict(reversed(x) for x in self.renames)
        # XXX: directory renames

        files = set(self.contents)
        files.update(rn.keys())
        files.update(rn.values())

        if self.base_commit is not None:
            base = self.base_commit.rev.node()
        else:
            base = None
        ctx = context.memctx(
            repo=repo,
            parents=[base, None],
            text=self.extra['message'],
            files=sorted(files),
            filectxfn=get_file,
            user=self.author,
            date="%(time_unix)d %(time_offset)s" % self.__dict__,
        )
        repo.commitctx(ctx)
예제 #50
0
    def createfn(repo, ctx, revmap, filectxfn):
        parents = newparents(repo, ctx, revmap)

        files = ctx.files()
        files.pop()
        memctx = context.memctx(repo, parents, ctx.description(),
                                files, filectxfn, user=ctx.user(),
                                date=ctx.date(), extra=ctx.extra())

        return memctx
예제 #51
0
    def test_push_add_of_added_upstream_gives_sane_error(self):
        repo = self.repo

        def file_callback(repo, memctx, path):
            if path == 'adding_file':
                return compathacks.makememfilectx(repo,
                                                  memctx=memctx,
                                                  path=path,
                                                  data='foo',
                                                  islink=False,
                                                  isexec=False,
                                                  copied=False)
            raise IOError()

        p1 = revsymbol(repo, 'default').node()
        ctx = context.memctx(repo, (p1, node.nullid), 'automated test',
                             ['adding_file'], file_callback, 'an_author',
                             '2008-10-07 20:59:48 -0500', {
                                 'branch': 'default',
                             })
        new_hash = repo.commitctx(ctx)
        hg.update(repo, revsymbol(repo, 'tip').node())
        old_tip = revsymbol(repo, 'tip').node()
        self.pushrevisions()
        tip = revsymbol(self.repo, 'tip')
        self.assertNotEqual(tip.node(), old_tip)

        # This node adds the same file as the first one we added, and
        # will be refused by the server for adding a file that already
        # exists. We should respond with an error suggesting the user
        # rebase.
        ctx = context.memctx(repo, (p1, node.nullid), 'automated test',
                             ['adding_file'], file_callback, 'an_author',
                             '2008-10-07 20:59:48 -0500', {
                                 'branch': 'default',
                             })
        new_hash = repo.commitctx(ctx)
        hg.update(repo, revsymbol(repo, 'tip').node())
        old_tip = revsymbol(repo, 'tip').node()
        try:
            self.pushrevisions()
        except hgerror.Abort, e:
            assert "pull again and rebase" in str(e)
예제 #52
0
    def createfn(repo, ctx, revmap, filectxfn):
        parents = newparents(repo, ctx, revmap)

        files = ctx.files()
        files.pop()
        memctx = context.memctx(
            repo, parents, ctx.description(), files, filectxfn, user=ctx.user(), date=ctx.date(), extra=ctx.extra()
        )

        return memctx
예제 #53
0
    def commitchanges(self, changes, parent='tip', message='automated test'):
        """Commit changes to mercurial directory

        'changes' is a sequence of tuples (source, dest, data). It can look
        like:
        - (source, source, data) to set source content to data
        - (source, dest, None) to set dest content to source one, and mark it as
        copied from source.
        - (source, dest, data) to set dest content to data, and mark it as copied
        from source.
        - (source, None, None) to remove source.
        """
        repo = self.repo
        if isinstance(parent, int):
            parentctx = repo[parent]
        else:
            parentctx = revsymbol(repo, parent)

        changed, removed = [], []
        for source, dest, newdata in changes:
            if dest is None:
                removed.append(source)
            else:
                changed.append(dest)

        def filectxfn(repo, memctx, path):
            if path in removed:
                return compathacks.filectxfn_deleted(memctx, path)
            entry = [e for e in changes if path == e[1]][0]
            source, dest, newdata = entry
            if newdata is None:
                newdata = parentctx[source].data()
            copied = None
            if source != dest:
                copied = source
            return compathacks.makememfilectx(repo,
                                              memctx=memctx,
                                              path=dest,
                                              data=newdata,
                                              islink=False,
                                              isexec=False,
                                              copied=copied)

        ctx = context.memctx(repo,
                             (parentctx.node(), node.nullid),
                             message,
                             changed + removed,
                             filectxfn,
                             'an_author',
                             '2008-10-07 20:59:48 -0500',
                             {'branch': parentctx.branch()})
        nodeid = repo.commitctx(ctx)
        repo = self.repo
        hg.clean(repo, nodeid)
        return nodeid
예제 #54
0
    def puttags(self, tags):
        tagparent = self.repo.branchtip(self.tagsbranch, ignoremissing=True)
        tagparent = tagparent or self.repo.nullid

        oldlines = set()
        for branch, heads in pycompat.iteritems(self.repo.branchmap()):
            for h in heads:
                if b'.hgtags' in self.repo[h]:
                    oldlines.update(
                        set(self.repo[h][b'.hgtags'].data().splitlines(True)))
        oldlines = sorted(list(oldlines))

        newlines = sorted([(b"%s %s\n" % (tags[tag], tag)) for tag in tags])
        if newlines == oldlines:
            return None, None

        # if the old and new tags match, then there is nothing to update
        oldtags = set()
        newtags = set()
        for line in oldlines:
            s = line.strip().split(b' ', 1)
            if len(s) != 2:
                continue
            oldtags.add(s[1])
        for line in newlines:
            s = line.strip().split(b' ', 1)
            if len(s) != 2:
                continue
            if s[1] not in oldtags:
                newtags.add(s[1].strip())

        if not newtags:
            return None, None

        data = b"".join(newlines)

        def getfilectx(repo, memctx, f):
            return context.memfilectx(repo, memctx, f, data, False, False,
                                      None)

        self.ui.status(_(b"updating tags\n"))
        date = b"%d 0" % int(time.mktime(time.gmtime()))
        extra = {b'branch': self.tagsbranch}
        ctx = context.memctx(
            self.repo,
            (tagparent, None),
            b"update tags",
            [b".hgtags"],
            getfilectx,
            b"convert-repo",
            date,
            extra,
        )
        node = self.repo.commitctx(ctx)
        return hex(node), hex(tagparent)
예제 #55
0
 def delbranch(self, branch, node, rev):
     pctx = self.repo[node]
     files = pctx.manifest().keys()
     extra = self.genextra(rev.revnum, branch)
     self.mapbranch(extra, True)
     ctx = context.memctx(self.repo, (node, revlog.nullid), rev.message
                          or util.default_commit_msg(self.ui), [],
                          lambda x, y, z: None, self.authors[rev.author],
                          self.fixdate(rev.date), extra)
     new = self.repo.commitctx(ctx)
     self.ui.status('Marked branch %s as closed.\n' % (branch or 'default'))
예제 #56
0
 def commit_octopus(p1, p2):
     ctx = context.memctx(
         self.repo,
         (p1, p2),
         text,
         list(files) + findconvergedfiles(p1, p2),
         getfilectx,
         author,
         date,
         {"hg-git": "octopus"},
     )
     return hex(self.repo.commitctx(ctx))
예제 #57
0
    def addcommitid(repo, ctx, revmap, copyfilectxfn):
        parents = newparents(repo, ctx, revmap)
        # Need to make a copy otherwise modification is made on original,
        # which is just plain wrong.
        extra = dict(ctx.extra())
        assert "commitid" not in extra
        extra["commitid"] = genid(repo)
        memctx = context.memctx(
            repo, parents, ctx.description(), ctx.files(), copyfilectxfn, user=ctx.user(), date=ctx.date(), extra=extra
        )

        return memctx
예제 #58
0
파일: hg.py 프로젝트: MezzLabs/mercurial
    def putcommit(self, files, copies, parents, commit, source, revmap):

        files = dict(files)
        def getfilectx(repo, memctx, f):
            v = files[f]
            data, mode = source.getfile(f, v)
            if f == '.hgtags':
                data = self._rewritetags(source, revmap, data)
            return context.memfilectx(f, data, 'l' in mode, 'x' in mode,
                                      copies.get(f))

        pl = []
        for p in parents:
            if p not in pl:
                pl.append(p)
        parents = pl
        nparents = len(parents)
        if self.filemapmode and nparents == 1:
            m1node = self.repo.changelog.read(bin(parents[0]))[0]
            parent = parents[0]

        if len(parents) < 2:
            parents.append(nullid)
        if len(parents) < 2:
            parents.append(nullid)
        p2 = parents.pop(0)

        text = commit.desc
        extra = commit.extra.copy()
        if self.branchnames and commit.branch:
            extra['branch'] = commit.branch
        if commit.rev:
            extra['convert_revision'] = commit.rev

        while parents:
            p1 = p2
            p2 = parents.pop(0)
            ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
                                 getfilectx, commit.author, commit.date, extra)
            self.repo.commitctx(ctx)
            text = "(octopus merge fixup)\n"
            p2 = hex(self.repo.changelog.tip())

        if self.filemapmode and nparents == 1:
            man = self.repo.manifest
            mnode = self.repo.changelog.read(bin(p2))[0]
            closed = 'close' in commit.extra
            if not closed and not man.cmp(m1node, man.revision(mnode)):
                self.ui.status(_("filtering out empty revision\n"))
                self.repo.rollback()
                return parent
        return p2
예제 #59
0
    def makememctx(repo, ctx, revmap, copyfilectxfn):
        parents = newparents(repo, ctx, revmap)
        # Need to make a copy otherwise modification is made on original,
        # which is just plain wrong.
        msg = encoding.fromlocal(ctx.description())
        new_msg, changed = addcommitid(msg, repo=repo)

        memctx = context.memctx(repo, parents,
                                encoding.tolocal(new_msg), ctx.files(),
                                copyfilectxfn, user=ctx.user(),
                                date=ctx.date(), extra=dict(ctx.extra()))

        return memctx