#git-branch #git #mercurial #hg #convert

bin+lib hg-git-fast-import

将单个和多个 Mercurial 仓库导入 Git 的工具

20 个稳定版本

1.4.0 2024 年 5 月 10 日
1.3.8 2021 年 5 月 17 日
1.3.7 2020 年 10 月 11 日
1.3.4 2020 年 5 月 29 日
1.2.3 2019 年 7 月 14 日

命令行工具 中排名第 82

Download history 97/week @ 2024-05-04 35/week @ 2024-05-11 6/week @ 2024-05-18 1/week @ 2024-05-25 2/week @ 2024-06-08 1/week @ 2024-06-15 134/week @ 2024-07-27

每月下载量 134

许可协议 Unlicense OR MITGPL-2.0-or-later

81KB
2K SLoC

使用 git fast-import 转换 Mercurial 到 Git,支持多仓库导入

Crates.io Packaging status hg-git-fast-import

双许可协议,根据 MITUNLICENSE

功能

  1. 将单个和多个 Mercurial 仓库导入 Git 仓库。
  2. 将先前导入的 Mercurial 仓库的新修订版本导入 Git 仓库。
  3. 标签。
  4. 已关闭的分支。
  5. 使用 diff 验证最终结果。

安装

使用 cargo

cargo install hg-git-fast-import

从源代码

git clone https://github.com/kilork/hg-git-fast-import.git
cd hg-git-fast-import
cargo install --path .

预构建发布二进制文件

下载最新版本

使用 Snap (*)

sudo snap install hg-git-fast-import

(*) 限制:不允许在严格 snap 包(hg 和 git)中运行子进程,目前不需要请求经典约束,这意味着您只能导出将用 git 处理的脚本。

Get it from the Snap Store

用法

hg-git-fast-import 是一个命令行工具,可以使用 --help 参数访问使用信息

$ hg-git-fast-import --help
hg-git-fast-import 1.4.0

USAGE:
    hg-git-fast-import <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    build-marks    Rebuilds saved state of repo
    help           Prints this message or the help of the given subcommand(s)
    multi          Exports multiple Mercurial repositories to single Git repo in fast-import compatible format
    single         Exports single Mercurial repository to Git fast-import compatible format

导入单个仓库

$ hg-git-fast-import single --help
hg-git-fast-import-single 1.4.0
Exports single Mercurial repository to Git fast-import compatible format

USAGE:
    hg-git-fast-import single [FLAGS] [OPTIONS] <hg-repo> [git-repo]

FLAGS:
        --clean                       Recreate Git repo before import if it exists
        --cron                        Produce minimal output only if new revisions loaded or error happened
        --fix-wrong-branch-names      Fix wrong Mercurial branch names (not compatible with git ref format)
    -h, --help                        Prints help information
        --no-clean-closed-branches    Do not clean closed Mercurial branches
        --source-pull                 Pull source Mercurial repository before import
        --target-pull                 Pull target Git repository before push
        --target-push                 Push target Git repository after successful import
    -V, --version                     Prints version information
        --verify                      Compares resulting Git repo with Mercurial

OPTIONS:
    -a, --authors <authors>                            Authors remapping in toml format
    -c, --config <config>                              Repository configuration in toml format
        --default-branch <default-branch>              Default branch to use
        --git-active-branches <git-active-branches>    Git maximum number of branches to maintain active at once
        --limit-high <limit-high>                      Limit high revision to import
        --log <log>
            Log file. If present - additional log info would be printed to this file


ARGS:
    <hg-repo>     The Mercurial repo for import to git
    <git-repo>    The Git repo to import to. Creates repo if it does not exist. Otherwise saved state must exist

导入多个仓库

$ hg-git-fast-import multi --help
hg-git-fast-import-multi 1.4.0
Exports multiple Mercurial repositories to single Git repo in fast-import compatible format

USAGE:
    hg-git-fast-import multi [FLAGS] [OPTIONS] --config <config>

FLAGS:
        --clean                       Recreate Git repo before import if it exists
        --cron                        Produce minimal output only if new revisions loaded or error happened
        --fix-wrong-branch-names      Fix wrong Mercurial branch names (not compatible with git ref format)
    -h, --help                        Prints help information
        --no-clean-closed-branches    Do not clean closed Mercurial branches
        --source-pull                 Pull source Mercurial repository before import
        --target-pull                 Pull target Git repository before push
        --target-push                 Push target Git repository after successful import
    -V, --version                     Prints version information
        --verify                      Compares resulting Git repo with Mercurial

OPTIONS:
    -a, --authors <authors>                            Authors remapping in toml format
    -c, --config <config>                              Repositories configuration in toml format
        --git-active-branches <git-active-branches>    Git maximum number of branches to maintain active at once
        --log <log>
            Log file. If present - additional log info would be printed to this file


重建仓库的保存状态

$ hg-git-fast-import build-marks --help
hg-git-fast-import-build-marks 1.4.0
Rebuilds saved state of repo

USAGE:
    hg-git-fast-import build-marks [FLAGS] [OPTIONS] <hg-repo> <git-repo>

FLAGS:
    -h, --help         Prints help information
        --no-backup    Do not backup old marks
    -V, --version      Prints version information

OPTIONS:
    -a, --authors <authors>    Authors remapping in toml format
    -o, --offset <offset>      Offset for git fast-import marks in Git repository. Optional, default is 0

ARGS:
    <hg-repo>     The Mercurial repo which was imported to git
    <git-repo>    The Git repo to save state to. Existing saved state would be updated with actual state

配置语法

对于更复杂的情况,可以提供 toml 格式的配置。

单模式配置示例

# Allows to start import in of hanged heads in repository
# (currently has no effect, default value is true). Optional.
allow_unnamed_heads = true
# Offset for git fast-import marks in Git repository. Optional, default is 0.
offset = 1000
# Path prefix in target repository. If path_prefix = 'test',
# all files will be under test folder in target Git repository.
# Optional.
path_prefix = 'prefix1'
# Tag prefix in target repository. Optional.
tag_prefix = 'prefix2-'
# Branch prefix in target repository. Optional.
branch_prefix = 'prefix3-'
# By default master branch is not prefixed by branch_prefix.
# This behavior can be changed by specifying this as true.
# Optional.
prefix_default_branch = false

# Mapping between authors in Mercurial and authors in Git.
# Required mainly because of Git asks for particular format "Somename <email@address>".
# But also can be used to fix typos and etc.
[authors]
'aaa 1' = 'Bbb <[email protected]>'
aaa = 'Bbb <[email protected]>'
ccc = 'Qqq <[email protected]>'
'My <[email protected]>' = 'My <[email protected]>'

# Mapping between branches in Mercurial and branches in Git.
# Required mainly because Git does not allow some characters,
# which allowed in Mercurial, for example - spaces.
# Branches taken from mapping will not have branch_prefix,
# so it must be added to mapped values.
[branches]
'branch in hg' = 'branch-in-git'
'anotherhg' = 'othergit'

参见 single.toml

使用 authorsbranches 子部分可以在导入期间重命名作者和分支。偏移在 Git 仓库中创建标记。如果计划将导入的仓库中的所有标记文件一起分析,则可能很有用。allow_unnamed_heads 允许在仓库中出现悬停头部的情况下开始导入,目前此功能没有效果。

多模式配置示例

# Path to target git repository.
path_git = "000_git"

# This is subsection with list of repositories to be aggregated into single repo.
# Each subsection start like this (see toml format for arrays).
[[repositories]]
# Mercurial repository path.
path_hg = "001_hg"
# Child Git repository path.
path_git = "001_git"

# Child repository configuration for 001_hg/001_git.
# Fields are the same as on root level in single mode configuration.
[repositories.config]
allow_unnamed_heads = true
offset = 1000
path_prefix = 'prefix1'
tag_prefix = 'prefix2-'
branch_prefix = 'prefix3-'
prefix_default_branch = true
default_branch = 'main'

# Same as authors section in single mode, but for this child repository.
[repositories.config.authors]
'aaa' = 'Bbb <[email protected]>'

# Same as branches section in single mode, but for this child repository.
[repositories.config.branches]
'branch1' = 'branch2'

# This sections specify to which branches would be merged migrated
# branches from this child Git repository.
[repositories.merged_branches]
branch_in_git = 'branch2'
# Explanation: in this case branch_in_git will be a branch in 000_git repo
# and it will contain branch2 merged from remote child repository.

# This is second child repository.
[[repositories]]
# Here we can also specify alias, this field used to add reference in target 000_git repository.
# Otherwise path_prefix is used from config section.
alias = "another_002"
path_hg = "002_hg"
path_git = "002_git"

[repositories.merged_branches]
branch_in_git = 'branch_in_hg'
# Actually this branch_in_hg is from second migrated Git repository.
# Interesting to note - both child repository branches are merged
# into single branch_in_git branch in target 000_git repository.

每个子仓库将根据配置导入相应的 path_git,然后顶级 path_git 中的单个仓库将作为 remote 引用子仓库。远程名称采用 aliaspath_prefix

参见 multi.toml

作者列表配置示例

'aaa 1' = 'Bbb <[email protected]>'
aaa = 'Bbb <[email protected]>'
ccc = 'Qqq <[email protected]>'
'My <[email protected]>' = 'My <[email protected]>'

参见 authors.toml

要求

  • Rust 1.78 或更高版本(2018 版本)
  • Git 2.19(可选,如果您使用不带仓库创建的 single 模式)
  • Diff 2.8(可选,如果您不使用 --verify
  • Mercurial 4.8(可选,如果您不需要版本修订的 delta 加载)
  • Python 2.7(可选,用于 Mercurial

Docker 支持

设置所有依赖可能是一项棘手的任务 - 可以使用 docker 来运行 hg-git-fast-import

Docker 安装

git clone https://github.com/kilork/hg-git-fast-import.git
cd hg-git-fast-import/docker
./build.sh

Docker 运行

docker run -it --rm kilork/hg-git-fast-import hg-git-fast-import --help

要使用 docker 将当前目录与仓库一起挂载并运行 hg-git-fast-import 命令,可以使用包装器 hg-git-fast-import/docker/run.sh

cd hg-git-fast-import/docker
./run.sh

默认情况下,这将把当前目录挂载到 docker 容器内的 /repositories 目录。这可以通过使用环境变量来覆盖。

HG_GIT_FAST_IMPORT_VOLUME=~/sandbox:/sandbox ./run.sh single /sandbox/source_hg /sandbox/target_git

依赖项

~11–22MB
~294K SLoC