Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 22e0a10

Browse files
committed
Handle already merged tickets correctly when merging dependencies in the dev scripts.
1 parent 37c8a8c commit 22e0a10

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

src/sage/dev/sagedev.py

+74
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
r'^(?!.*/\.)(?!.*\.\.)(?!/)(?!.*//)(?!.*@\{)(?!.*\\)'
4545
r'[^\040\177 ~^:?*[]+(?<!\.lock)(?<!/)(?<!\.)$')
4646

47+
GIT_COMMIT_REGEX = re.compile(r'[0-9a-f]{5,40}')
48+
4749
# the name of the branch which holds the vanilla clone of sage
4850
MASTER_BRANCH = "master"
4951
USER_BRANCH = re.compile(r"^u/([^/]+)/")
@@ -3157,6 +3159,26 @@ def merge(self, ticket_or_branch=MASTER_BRANCH, pull=None, create_dependency=Non
31573159
Cannot merge because working directory is not in a clean state.
31583160
<BLANKLINE>
31593161
# (use "sage --dev commit" to commit your changes)
3162+
3163+
Merging a ticket whose branch field points to a commit checks whether
3164+
the commit is present in the current branch::
3165+
3166+
sage: alice.trac.set_attributes(1, branch='12345678')
3167+
sage: alice._UI.append("discard")
3168+
sage: alice.merge(ticket_or_branch=1, pull=True)
3169+
The following files in your working directory contain uncommitted changes:
3170+
<BLANKLINE>
3171+
alice2
3172+
<BLANKLINE>
3173+
Discard changes? [discard/Cancel/stash] discard
3174+
# It seems that the branch for #1 has already been merged in the latest version of sage. The branch field on #1 points to the commit "12345678".
3175+
Failed to determine whether commit "12345678" is present in the current branch "ticket/2". Is your "master" branch up to date?
3176+
sage: sha = alice.git.show_ref('master',hash=True)[:8]
3177+
sage: alice.trac.set_attributes(1, branch=sha)
3178+
sage: alice.merge(ticket_or_branch=1, pull=True)
3179+
# It seems that the branch for #1 has already been merged in the latest version of sage. The branch field on #1 points to the commit "...".
3180+
Your branch "ticket/2" already contains commit "...". Nothing to merge.
3181+
31603182
"""
31613183
try:
31623184
self.reset_to_clean_state()
@@ -3238,9 +3260,34 @@ def merge(self, ticket_or_branch=MASTER_BRANCH, pull=None, create_dependency=Non
32383260
if pull:
32393261
assert remote_branch
32403262
if not self._is_remote_branch_name(remote_branch, exists=True):
3263+
if ticket and self._is_commit_name(remote_branch):
3264+
commit = remote_branch
3265+
self._UI.info('It seems that the branch for #{0} has already been merged in the latest version of sage. The branch field on #{0} points to the commit "{1}".', ticket, commit)
3266+
from git_error import GitError
3267+
try:
3268+
branches = self.git.branch(contains=commit)
3269+
except GitError as e:
3270+
self._UI.error('Failed to determine whether commit "{0}" is present in the current branch "{1}". Is your "{2}" branch up to date?', commit, current_branch, MASTER_BRANCH)
3271+
raise OperationCancelledError("unknown commit")
3272+
present_in_master = False
3273+
for present_in_branch in branches.split():
3274+
present_in_branch = present_in_branch.split()[-1]
3275+
if current_branch == present_in_branch:
3276+
self._UI.show('Your branch "{0}" already contains commit "{1}". Nothing to merge.', current_branch, commit)
3277+
return
3278+
if MASTER_BRANCH == present_in_branch:
3279+
present_in_master = True
3280+
self._UI.show('Your branch "{0}" does not contain commit "{1}". Merging of remote commits is not implemented. You need to merge manually.', current_branch, commit)
3281+
if present_in_master:
3282+
self._UI.info('Merge "{0}" into your branch "{1}" with "{2}".', MASTER_BRANCH, current_branch, self._format_command("merge"))
3283+
else:
3284+
self._UI.info('Your branch "{0}" seems to be out of date. Pull the latest changes to "{0}" with "{1}" and "{2}". Then come back to this branch and merge "{0}" with "{3}" and "{4}".', MASTER_BRANCH, self._format_command("checkout", branch=MASTER_BRANCH), self._format_command("pull"), self._format_command("checkout", branch=current_branch), self._format_command("merge"))
3285+
raise OperationCancelledError("Remote commit merge not implemented.")
3286+
32413287
self._UI.error('Can not merge remote branch "{0}". It does not exist.',
32423288
remote_branch)
32433289
raise OperationCancelledError("no such branch")
3290+
32443291
self._UI.show('Merging the remote branch "{0}" into the local branch "{1}".',
32453292
remote_branch, current_branch)
32463293
self.git.super_silent.fetch(self.git._repository_anonymous, remote_branch)
@@ -4357,6 +4404,33 @@ def _is_local_branch_name(self, name, exists=any):
43574404
else:
43584405
raise ValueError("exists")
43594406

4407+
def _is_commit_name(self, name):
4408+
r"""
4409+
Return whether ``name`` is a valid name for a commit.
4410+
4411+
INPUT:
4412+
4413+
- ``name`` -- a string
4414+
4415+
TESTS::
4416+
4417+
sage: from sage.dev.test.sagedev import single_user_setup
4418+
sage: dev, config, UI, server = single_user_setup()
4419+
sage: dev = dev._sagedev
4420+
4421+
sage: dev._is_commit_name('')
4422+
False
4423+
sage: dev._is_commit_name('ticket/1')
4424+
False
4425+
sage: dev._is_commit_name('12345a78')
4426+
True
4427+
4428+
"""
4429+
if not isinstance(name, str):
4430+
raise ValueError("name must be a string")
4431+
4432+
return bool(GIT_COMMIT_REGEX.match(name))
4433+
43604434
def _is_trash_name(self, name, exists=any):
43614435
r"""
43624436
Return whether ``name`` is a valid name for an abandoned branch.

0 commit comments

Comments
 (0)