fix(repos create): default new repos to main, not master
`git init` without `-b` inherits the ambient `init.defaultBranch` config, which is `master` unless the host has configured otherwise, so `pkgmgr repos create` produced master-based repositories. On top of that, the push fallback renamed an already-correct `main` branch back to `master` whenever the initial push failed (missing remote, auth error). `init()` now requires an explicit `initial_branch` and runs `git init -b <branch>`; the bootstrapper passes `main` and no longer falls back to `master` on push failure. `resolve_base_branch()` keeps its main -> master fallback, since it reads existing repositories that may legitimately use master. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,10 +10,12 @@ from pkgmgr.core.git.commands import (
|
|||||||
push_upstream,
|
push_upstream,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DEFAULT_BRANCH = "main"
|
||||||
|
|
||||||
|
|
||||||
class GitBootstrapper:
|
class GitBootstrapper:
|
||||||
def init_repo(self, repo_dir: str, preview: bool) -> None:
|
def init_repo(self, repo_dir: str, preview: bool) -> None:
|
||||||
init(cwd=repo_dir, preview=preview)
|
init(initial_branch=DEFAULT_BRANCH, cwd=repo_dir, preview=preview)
|
||||||
add_all(cwd=repo_dir, preview=preview)
|
add_all(cwd=repo_dir, preview=preview)
|
||||||
try:
|
try:
|
||||||
commit("Initial commit", cwd=repo_dir, preview=preview)
|
commit("Initial commit", cwd=repo_dir, preview=preview)
|
||||||
@@ -21,15 +23,8 @@ class GitBootstrapper:
|
|||||||
print(f"[WARN] Initial commit failed (continuing): {exc}")
|
print(f"[WARN] Initial commit failed (continuing): {exc}")
|
||||||
|
|
||||||
def push_default_branch(self, repo_dir: str, preview: bool) -> None:
|
def push_default_branch(self, repo_dir: str, preview: bool) -> None:
|
||||||
|
branch_move(DEFAULT_BRANCH, cwd=repo_dir, preview=preview)
|
||||||
try:
|
try:
|
||||||
branch_move("main", cwd=repo_dir, preview=preview)
|
push_upstream("origin", DEFAULT_BRANCH, cwd=repo_dir, preview=preview)
|
||||||
push_upstream("origin", "main", cwd=repo_dir, preview=preview)
|
|
||||||
return
|
|
||||||
except GitPushUpstreamError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
branch_move("master", cwd=repo_dir, preview=preview)
|
|
||||||
push_upstream("origin", "master", cwd=repo_dir, preview=preview)
|
|
||||||
except GitPushUpstreamError as exc:
|
except GitPushUpstreamError as exc:
|
||||||
print(f"[WARN] Push failed: {exc}")
|
print(f"[WARN] Push failed: {exc}")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from ..errors import GitRunError, GitCommandError
|
from ..errors import GitCommandError, GitRunError
|
||||||
from ..run import run
|
from ..run import run
|
||||||
|
|
||||||
|
|
||||||
@@ -8,14 +8,17 @@ class GitInitError(GitCommandError):
|
|||||||
"""Raised when `git init` fails."""
|
"""Raised when `git init` fails."""
|
||||||
|
|
||||||
|
|
||||||
def init(*, cwd: str = ".", preview: bool = False) -> None:
|
def init(*, initial_branch: str, cwd: str = ".", preview: bool = False) -> None:
|
||||||
"""
|
"""
|
||||||
Initialize a repository.
|
Initialize a repository with an explicit initial branch.
|
||||||
|
|
||||||
Equivalent to:
|
Equivalent to:
|
||||||
git init
|
git init -b <initial_branch>
|
||||||
|
|
||||||
|
initial_branch: required, so the branch never depends on the ambient
|
||||||
|
`init.defaultBranch` git config (which is `master` unless configured).
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
run(["init"], cwd=cwd, preview=preview)
|
run(["init", "-b", initial_branch], cwd=cwd, preview=preview)
|
||||||
except GitRunError as exc:
|
except GitRunError as exc:
|
||||||
raise GitInitError("Failed to initialize git repository.", cwd=cwd) from exc
|
raise GitInitError("Failed to initialize git repository.", cwd=cwd) from exc
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from pkgmgr.actions.repository.create.git_bootstrap import GitBootstrapper
|
||||||
|
from pkgmgr.core.git.commands import GitPushUpstreamError
|
||||||
|
|
||||||
|
|
||||||
|
class TestGitBootstrapperDefaultBranch(unittest.TestCase):
|
||||||
|
def test_init_repo_uses_main_as_initial_branch(self):
|
||||||
|
with (
|
||||||
|
patch("pkgmgr.actions.repository.create.git_bootstrap.init") as init,
|
||||||
|
patch("pkgmgr.actions.repository.create.git_bootstrap.add_all"),
|
||||||
|
patch("pkgmgr.actions.repository.create.git_bootstrap.commit"),
|
||||||
|
):
|
||||||
|
GitBootstrapper().init_repo("/repo", preview=False)
|
||||||
|
|
||||||
|
init.assert_called_once_with(
|
||||||
|
initial_branch="main", cwd="/repo", preview=False
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_push_default_branch_pushes_main(self):
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"pkgmgr.actions.repository.create.git_bootstrap.branch_move"
|
||||||
|
) as branch_move,
|
||||||
|
patch(
|
||||||
|
"pkgmgr.actions.repository.create.git_bootstrap.push_upstream"
|
||||||
|
) as push_upstream,
|
||||||
|
):
|
||||||
|
GitBootstrapper().push_default_branch("/repo", preview=False)
|
||||||
|
|
||||||
|
branch_move.assert_called_once_with("main", cwd="/repo", preview=False)
|
||||||
|
push_upstream.assert_called_once_with(
|
||||||
|
"origin", "main", cwd="/repo", preview=False
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_failed_push_does_not_fall_back_to_master(self):
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"pkgmgr.actions.repository.create.git_bootstrap.branch_move"
|
||||||
|
) as branch_move,
|
||||||
|
patch(
|
||||||
|
"pkgmgr.actions.repository.create.git_bootstrap.push_upstream",
|
||||||
|
side_effect=GitPushUpstreamError("boom"),
|
||||||
|
) as push_upstream,
|
||||||
|
):
|
||||||
|
GitBootstrapper().push_default_branch("/repo", preview=False)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
[call.args[0] for call in branch_move.call_args_list], ["main"]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
[call.args[1] for call in push_upstream.call_args_list], ["main"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user