mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-07-15 21:27:00 +00:00
rebase: Resolve revisionExpr to tracking branch for --onto-manifest
When running `repo rebase -m` (`--onto-manifest`), the command uses the raw `revisionExpr` from the manifest (e.g. `main`) directly as the `--onto` target. This can fail or behave incorrectly if it should reference the local tracking branch (e.g. `refs/remotes/<remote>/main`). Resolve `project.revisionExpr` to its local tracking branch using `project.GetRemote().ToLocal()`. Fall back to using the raw `revisionExpr` value if the resolution fails (raising a `GitError`). Bug: 532028666 Change-Id: I4c1bca1374a5842688be227f6aa2afffcdad5397 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/604941 Reviewed-by: Brian Gan <brgan@google.com> Tested-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Gavin Mak <gavinmak@google.com>
This commit is contained in:
committed by
gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
35bbf701d0
commit
3bb4871c44
+14
-1
@@ -16,7 +16,9 @@ import sys
|
||||
|
||||
from color import Coloring
|
||||
from command import Command
|
||||
from error import GitError
|
||||
from git_command import GitCommand
|
||||
from project import Project
|
||||
from repo_logging import RepoLogger
|
||||
|
||||
|
||||
@@ -30,6 +32,17 @@ class RebaseColoring(Coloring):
|
||||
self.fail = self.printer("fail", fg="red")
|
||||
|
||||
|
||||
def _ResolveOntoManifest(project: Project) -> str:
|
||||
"""Resolve project's revisionExpr to a local tracking branch.
|
||||
|
||||
Falls back to the raw revisionExpr if ToLocal fails or raises GitError.
|
||||
"""
|
||||
try:
|
||||
return project.GetRemote().ToLocal(project.revisionExpr)
|
||||
except GitError:
|
||||
return project.revisionExpr
|
||||
|
||||
|
||||
class Rebase(Command):
|
||||
COMMON = True
|
||||
helpSummary = "Rebase local branches on upstream branch"
|
||||
@@ -162,7 +175,7 @@ branch but need to incorporate new upstream changes "underneath" them.
|
||||
args = common_args[:]
|
||||
if opt.onto_manifest:
|
||||
args.append("--onto")
|
||||
args.append(project.revisionExpr)
|
||||
args.append(_ResolveOntoManifest(project))
|
||||
|
||||
args.append(upbranch.LocalMerge)
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2026 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Unittests for the subcmds/rebase.py module."""
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from error import GitError
|
||||
from subcmds import rebase
|
||||
|
||||
|
||||
def test_resolve_onto_manifest_success() -> None:
|
||||
"""Test _ResolveOntoManifest when ToLocal succeeds."""
|
||||
project = mock.MagicMock()
|
||||
project.revisionExpr = "main"
|
||||
|
||||
remote = mock.MagicMock()
|
||||
remote.ToLocal.return_value = "refs/remotes/goog/main"
|
||||
project.GetRemote.return_value = remote
|
||||
|
||||
res = rebase._ResolveOntoManifest(project)
|
||||
assert res == "refs/remotes/goog/main"
|
||||
project.GetRemote.assert_called_once()
|
||||
remote.ToLocal.assert_called_once_with("main")
|
||||
|
||||
|
||||
def test_resolve_onto_manifest_fallback() -> None:
|
||||
"""Test _ResolveOntoManifest when ToLocal raises GitError."""
|
||||
project = mock.MagicMock()
|
||||
project.revisionExpr = "main"
|
||||
|
||||
remote = mock.MagicMock()
|
||||
remote.ToLocal.side_effect = GitError("Failed to resolve")
|
||||
project.GetRemote.return_value = remote
|
||||
|
||||
res = rebase._ResolveOntoManifest(project)
|
||||
assert res == "main"
|
||||
project.GetRemote.assert_called_once()
|
||||
remote.ToLocal.assert_called_once_with("main")
|
||||
Reference in New Issue
Block a user