Commit b18c555b authored by Georges Racinet's avatar Georges Racinet 🦑
Browse files

Merged stable branch into default branch

......@@ -466,8 +466,12 @@
def FindCommits(self, request: FindCommitsRequest,
context) -> FindCommitsResponse:
if request.limit == 0:
return
repo = self.load_repo(request.repository, context)
pats = request.paths
# XXX: raise error if one of the path given is an empty string
if pats:
pats = list(map(lambda p: repo.root + b'/' + p, pats))
......@@ -469,6 +473,7 @@
repo = self.load_repo(request.repository, context)
pats = request.paths
# XXX: raise error if one of the path given is an empty string
if pats:
pats = list(map(lambda p: repo.root + b'/' + p, pats))
opts = parse_find_commits_request_opts(request, repo)
......@@ -474,6 +479,7 @@
opts = parse_find_commits_request_opts(request, repo)
if request.revision and not opts[b'rev'][0]:
logger.debug(
"FindCommits revision %r could not be found",
request.revision)
return FindCommitsResponse()
......@@ -475,8 +481,9 @@
if request.revision and not opts[b'rev'][0]:
logger.debug(
"FindCommits revision %r could not be found",
request.revision)
return FindCommitsResponse()
if util.versiontuple(n=2) <= (5, 5): # hg<=5.5
if request.follow and opts.get(b'rev'):
# Mercurial 5.5: 'follow' option of `hg log` doesn't work
......@@ -487,10 +494,11 @@
else: # hg>5.5
walk_opts = logcmdutil.parseopts(repo.ui, pats, opts)
revs, _ = logcmdutil.getrevs(repo, walk_opts)
offset = request.offset
if offset > 0:
revs = revs.slice(offset, len(revs))
if request.offset > 0:
revs = revs.slice(request.offset, len(revs))
if request.order == FindCommitsRequest.TOPO:
revs = repo.revs(b"sort(%ld, topo)", revs)
if request.all:
revs = repo.revs(b"reverse(%ld)", revs)
......@@ -493,7 +501,8 @@
if request.order == FindCommitsRequest.TOPO:
revs = repo.revs(b"sort(%ld, topo)", revs)
if request.all:
revs = repo.revs(b"reverse(%ld)", revs)
for chunk in chunked(revs):
yield FindCommitsResponse(
commits=(message.commit(repo[rev]) for rev in chunk))
......@@ -708,8 +717,9 @@
opts = {
b'follow': request.follow,
b'no_merges': request.skip_merges,
b'limit': request.limit + request.offset,
}
# TODO: implement 'request.first_parent' option
# khanchi97: found that its counterpart follow-first in "hg log" is
# deprecated and give wrong results with other options like revision,
# all, etc.
......@@ -711,10 +721,8 @@
}
# TODO: implement 'request.first_parent' option
# khanchi97: found that its counterpart follow-first in "hg log" is
# deprecated and give wrong results with other options like revision,
# all, etc.
if request.limit:
opts[b'limit'] = request.limit
if request.author:
opts[b'user'] = [request.author]
after = request.after.ToSeconds()
......@@ -786,9 +794,7 @@
left = ctx_start.rev()
right = ctx_end.rev()
branchpoint = repo.revs(b"ancestor(%d, %d)" % (left, right)).first()
revset = b"(%d::%d | %d::%d) - %d" % (
branchpoint, left, branchpoint, right, branchpoint
)
revset = b"only(%d + %d, %d)" % (left, right, branchpoint)
# sort them in descending order
revset = b"sort(%s, -rev)" % revset
return revset
......
......@@ -216,9 +216,9 @@
# o 0 creates 'foo'
#
def do_rpc(**opts):
request = FindCommitsRequest(repository=grpc_repo, **opts)
def do_rpc(limit=10, **opts):
request = FindCommitsRequest(repository=grpc_repo, limit=limit, **opts)
resp = grpc_stub.FindCommits(request)
return [pycompat.sysbytes(commit.id)
for chunk in resp for commit in chunk.commits]
ctx0 = wrapper.write_commit('foo')
......@@ -221,8 +221,8 @@
resp = grpc_stub.FindCommits(request)
return [pycompat.sysbytes(commit.id)
for chunk in resp for commit in chunk.commits]
ctx0 = wrapper.write_commit('foo')
ctx1 = wrapper.write_commit('foo', parent=ctx0)
ctx1 = wrapper.write_commit('foo')
wrapper.update(0)
wrapper.command(b'mv', wrapper.repo.root + b'/foo',
wrapper.repo.root + b'/zoo')
......@@ -226,8 +226,7 @@
wrapper.update(0)
wrapper.command(b'mv', wrapper.repo.root + b'/foo',
wrapper.repo.root + b'/zoo')
wrapper.command(b'ci', message=b"rename foo to zoo")
ctx2 = wrapper.repo[b'.']
ctx2 = wrapper.commit([b'foo', b'zoo'], message=b"rename foo to zoo")
# commits with different date/time, to test with date filter later
timestamp = int(time.time())
ctx3 = wrapper.write_commit('animals', branch='stable', parent=ctx0,
......@@ -279,7 +278,7 @@
# with order
ctx5 = wrapper.write_commit('foo', parent=ctx1)
sha5 = ctx5.hex()
assert do_rpc(all=True, order='TOPO') == [
assert do_rpc(all=True, order=FindCommitsRequest.Order.TOPO) == [
sha0, sha2, sha3, sha4, sha1, sha5]
......
......@@ -7,4 +7,5 @@
import grpc
import pytest
import re
import time
from hgitaly.stub.commit_pb2 import (
......@@ -10,6 +11,7 @@
from hgitaly.stub.commit_pb2 import (
FindCommitsRequest,
ListFilesRequest,
ListLastCommitsForTreeRequest,
RawBlameRequest,
)
from hgitaly.stub.commit_pb2_grpc import CommitServiceStub
......@@ -11,8 +13,10 @@
ListFilesRequest,
ListLastCommitsForTreeRequest,
RawBlameRequest,
)
from hgitaly.stub.commit_pb2_grpc import CommitServiceStub
from google.protobuf.timestamp_pb2 import Timestamp
from mercurial import pycompat
from . import skip_comparison_tests
if skip_comparison_tests(): # pragma no cover
......@@ -250,3 +254,164 @@
for rev in [ctx0.hex(), ctx1.hex(), ctx2.hex(), ctx3.hex(),
not_exists, b'branch/default', b'branch/other']:
assert do_rpc('hg', rev) == do_rpc('git', rev)
def test_compare_find_commits(gitaly_comparison):
fixture = gitaly_comparison
repo_message = fixture.gitaly_repo
git_repo = fixture.git_repo
wrapper = fixture.hg_repo_wrapper
# set_default_gitlab_branch(wrapper.repo, b'branch/default')
# prepare repo as:
#
# @ 4 (branch/default) merge with stable
# |\
# | o 3 creates 'animal' (branch/stable)
# | |
# o | 2 rename 'foo' to 'zoo' (user: testuser)
# |/
# | 1 changes 'foo' (topic: sampletop)
# |/
# o 0 creates 'foo'
#
ctx0 = wrapper.commit_file('foo')
git_shas = {
ctx0.hex(): git_repo.branches()[b'branch/default']['sha'],
}
ctx1 = wrapper.commit_file('foo', topic='sampletop')
git_shas[ctx1.hex()] = (
git_repo.branches()[b'topic/default/sampletop']['sha']
)
wrapper.update(ctx0.rev())
wrapper.command(b'mv', wrapper.repo.root + b'/foo',
wrapper.repo.root + b'/zoo')
ctx2 = wrapper.commit([b'foo', b'zoo'], message=b"rename foo to zoo")
git_shas[ctx2.hex()] = git_repo.branches()[b'branch/default']['sha']
# commits with different date/time, to test with 'date' filter
ts = int(time.time())
ctx3 = wrapper.write_commit('animals', branch='stable', parent=ctx0,
utc_timestamp=ts+10, user='testuser')
git_shas[ctx3.hex()] = git_repo.branches()[b'branch/stable']['sha']
wrapper.update(2)
ctx4 = wrapper.merge_commit(ctx3, message=b'merge with stable',
utc_timestamp=ts+20)
git_shas[ctx4.hex()] = git_repo.branches()[b'branch/default']['sha']
commit_stubs = dict(git=CommitServiceStub(fixture.gitaly_channel),
hg=CommitServiceStub(fixture.hgitaly_channel))
def convert(sha, vcs):
"""Convert an Hg sha to Git, if apply"""
sha = pycompat.sysbytes(sha)
if vcs == 'git':
return sha
return git_shas.get(sha)
def do_rpc(vcs, return_sorted=False, limit=10, **opts):
request = FindCommitsRequest(repository=repo_message,
limit=limit,
**opts)
resp = commit_stubs[vcs].FindCommits(request)
final = [
convert(commit.id, vcs)
for chunk in resp for commit in chunk.commits
]
if return_sorted:
# for the special cases where, we have two commits diverging
# and Git order the commits arbitrarily
# for e.g.
#
# B
# | C Here, if selecting from bottom to top, order
# | / can be: (A, B, C) or (A, C, B)
# A
#
return sorted(final)
return final
# when `revision` is provided as <revspec>
all_revs = [ctx0.hex(), ctx1.hex(), ctx2.hex(), ctx3.hex(), ctx4.hex()]
for range_str in (b'..', b'...'):
for r1 in all_revs:
for r2 in all_revs:
revision = r1 + range_str + r2
git_revision = git_shas[r1] + range_str + git_shas[r2]
assert (
do_rpc('hg', revision=revision, return_sorted=True)
==
do_rpc('git', revision=git_revision, return_sorted=True)
)
# when `revision` is provided as a ref to a single commit
refs = [b'', ctx0.hex(), b'topic/default/sampletop', ctx2.hex(),
b'branch/stable', b'branch/default']
for ref in refs:
git_ref = git_shas[ref] if len(ref) == 40 else ref
assert do_rpc('hg', revision=ref) == do_rpc('git', revision=git_ref)
# with `path` and `follow` options
test_paths = [
# Note: we are not including [b'foo'] here, because of a special case:
# in a rename-cset (foo -> zoo), Git consider the cset but Hg doesn't,
# as 'foo' is not present in rename-cset.
[b'zoo'],
[b'foo', b'zoo'],
]
for follow in [True, False]:
for paths in test_paths:
if len(paths) > 1:
# In Git, 'follow' doesn't work with multiple paths
follow = False
assert (
do_rpc('hg', paths=paths, follow=follow)
==
do_rpc('git', paths=paths, follow=follow)
)
# with `all` option
assert (
do_rpc('hg', all=True, return_sorted=True)
==
do_rpc('git', all=True, return_sorted=True)
)
# with `author` option
assert (
do_rpc('hg', author=b'testuser') == do_rpc('git', author=b'testuser')
)
# with `skip_merges` option
assert (
do_rpc('hg', skip_merges=True) == do_rpc('git', skip_merges=True)
)
# with `limit` and `offset` options
for limit in range(0, 5):
for offset in range(0, 5):
assert (
do_rpc('hg', offset=offset, limit=limit)
==
do_rpc('git', offset=offset, limit=limit)
)
# with `order` option
assert (
do_rpc('hg', order=FindCommitsRequest.Order.TOPO)
==
do_rpc('git', order=FindCommitsRequest.Order.TOPO)
)
# with `after` and `before` options for dates
date1, date2 = Timestamp(), Timestamp()
date1.FromSeconds(ts+10)
date2.FromSeconds(ts+20)
for date in [date1, date2]:
assert do_rpc('hg', after=date) == do_rpc('git', after=date)
assert do_rpc('hg', before=date) == do_rpc('git', before=date)
assert (
do_rpc('hg', before=date, after=date)
==
do_rpc('git', before=date, after=date)
)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment