@@ -21,25 +21,26 @@ news
- pull request notifications send much nicer emails with details about pull
request
fixes
+++++
- fixed migrations of permissions that can lead to inconsistency.
Some users sent feedback that after upgrading from older versions issues
with updating default permissions occurred. RhodeCode detects that now and
resets default user permission to initial state if there is a need for that.
Also forces users to set the default value for new forking permission.
- #535 improved apache wsgi example configuration in docs
- fixes #550 mercurial repositories comparision failed when origin repo had
additional not-common changesets
1.4.0 (**2012-09-03**)
----------------------
news
++++
- new codereview system
- email map, allowing users to have multiple email addresses mapped into
their accounts
- improved git-hook system. Now all actions for git are logged into journal
including pushed revisions, user and IP address
@@ -601,25 +601,25 @@ def differ(org_repo, org_ref, other_repo
common, incoming, rheads = discovery_data
other_repo_peer = localrepo.locallegacypeer(other_repo.local())
# create a bundle (uncompressed if other repo is not local)
if other_repo_peer.capable('getbundle') and incoming:
# disable repo hooks here since it's just bundle !
# patch and reset hooks section of UI config to not run any
# hooks on fetching archives with subrepos
for k, _ in other_repo.ui.configitems('hooks'):
other_repo.ui.setconfig('hooks', k, None)
unbundle = other_repo.getbundle('incoming', common=common,
heads=rheads)
heads=None)
buf = BytesIO()
while True:
chunk = unbundle._stream.read(1024 * 4)
if not chunk:
break
buf.write(chunk)
buf.seek(0)
# replace chunked _stream with data that can do tell() and seek()
unbundle._stream = buf
@@ -5,13 +5,14 @@ Mercurial libs compatibility
from mercurial import archival, merge as hg_merge, patch, ui
from mercurial.commands import clone, nullid, pull
from mercurial.context import memctx, memfilectx
from mercurial.error import RepoError, RepoLookupError, Abort
from mercurial.hgweb.common import get_contact
from mercurial.localrepo import localrepository
from mercurial.match import match
from mercurial.mdiff import diffopts
from mercurial.node import hex
from mercurial.encoding import tolocal
from mercurial import discovery
from mercurial import localrepo
from mercurial import scmutil
\ No newline at end of file
from mercurial.discovery import findcommonoutgoing
@@ -27,25 +27,26 @@ import logging
import binascii
import datetime
from pylons.i18n.translation import _
from rhodecode.model.meta import Session
from rhodecode.lib import helpers as h
from rhodecode.model import BaseModel
from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification
from rhodecode.model.notification import NotificationModel
from rhodecode.lib.utils2 import safe_unicode
from rhodecode.lib.vcs.utils.hgcompat import discovery, localrepo, scmutil
from rhodecode.lib.vcs.utils.hgcompat import discovery, localrepo, scmutil, \
findcommonoutgoing
log = logging.getLogger(__name__)
class PullRequestModel(BaseModel):
cls = PullRequest
def __get_pull_request(self, pull_request):
return self._get_instance(PullRequest, pull_request)
def get_all(self, repo):
@@ -155,25 +156,27 @@ class PullRequestModel(BaseModel):
:type org_ref:
:param other_repo:
:type other_repo:
:param other_ref:
:type other_ref:
:param tmp:
:type tmp:
"""
changesets = []
#case two independent repos
if org_repo != other_repo and incoming:
revs = org_repo._repo.changelog.findmissing(common, rheads)
obj = findcommonoutgoing(org_repo._repo,
localrepo.locallegacypeer(other_repo._repo.local()))
revs = obj.missing
for cs in reversed(map(binascii.hexlify, revs)):
changesets.append(org_repo.get_changeset(cs))
else:
_revset_predicates = {
'branch': 'branch',
'book': 'bookmark',
'tag': 'tag',
'rev': 'id',
}
revs = [
@@ -21,35 +21,35 @@ class TestCompareController(TestControll
))
response.mustcontain('%s@%s -> %s@%s' % (HG_REPO, tag1, HG_REPO, tag2))
## outgoing changesets between tags
response.mustcontain('''<a href="/%s/changeset/17544fbfcd33ffb439e2b728b5d526b1ef30bfcf">r120:17544fbfcd33</a>''' % HG_REPO)
response.mustcontain('''<a href="/%s/changeset/36e0fc9d2808c5022a24f49d6658330383ed8666">r119:36e0fc9d2808</a>''' % HG_REPO)
response.mustcontain('''<a href="/%s/changeset/bb1a3ab98cc45cb934a77dcabf87a5a598b59e97">r118:bb1a3ab98cc4</a>''' % HG_REPO)
response.mustcontain('''<a href="/%s/changeset/41fda979f02fda216374bf8edac4e83f69e7581c">r117:41fda979f02f</a>''' % HG_REPO)
response.mustcontain('''<a href="/%s/changeset/9749bfbfc0d2eba208d7947de266303b67c87cda">r116:9749bfbfc0d2</a>''' % HG_REPO)
response.mustcontain('''<a href="/%s/changeset/70d4cef8a37657ee4cf5aabb3bd9f68879769816">r115:70d4cef8a376</a>''' % HG_REPO)
response.mustcontain('''<a href="/%s/changeset/c5ddebc06eaaba3010c2d66ea6ec9d074eb0f678">r112:c5ddebc06eaa</a>''' % HG_REPO)
## files diff
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--1c5cf9e91c12">docs/api/utils/index.rst</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--e3305437df55">test_and_report.sh</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--c8e92ef85cd1">.hgignore</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--6e08b694d687">.hgtags</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--2c14b00f3393">docs/api/index.rst</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--430ccbc82bdf">vcs/__init__.py</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--9c390eb52cd6">vcs/backends/hg.py</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--ebb592c595c0">vcs/utils/__init__.py</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--7abc741b5052">vcs/utils/annotate.py</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--2ef0ef106c56">vcs/utils/diffs.py</a></div>''' % (HG_REPO, tag1, tag2))
response.mustcontain('''<div class="node"><a href="/%s/compare/tag@%s...tag@%s#C--3150cb87d4b7">vcs/utils/lazy.py</a></div>''' % (HG_REPO, tag1, tag2))
def test_index_branch(self):
self.log_user()
response = self.app.get(url(controller='compare', action='index',
repo_name=HG_REPO,
org_ref_type="branch",
org_ref='default',
other_ref_type="branch",
other_ref='default',
response.mustcontain('%s@default -> %s@default' % (HG_REPO, HG_REPO))
@@ -174,16 +174,120 @@ class TestCompareController(TestControll
other_ref=rev2,
repo=r1_name
try:
response.mustcontain('%s@%s -> %s@%s' % (r2_name, rev1, r1_name, rev2))
response.mustcontain("""<div class="message">commit2</div>""")
response.mustcontain("""<a href="/%s/changeset/%s">r1:%s</a>""" % (r2_name, cs1.raw_id, cs1.short_id))
## files
response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s#C--826e8142e6ba">file1</a>""" % (r2_name, rev1, rev2))
finally:
RepoModel().delete(r1_id)
RepoModel().delete(r2_id)
def test_org_repo_new_commits_after_forking(self):
repo1 = RepoModel().create_repo(repo_name='one', repo_type='hg',
description='diff-test',
owner=TEST_USER_ADMIN_LOGIN)
Session().commit()
r1_id = repo1.repo_id
r1_name = repo1.repo_name
#commit something initially !
cs0 = ScmModel().create_node(
repo=repo1.scm_instance, repo_name=r1_name,
cs=EmptyChangeset(alias='hg'), user=TEST_USER_ADMIN_LOGIN,
author=TEST_USER_ADMIN_LOGIN,
message='commit1',
content='line1',
f_path='file1'
)
self.assertEqual(repo1.scm_instance.revisions, [cs0.raw_id])
#fork the repo1
repo2 = RepoModel().create_repo(repo_name='one-fork', repo_type='hg',
description='compare-test',
clone_uri=repo1.repo_full_path,
owner=TEST_USER_ADMIN_LOGIN, fork_of='one')
self.assertEqual(repo2.scm_instance.revisions, [cs0.raw_id])
r2_id = repo2.repo_id
r2_name = repo2.repo_name
#make 3 new commits in fork
cs1 = ScmModel().create_node(
repo=repo2.scm_instance, repo_name=r2_name,
cs=repo2.scm_instance[-1], user=TEST_USER_ADMIN_LOGIN,
message='commit1-fork',
content='file1-line1-from-fork',
f_path='file1-fork'
cs2 = ScmModel().create_node(
cs=cs1, user=TEST_USER_ADMIN_LOGIN,
message='commit2-fork',
content='file2-line1-from-fork',
f_path='file2-fork'
cs3 = ScmModel().create_node(
cs=cs2, user=TEST_USER_ADMIN_LOGIN,
message='commit3-fork',
content='file3-line1-from-fork',
f_path='file3-fork'
#compare !
rev1 = 'default'
rev2 = 'default'
repo_name=r2_name,
org_ref=rev1,
response.mustcontain("""file1-line1-from-fork""")
response.mustcontain("""file2-line1-from-fork""")
response.mustcontain("""file3-line1-from-fork""")
#add new commit into parent !
message='commit2',
f_path='file2'
Status change: