def test_push_two_that_modify_same_file(self): ''' Push performs a rebase if two commits touch the same file. This test verifies that code path works. ''' oldlen = test_util.repolen(self.repo) oldtiphash = self.repo['default'].node() changes = [('gamma', 'gamma', 'sometext')] newhash = self.commitchanges(changes) changes = [('gamma', 'gamma', 'sometext\n moretext'), ('delta', 'delta', 'sometext\n moretext'), ] newhash = self.commitchanges(changes) repo = self.repo hg.update(repo, newhash) commands.push(repo.ui, repo) self.assertEqual(test_util.repolen(self.repo), oldlen + 2) # verify that both commits are pushed commit1 = self.repo['tip'] self.assertEqual(commit1.files(), ['delta', 'gamma']) prefix = 'svn:' + self.repo.svnmeta().uuid self.assertEqual(util.getsvnrev(commit1), prefix + '/branches/the_branch@6') commit2 = commit1.parents()[0] self.assertEqual(commit2.files(), ['gamma']) self.assertEqual(util.getsvnrev(commit2), prefix + '/branches/the_branch@5')
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)
def test_push_without_pushing_children(self): ''' Verify that a push of a nontip node, keeps the tip child on top of the pushed commit. ''' oldlen = test_util.repolen(self.repo) oldtiphash = self.repo['default'].node() changes = [('gamma', 'gamma', 'sometext')] newhash1 = self.commitchanges(changes) changes = [('delta', 'delta', 'sometext')] newhash2 = self.commitchanges(changes) # push only the first commit repo = self.repo hg.update(repo, newhash1) commands.push(repo.ui, repo) self.assertEqual(test_util.repolen(self.repo), oldlen + 2) # verify that the first commit is pushed, and the second is not commit2 = self.repo['tip'] self.assertEqual(commit2.files(), ['delta', ]) self.assertEqual(util.getsvnrev(commit2), None) commit1 = commit2.parents()[0] self.assertEqual(commit1.files(), ['gamma', ]) prefix = 'svn:' + self.repo.svnmeta().uuid self.assertEqual(util.getsvnrev(commit1), prefix + '/branches/the_branch@5')
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, ''))
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())
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')
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', ])
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))
def test_push_to_non_tip(self): self.test_push_to_branch(push=False) wc2path = self.wc_path + '_clone' u = self.repo.ui hg.clone(self.repo.ui, self.wc_path, wc2path, update=False) res = self.pushrevisions() self.assertEqual(0, res) oldf = open(os.path.join(self.wc_path, '.hg', 'hgrc')) hgrc = oldf.read() oldf.close() shutil.rmtree(self.wc_path) hg.clone(u, wc2path, self.wc_path, update=False) oldf = open(os.path.join(self.wc_path, '.hg', 'hgrc'), 'w') oldf.write(hgrc) oldf.close() # do a commit here self.commitchanges([('foobaz', 'foobaz', 'This file is added on default.', ), ], parent='default', message='commit to default') from hgsubversion import svncommands svncommands.rebuildmeta(u, self.repo, args=[test_util.fileurl(self.repo_path)]) hg.update(self.repo, self.repo['tip'].node()) oldnode = self.repo['tip'].hex() self.pushrevisions(expected_extra_back=1) self.assertNotEqual(oldnode, self.repo['tip'].hex(), 'Revision was not pushed.')
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'])
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())
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')
def pullrebase(orig, ui, repo, *args, **opts): 'Call rebase after pull if the latter has been invoked with --rebase' if opts.get('rebase'): if opts.get('update'): del opts['update'] ui.debug('--update and --rebase are not compatible, ignoring ' 'the update flag\n') movemarkfrom = repo['.'].node() cmdutil.bailifchanged(repo) revsprepull = len(repo) origpostincoming = commands.postincoming def _dummy(*args, **kwargs): pass commands.postincoming = _dummy try: orig(ui, repo, *args, **opts) finally: commands.postincoming = origpostincoming revspostpull = len(repo) if revspostpull > revsprepull: rebase(ui, repo, **opts) branch = repo[None].branch() dest = repo[branch].rev() if dest != repo['.'].rev(): # there was nothing to rebase we force an update hg.update(repo, dest) if bookmarks.update(repo, [movemarkfrom], repo['.'].node()): ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent) else: if opts.get('tool'): raise util.Abort(_('--tool can only be used with --rebase')) orig(ui, repo, *args, **opts)
def pick(ui, repo, ctx, ha, opts): oldctx = repo[ha] if oldctx.parents()[0] == ctx: ui.debug('node %s unchanged\n' % ha) return oldctx, [], [], [] hg.update(repo, ctx.node()) fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-') fp = os.fdopen(fd, 'w') diffopts = patch.diffopts(ui, opts) diffopts.git = True gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts) for chunk in gen: fp.write(chunk) fp.close() try: files = {} try: patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None) if not files: ui.warn(_('%s: empty changeset') % node.hex(ha)) return ctx, [], [], [] finally: files = patch.updatedir(ui, repo, files) os.unlink(patchfile) except Exception, inst: raise util.Abort(_('Fix up the change and run ' 'hg histedit --continue'))
def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges): parent = ctx.parents()[0].node() hg.update(repo, parent) fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-') fp = os.fdopen(fd, 'w') diffopts = patch.diffopts(ui, opts) diffopts.git = True gen = patch.diff(repo, parent, newnode, opts=diffopts) for chunk in gen: fp.write(chunk) fp.close() files = {} try: patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None) finally: files = patch.updatedir(ui, repo, files) os.unlink(patchfile) newmessage = '\n***\n'.join( [ctx.description(), ] + [repo[r].description() for r in internalchanges] + [oldctx.description(), ]) newmessage = ui.edit(newmessage, ui.username()) n = repo.commit(text=newmessage, user=ui.username(), date=max(ctx.date(), oldctx.date()), extra=oldctx.extra()) return repo[n], [n, ], [oldctx.node(), ctx.node() ], [newnode, ] # xxx
def pullrebaseif(orig, ui, repo, *args, **opts): '''Call rebaseif after pull if the latter has been invoked with --rebaseif''' # this function is taken in verbatim from rebase extension, with rebase replaced with rebaseif if opts.get('rebaseif'): if opts.get('update'): del opts['update'] ui.debug(_('--update and --rebaseif are not compatible, ignoring the update flag\n')) try: cmdutil.bailifchanged(repo) # 1.9 except AttributeError: cmdutil.bail_if_changed(repo) # < 1.9 revsprepull = len(repo) origpostincoming = commands.postincoming def _dummy(*args, **kwargs): pass commands.postincoming = _dummy try: orig(ui, repo, *args, **opts) finally: commands.postincoming = origpostincoming revspostpull = len(repo) if revspostpull > revsprepull: rebaseif(ui, repo, **opts) branch = repo[None].branch() dest = repo[branch].rev() if dest != repo['.'].rev(): # there was nothing to rebase we force an update hg.update(repo, dest) else: orig(ui, repo, *args, **opts)
def domergecmd(ui, repo, *revs, **opts): node = (list(revs) + opts.get('rev'))[0] originalCtx = repo[None].parents()[0] originalRev = originalCtx.rev() ui.write('Updating to revision %s \n' % node) hg.updaterepo(repo, node, True) defaultRev = repo['default'].rev() ui.write('Merging with default revision %s \n' % defaultRev) hg.merge(repo, defaultRev) #TODO: handle conflict case ui.write('Committing after merge... \n') commitMsg = getMergeDescription(repo[None].parents()[0].description()) ui.write(' Commit message: %s \n' % commitMsg) repo.commit(commitMsg) if (originalRev != repo[None].parents()[0].parents()[0].rev()): # update to original rev in case branches are different ui.write('Updating to original revision %s \n' % originalRev) hg.update(repo, originalRev) return 0
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, '')
def edit(ui, repo, ctx, ha, opts): oldctx = repo[ha] hg.update(repo, ctx.node()) applychanges(ui, repo, oldctx, opts) raise error.InterventionRequired( _('Make changes as needed, you may commit or record as needed now.\n' 'When you are finished, run hg histedit --continue to resume.'))
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(''))
def pick(ui, repo, ctx, ha, opts): oldctx = repo[ha] if oldctx.parents()[0] == ctx: ui.debug('node %s unchanged\n' % ha) return oldctx, [], [], [] hg.update(repo, ctx.node()) fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-') fp = os.fdopen(fd, 'w') diffopts = patch.diffopts(ui, opts) diffopts.git = True diffopts.ignorews = False diffopts.ignorewsamount = False diffopts.ignoreblanklines = False gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts) for chunk in gen: fp.write(chunk) fp.close() try: files = set() try: applypatch(ui, repo, patchfile, files=files, eolmode=None) if not files: ui.warn(_('%s: empty changeset') % node.hex(ha)) return ctx, [], [], [] finally: os.unlink(patchfile) except Exception, inst: raise util.Abort(_('Fix up the change and run ' 'hg histedit --continue'))
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))
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(''))
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')
def fold(ui, repo, ctx, ha, opts): oldctx = repo[ha] hg.update(repo, ctx.node()) fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-') fp = os.fdopen(fd, 'w') diffopts = patch.diffopts(ui, opts) diffopts.git = True diffopts.ignorews = False diffopts.ignorewsamount = False diffopts.ignoreblanklines = False gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts) for chunk in gen: fp.write(chunk) fp.close() try: files = set() try: applypatch(ui, repo, patchfile, files=files, eolmode=None) if not files: ui.warn(_('%s: empty changeset') % node.hex(ha)) return ctx, [], [], [] finally: os.unlink(patchfile) except Exception, inst: raise util.Abort(_('Fix up the change and run ' 'hg histedit --continue'))
def pullrebase(orig, ui, repo, *args, **opts): 'Call rebase after pull if the latter has been invoked with --rebase' if opts.get('rebase'): if opts.get('update'): del opts['update'] ui.debug('--update and --rebase are not compatible, ignoring ' 'the update flag\n') cmdutil.bail_if_changed(repo) revsprepull = len(repo) origpostincoming = commands.postincoming def _dummy(*args, **kwargs): pass commands.postincoming = _dummy try: orig(ui, repo, *args, **opts) finally: commands.postincoming = origpostincoming revspostpull = len(repo) if revspostpull > revsprepull: rebase(ui, repo, **opts) branch = repo[None].branch() dest = repo[branch].rev() if dest != repo['.'].rev(): # there was nothing to rebase we force an update hg.update(repo, dest) else: orig(ui, repo, *args, **opts)
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')
def run(self): state = self.state repo, ctxnode = state.repo, state.parentctxnode hg.update(repo, ctxnode) # release locks so the program can call hg and then relock. lock.release(state.lock, state.wlock) try: ctx = repo[ctxnode] shell = encoding.environ.get('SHELL', None) cmd = self.command if shell and self.repo.ui.config('fbhistedit', 'exec_in_user_shell'): cmd = "%s -c -i %s" % (shell, quote(cmd)) rc = repo.ui.system(cmd, environ={'HGNODE': ctx.hex()}, cwd=self.cwd, blockedtag='histedit_exec') except OSError as ose: raise error.InterventionRequired( _("Cannot execute command '%s': %s") % (self.command, ose)) finally: # relock the repository state.wlock = repo.wlock() state.lock = repo.lock() repo.invalidateall() if rc != 0: raise error.InterventionRequired( _("Command '%s' failed with exit status %d") % (self.command, rc)) m, a, r, d = self.repo.status()[:4] if m or a or r or d: self.continuedirty() return self.continueclean()
def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges): parent = ctx.parents()[0].node() hg.update(repo, parent) fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-') fp = os.fdopen(fd, 'w') diffopts = patch.diffopts(ui, opts) diffopts.git = True diffopts.ignorews = False diffopts.ignorewsamount = False diffopts.ignoreblanklines = False gen = patch.diff(repo, parent, newnode, opts=diffopts) for chunk in gen: fp.write(chunk) fp.close() files = set() try: applypatch(ui, repo, patchfile, files=files, eolmode=None) finally: os.unlink(patchfile) newmessage = '\n***\n'.join( [ctx.description(), ] + [repo[r].description() for r in internalchanges] + [oldctx.description(), ]) # If the changesets are from the same author, keep it. if ctx.user() == oldctx.user(): username = ctx.user() else: username = ui.username() newmessage = ui.edit(newmessage, username) n = repo.commit(text=newmessage, user=username, date=max(ctx.date(), oldctx.date()), extra=oldctx.extra()) return repo[n], [n, ], [oldctx.node(), ctx.node() ], [newnode, ] # xxx
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)
def test_genignore_single(self): self._load_fixture_and_fetch('ignores.svndump', subdir='trunk') hg.update(self.repo, 'tip') u = self.ui() u.pushbuffer() svncommands.genignore(u, self.repo, self.wc_path) self.assertStringEqual(open(os.path.join(self.wc_path, '.hgignore')).read(), '.hgignore\nsyntax:glob\nblah\notherblah\nbaz/magic\n')
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')
def run(self): repo = self.repo rulectx = repo[self.node] hg.update(repo, self.state.parentctxnode) applychanges(repo.ui, repo, rulectx, {}) raise error.InterventionRequired( _('Make changes as needed, you may commit or record as needed ' 'now.\nWhen you are finished, run hg histedit --continue to ' 'resume.'))
def applychange(self): """Applies the changes from this action's rulectx onto the current parentctx, but does not commit them.""" repo = self.repo rulectx = repo[self.node] hg.update(repo, self.state.parentctxnode) stats = applychanges(repo.ui, repo, rulectx, {}) if stats and stats[3] > 0: raise error.InterventionRequired(_('Fix up the change and run ' 'hg histedit --continue'))
def fold(ui, repo, ctx, ha, opts): oldctx = repo[ha] hg.update(repo, ctx.node()) stats = applychanges(ui, repo, oldctx, opts) if stats and stats[3] > 0: raise error.InterventionRequired(_("Fix up the change and run hg histedit --continue")) n = repo.commit(text="fold-temp-revision %s" % ha, user=oldctx.user(), date=oldctx.date(), extra=oldctx.extra()) if n is None: ui.warn(_("%s: empty changeset") % node.hex(ha)) return ctx, [] return finishfold(ui, repo, ctx, oldctx, n, opts, [])
def fold(ui, state, ha, opts): repo, ctx = state.repo, state.parentctx oldctx = repo[ha] hg.update(repo, ctx.node()) stats = applychanges(ui, repo, oldctx, opts) if stats and stats[3] > 0: raise error.InterventionRequired( _('Fix up the change and run hg histedit --continue')) n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(), date=oldctx.date(), extra=oldctx.extra()) if n is None: ui.warn(_('%s: empty changeset') % node.hex(ha)) return ctx, [] return finishfold(ui, repo, ctx, oldctx, n, opts, [])
def checkout(self, path="."): """Clone a repository.""" path = os.path.abspath(path) if self.url == path: # update hg.update(self._repository, None) else: try: hg.clone(self._repository.ui, {}, self.url, path, update=True) except: # hg.clone fails for older versions of mercurial, e.g. 1.5 local_repos = hg.repository(self._repository.ui, path, create=True) local_repos.pull(self._repository) hg.update(local_repos, None)
def test_push_single_dir_branch(self): # Tests local branches pushing to a single dir repo. Creates a fork at # tip. The default branch adds a file called default, while branch foo # adds a file called foo, then tries to push the foo branch and default # branch in that order. repo, repo_path = self.load_and_fetch('branch_from_tag.svndump', layout='single', subdir='') def file_callback(data): def cb(repo, memctx, path): if path == data: return compathacks.makememfilectx(repo, memctx=memctx, path=path, data=data, islink=False, isexec=False, copied=False) raise IOError(errno.EINVAL, 'Invalid operation: ' + path) return cb 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, })) parent = repo['tip'].node() commit_to_branch('default', parent) commit_to_branch('foo', parent) hg.update(repo, revsymbol(repo, 'foo').node()) self.pushrevisions() repo = self.repo # repo is outdated after the rebase happens, refresh self.assertTrue('foo' in test_util.svnls(repo_path, '')) self.assertEqual(set(repo.branchmap()), set(['default'])) # Have to cross to another branch head, so hg.update doesn't work commands.update(self.ui(), self.repo, node.hex(self.repo.branchheads('default')[1]), clean=True) self.pushrevisions() self.assertTrue('default' in test_util.svnls(repo_path, '')) self.assertEquals(len(self.repo.branchheads('default')), 1)
def update(ui, args, repo, clean=False, **opts): """update to a specified Subversion revision number """ try: rev = int(args[0]) except IndexError: raise error.CommandError('svn', "no revision number specified for 'update'") except ValueError: raise error.Abort("'%s' is not a valid Subversion revision number" % args[0]) meta = repo.svnmeta() answers = [] for k, v in meta.revmap.iteritems(): if k[0] == rev: answers.append((v, k[1])) if len(answers) == 1: if clean: return hg.clean(repo, answers[0][0]) return hg.update(repo, answers[0][0]) elif len(answers) == 0: ui.status('revision %s did not produce an hg revision\n' % rev) return 1 else: ui.status('ambiguous revision!\n') revs = ['%s on %s' % (node.hex(a[0]), a[1]) for a in answers] + [''] ui.status('\n'.join(revs)) return 1
def cloneunified(ui, dest='gecko', **opts): """Clone main Mozilla repositories into a unified local repository. This command will clone the most common Mozilla repositories and will add changesets and remote tracking markers into a common repository. If the destination path is not given, 'gecko' will be used. This command is effectively an alias for a number of other commands. However, due to the way Mercurial internally stores data, it is recommended to run this command to ensure optimal storage of data. """ path = ui.expandpath(dest) repo = hg.repository(ui, path, create=True) success = False try: for tree in ('esr17', 'b2g18', 'release', 'beta', 'aurora', 'central', 'inbound'): peer = hg.peer(ui, {}, tree) ui.warn('Pulling from %s.\n' % peer.url()) repo.pull(peer) res = hg.update(repo, repo.lookup('central/default')) success = True return res finally: if not success: shutil.rmtree(path)
def pullrebase(orig, ui, repo, *args, **opts): 'Call rebase after pull if the latter has been invoked with --rebase' if opts.get('rebase'): wlock = lock = None try: wlock = repo.wlock() lock = repo.lock() if opts.get('update'): del opts['update'] ui.debug('--update and --rebase are not compatible, ignoring ' 'the update flag\n') movemarkfrom = repo['.'].node() revsprepull = len(repo) origpostincoming = commands.postincoming def _dummy(*args, **kwargs): pass commands.postincoming = _dummy try: orig(ui, repo, *args, **opts) finally: commands.postincoming = origpostincoming revspostpull = len(repo) if revspostpull > revsprepull: # --rev option from pull conflict with rebase own --rev # dropping it if 'rev' in opts: del opts['rev'] # positional argument from pull conflicts with rebase's own # --source. if 'source' in opts: del opts['source'] rebase(ui, repo, **opts) branch = repo[None].branch() dest = repo[branch].rev() if dest != repo['.'].rev(): # there was nothing to rebase we force an update hg.update(repo, dest) if bookmarks.update(repo, [movemarkfrom], repo['.'].node()): ui.status(_("updating bookmark %s\n") % repo._activebookmark) finally: release(lock, wlock) else: if opts.get('tool'): raise util.Abort(_('--tool can only be used with --rebase')) orig(ui, repo, *args, **opts)
def test_incremental_fetching_of_repository_with_non_conflict_merge(self): # Create Mercurial configuration and override possible definition # of external interactive merge tools. ui = hgui() ui.setconfig("ui", "merge", "internal:merge") # Create Mercurial repository and Bazaar branch to import into. hgrepo = mercurial.localrepo.localrepository(ui, "hg", create=True) hgbranch = Branch.open("hg") bzrtree = self.make_branch_and_tree("bzr") # Create history graph in Mercurial repository # (history flows from left to right): # # A--B--D # | # \--C self.build_tree_contents([("hg/f1", "f1")]) hgrepo[None].add(["f1"]) hgrepo.commit("A (initial commit; first commit to main branch)") self.build_tree_contents([("hg/f2", "f2")]) hgrepo[None].add(["f2"]) hgrepo.commit("B (second commit to main branch)") hg.update(hgrepo, 0) self.build_tree_contents([("hg/f3", "f3")]) hgrepo[None].add(["f3"]) hgrepo.commit("C (first commit to secondary branch)") hg.update(hgrepo, 1) self.build_tree_contents([("hg/f4", "f4")]) hgrepo[None].add(["f4"]) hgrepo.commit("D (third commit to main branch)") # Pull commited changesets to Bazaar branch. bzrtree.pull(hgbranch) # Continue history graph in Mercurial repository # (history flows from up to down): # # a--b--d--E # | | # \--c--F-/ hg.update(hgrepo, 2) self.build_tree_contents([("hg/f5", "f5")]) hgrepo[None].add(["f5"]) hgrepo.commit("F (second commit to secondary branch)") hg.update(hgrepo, 3) hg.merge(hgrepo, 4) hgrepo.commit("E (commit merge of main branch with secondary branch)") # Pull commited changesets to Bazaar branch. bzrtree.pull(hgbranch) # Self-assurance check that all changesets was really pulled in. for i in range(1, 6): file_content = "f%d" % i file_path = "bzr/%s" % file_content self.assertFileEqual(file_content, file_path)
def mergefiles(ui, repo, wctx, shelvectx): """updates to wctx and merges the changes from shelvectx into the dirstate.""" with ui.configoverride({('ui', 'quiet'): True}): hg.update(repo, wctx.node()) files = [] files.extend(shelvectx.files()) files.extend(shelvectx.parents()[0].files()) # revert will overwrite unknown files, so move them out of the way for file in repo.status(unknown=True).unknown: if file in files: util.rename(file, scmutil.origpath(ui, repo, file)) ui.pushbuffer(True) cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(), *pathtofiles(repo, files), **{r'no_backup': True}) ui.popbuffer()
def test_push_single_dir(self): # Tests simple pushing from default branch to a single dir repo repo, repo_path = self.load_and_fetch('branch_from_tag.svndump', layout='single', subdir='') 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) elif path == 'adding_binary': return compathacks.makememfilectx(repo, memctx=memctx, path=path, data='\0binary', 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', 'adding_binary'], 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 test_util.svnls(repo_path, '')) self.assertEqual( 'application/octet-stream', test_util.svnpropget(repo_path, 'adding_binary', 'svn:mime-type')) # Now add another commit and test mime-type being reset changes = [('adding_binary', 'adding_binary', 'no longer binary')] self.commitchanges(changes) self.pushrevisions() self.assertEqual( '', test_util.svnpropget(repo_path, 'adding_binary', 'svn:mime-type'))
def finishfold(self, ui, repo, ctx, oldctx, newnode, internalchanges): parent = ctx.parents()[0].node() hg.update(repo, parent) ### prepare new commit data commitopts = {} commitopts['user'] = ctx.user() # commit message if self.skipprompt(): newmessage = ctx.description() else: newmessage = '\n***\n'.join( [ctx.description()] + [repo[r].description() for r in internalchanges] + [oldctx.description()]) + '\n' commitopts['message'] = newmessage # date commitopts['date'] = max(ctx.date(), oldctx.date()) extra = ctx.extra().copy() # histedit_source # note: ctx is likely a temporary commit but that the best we can do # here. This is sufficient to solve issue3681 anyway. extra['histedit_source'] = '%s,%s' % (ctx.hex(), oldctx.hex()) commitopts['extra'] = extra phasebackup = repo.ui.backupconfig('phases', 'new-commit') try: phasemin = max(ctx.phase(), oldctx.phase()) repo.ui.setconfig('phases', 'new-commit', phasemin, 'histedit') n = collapse(repo, ctx, repo[newnode], commitopts, skipprompt=self.skipprompt()) finally: repo.ui.restoreconfig(phasebackup) if n is None: return ctx, [] hg.update(repo, n) replacements = [ (oldctx.node(), (newnode, )), (ctx.node(), (n, )), (newnode, (n, )), ] for ich in internalchanges: replacements.append((ich, (n, ))) return repo[n], replacements
def message(ui, state, ha, opts): repo, ctx = state.repo, state.parentctx oldctx = repo[ha] hg.update(repo, ctx.node()) stats = applychanges(ui, repo, oldctx, opts) if stats and stats[3] > 0: raise error.InterventionRequired( _('Fix up the change and run hg histedit --continue')) message = oldctx.description() commit = commitfuncfor(repo, oldctx) editor = cmdutil.getcommiteditor(edit=True, editform='histedit.mess') new = commit(text=message, user=oldctx.user(), date=oldctx.date(), extra=oldctx.extra(), editor=editor) newctx = repo[new] if oldctx.node() != newctx.node(): return newctx, [(oldctx.node(), (new,))] # We didn't make an edit, so just indicate no replaced nodes return newctx, []
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')
def message(ui, repo, ctx, ha, opts): oldctx = repo[ha] hg.update(repo, ctx.node()) stats = applychanges(ui, repo, oldctx, opts) if stats and stats[3] > 0: raise error.InterventionRequired( _('Fix up the change and run hg histedit --continue')) message = oldctx.description() + '\n' message = ui.edit(message, ui.username()) commit = commitfuncfor(repo, oldctx) new = commit(text=message, user=oldctx.user(), date=oldctx.date(), extra=oldctx.extra()) newctx = repo[new] if oldctx.node() != newctx.node(): return newctx, [(oldctx.node(), (new, ))] # We didn't make an edit, so just indicate no replaced nodes return newctx, []
def test_delete_file(self): repo = self.repo def file_callback(repo, memctx, path): return compathacks.filectxfn_deleted(memctx, path) old_files = set(revsymbol(repo, 'default').manifest().keys()) ctx = context.memctx(repo, (revsymbol(repo, 'default').node(), node.nullid), 'automated test', ['alpha'], file_callback, 'an author', '2008-10-29 21:26:00 -0500', { 'branch': 'default', }) new_hash = repo.commitctx(ctx) hg.update(repo, revsymbol(repo, 'tip').node()) self.pushrevisions() tip = revsymbol(self.repo, 'tip') self.assertEqual(old_files, set(tip.manifest().keys() + ['alpha'])) self.assert_('alpha' not in tip.manifest())
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)
def pick(ui, state, ha, opts): repo, ctx = state.repo, state.parentctx oldctx = repo[ha] if oldctx.parents()[0] == ctx: ui.debug('node %s unchanged\n' % ha) return oldctx, [] hg.update(repo, ctx.node()) stats = applychanges(ui, repo, oldctx, opts) if stats and stats[3] > 0: raise error.InterventionRequired(_('Fix up the change and run ' 'hg histedit --continue')) # drop the second merge parent commit = commitfuncfor(repo, oldctx) n = commit(text=oldctx.description(), user=oldctx.user(), date=oldctx.date(), extra=oldctx.extra()) if n is None: ui.warn(_('%s: empty changeset\n') % node.hex(ha)) return ctx, [] new = repo[n] return new, [(oldctx.node(), (n,))]
def mergefiles(ui, repo, wctx, shelvectx): """updates to wctx and merges the changes from shelvectx into the dirstate.""" oldquiet = ui.quiet try: ui.quiet = True hg.update(repo, wctx.node()) files = [] files.extend(shelvectx.files()) files.extend(shelvectx.parents()[0].files()) # revert will overwrite unknown files, so move them out of the way m, a, r, d, u = repo.status(unknown=True)[:5] for file in u: if file in files: util.rename(file, file + ".orig") cmdutil.revert(ui, repo, shelvectx, repo.dirstate.parents(), *pathtofiles(repo, files), **{'no_backup': True}) finally: ui.quiet = oldquiet
def test_push_two_revs(self): # set up some work for us self.test_push_to_default(commit=False) repo = self.repo old_tip = revsymbol(repo, 'tip').node() expected_parent = revsymbol(repo, 'tip').parents()[0].node() def file_callback(repo, memctx, path): if path == 'adding_file2': return compathacks.makememfilectx(repo, memctx=memctx, path=path, data='foo2', 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_file2'], 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()) self.pushrevisions() tip = revsymbol(self.repo, 'tip') self.assertNotEqual(tip.node(), old_tip) self.assertNotEqual(tip.parents()[0].node(), old_tip) self.assertEqual(tip.parents()[0].parents()[0].node(), expected_parent) self.assertEqual(tip['adding_file2'].data(), 'foo2') self.assertEqual(tip['adding_file'].data(), 'foo') self.assertEqual(tip.parents()[0]['adding_file'].data(), 'foo') try: self.assertEqual(tip.parents()[0]['adding_file2'].data(), 'foo') assert False, "this is impossible, adding_file2 should not be in this manifest." except lookuperror, e: pass
def test_info_single(self, custom=False): if custom: subdir = None config = {'hgsubversionbranch.default': 'trunk/'} else: subdir = 'trunk' config = {} repo, repo_path = self.load_and_fetch('two_heads.svndump', subdir=subdir, config=config) hg.update(self.repo, 'tip') u = self.ui() u.pushbuffer() svncommands.info(u, self.repo) actual = u.popbuffer() expected = (expected_info_output % { 'date': '2008-10-08 01:39:29 +0000 (Wed, 08 Oct 2008)', 'repourl': repourl(repo_path), 'branch': 'trunk', 'rev': 6, }) self.assertMultiLineEqual(expected, actual)
def edit(ui, repo, ctx, ha, opts): oldctx = repo[ha] hg.update(repo, ctx.node()) fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-') fp = os.fdopen(fd, 'w') diffopts = patch.diffopts(ui, opts) diffopts.git = True diffopts.ignorews = False diffopts.ignorewsamount = False diffopts.ignoreblanklines = False gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts) for chunk in gen: fp.write(chunk) fp.close() try: files = set() try: applypatch(ui, repo, patchfile, files=files, eolmode=None) finally: os.unlink(patchfile) except Exception, inst: pass
def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges): parent = ctx.parents()[0].node() hg.update(repo, parent) fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-') fp = os.fdopen(fd, 'w') diffopts = patch.diffopts(ui, opts) diffopts.git = True diffopts.ignorews = False diffopts.ignorewsamount = False diffopts.ignoreblanklines = False gen = patch.diff(repo, parent, newnode, opts=diffopts) for chunk in gen: fp.write(chunk) fp.close() files = set() try: applypatch(ui, repo, patchfile, files=files, eolmode=None) finally: os.unlink(patchfile) newmessage = '\n***\n'.join([ ctx.description(), ] + [repo[r].description() for r in internalchanges] + [ oldctx.description(), ]) # If the changesets are from the same author, keep it. if ctx.user() == oldctx.user(): username = ctx.user() else: username = ui.username() newmessage = ui.edit(newmessage, username) n = repo.commit(text=newmessage, user=username, date=max(ctx.date(), oldctx.date()), extra=oldctx.extra()) return repo[n], [ n, ], [oldctx.node(), ctx.node()], [ newnode, ] # xxx
def test_outgoing_output(self): repo, repo_path = self.load_and_fetch('two_heads.svndump') u = self.ui() 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) u.pushbuffer() commands.outgoing(u, self.repo, repourl(repo_path)) actual = u.popbuffer() self.assertTrue( node.hex(revsymbol(self.repo, 'localbranch').node())[:8] in actual) # two hashes for compat with hg < 4.8 self.assertTrue(actual.strip() in ('5:6de15430fa20', '5:76670ad282fd')) hg.update(self.repo, revsymbol(self.repo, 'default')) u.pushbuffer() commands.outgoing(u, self.repo, repourl(repo_path)) actual = u.popbuffer() self.assertEqual(actual, '')