Skip to content

Commit b1595c2

Browse files
committed
add the ability to strip outgoing changesets for Mercurial repositories
fixes oracle#4602
1 parent 737b69f commit b1595c2

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

tools/src/main/python/opengrok_tools/scm/mercurial.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,37 @@ def incoming_check(self):
129129
return True
130130
else:
131131
return False
132+
133+
def strip_outgoing(self):
134+
"""
135+
Check for outgoing changes and if found, strip them.
136+
:return: True if there were any changes stripped, False otherwise.
137+
"""
138+
branch = self.get_branch()
139+
if branch is None:
140+
return False
141+
status, out = self._run_command([self.command, 'out', '-q', '-b', branch,
142+
'--template={rev}\\n'])
143+
if status == 1:
144+
return False
145+
146+
lines = list(filter(None, out.split('\n')))
147+
if len(lines) == 0:
148+
return False
149+
150+
# The first revision is the oldest outgoing revision.
151+
self.logger.debug("Found outgoing changesets in repository {}: {}".
152+
format(self, lines))
153+
cset = lines[0]
154+
if len(cset) > 0:
155+
self.logger.debug("Resetting the repository {} to parent of changeset '{}'".
156+
format(self, cset))
157+
status, out = self._run_command([self.command, '--config', 'extensions.strip=',
158+
'strip', cset])
159+
if status != 0:
160+
raise RepositoryException("failed to reset {} to parent of changeset '{}': {}".
161+
format(self, cset, out))
162+
else:
163+
return True
164+
165+
return False
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env python3
2+
3+
#
4+
# CDDL HEADER START
5+
#
6+
# The contents of this file are subject to the terms of the
7+
# Common Development and Distribution License (the "License").
8+
# You may not use this file except in compliance with the License.
9+
#
10+
# See LICENSE.txt included in this distribution for the specific
11+
# language governing permissions and limitations under the License.
12+
#
13+
# When distributing Covered Code, include this CDDL HEADER in each
14+
# file and include the License file at LICENSE.txt.
15+
# If applicable, add the following below this CDDL HEADER, with the
16+
# fields enclosed by brackets "[]" replaced with your own identifying
17+
# information: Portions Copyright [yyyy] [name of copyright owner]
18+
#
19+
# CDDL HEADER END
20+
#
21+
22+
#
23+
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
24+
#
25+
26+
import os
27+
import shutil
28+
import tempfile
29+
import time
30+
31+
import pytest
32+
from mockito import mock
33+
from opengrok_tools.scm.mercurial import MercurialRepository
34+
from opengrok_tools.utils.command import Command
35+
36+
37+
def add_commit_file(file_path, repo_path, comment):
38+
"""
39+
:param file_path: path to the file to be created
40+
:param repo_path: Mercurial repository path
41+
:param comment: content and commit comment
42+
"""
43+
with open(file_path, "w") as fp:
44+
fp.write(comment)
45+
assert os.path.exists(file_path)
46+
47+
cmd = Command(["hg", "add", file_path],
48+
work_dir=repo_path)
49+
cmd.execute()
50+
assert cmd.getretcode() == 0
51+
52+
cmd = Command(["hg", "commit", "-m", comment],
53+
work_dir=repo_path)
54+
cmd.execute()
55+
assert cmd.getretcode() == 0
56+
57+
58+
@pytest.mark.skipif(shutil.which("hg") is None, reason="need hg")
59+
def test_strip_outgoing():
60+
with tempfile.TemporaryDirectory() as test_root:
61+
# Initialize Mercurial repository.
62+
repo_parent_path = os.path.join(test_root, "parent")
63+
os.mkdir(repo_parent_path)
64+
cmd = Command(["hg", "init"], work_dir=repo_parent_path)
65+
cmd.execute()
66+
assert cmd.getretcode() == 0
67+
68+
#
69+
# Create a file in the parent repository. This is done so that
70+
# after the strip is done in the cloned repository, the branch
71+
# is still known. Normally this would be the case.
72+
#
73+
file_path = os.path.join(repo_parent_path, "foo.txt")
74+
add_commit_file(file_path, repo_parent_path, "parent")
75+
76+
# Clone the repository and create couple of new changesets.
77+
repo_clone_path = os.path.join(test_root, "clone")
78+
cmd = Command(["hg", "clone", repo_parent_path, repo_clone_path],
79+
work_dir=test_root)
80+
cmd.execute()
81+
assert cmd.getretcode() == 0
82+
83+
file_path = os.path.join(repo_clone_path, "foo.txt")
84+
add_commit_file(file_path, repo_clone_path, "first")
85+
86+
with open(file_path, "a") as fp:
87+
fp.write("bar")
88+
cmd = Command(["hg", "commit", "-m", "second"],
89+
work_dir=repo_clone_path)
90+
cmd.execute()
91+
assert cmd.getretcode() == 0
92+
93+
# time.sleep(60)
94+
95+
# Strip the changesets.
96+
repository = MercurialRepository("hgout", mock(), repo_clone_path, 'test-1',
97+
None, None, None, None)
98+
assert repository.strip_outgoing()
99+
assert not repository.strip_outgoing()
100+
101+
102+
test_strip_outgoing()

0 commit comments

Comments
 (0)