ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

jj 多远程(Multiple Remotes)实战指南:GitHub 式 Fork 协作与上游集成工作流配置

jj 多远程(Multiple Remotes)实战指南:GitHub 式 Fork 协作与上游集成工作流配置 jj 多远程Multiple Remotes实战指南GitHub 式 Fork 协作与上游集成工作流配置【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj导读本指南基于 Jujutsujj官方文档 docs/guides/multiple-remotes.md 编写系统讲解在一个仓库中配置多个 Git 远程remote的两种典型工作流——向上游项目贡献代码GitHub 式 fork与维护一个独立仓库并周期性地从上游集成变更。你将掌握git.fetch、git.push的默认远程配置、jj bookmark track/untrack的远程书签跟踪机制以及如何通过覆盖trunk()revset 别名来正确设定主干immutable 边界并理解这些配置背后的源码实现原理。Jujutsu 与 Git 完全兼容可以对接 GitHub、GitLab、Codeberg 等所有主流 Git 托管平台参见 glossary.md 中对 Remote 的定义。当仓库同时存在多个远程时如何配置取决于你的工作流以及每个远程扮演的角色是向上游项目提交贡献还是从另一个仓库集成变更。两种场景下jj git fetch、jj git push、书签跟踪与trunk()别名的配置策略截然不同。术语约定Nomenclature在开始配置之前先统一文档中的命名约定origin你拥有写权限的远程通常是你推送变更的地方例如你自己的 fork。upstream更知名的权威上游仓库你可能没有推送权限只能拉取。每个仓库的主干trunk假定为main因此对应的远程书签是mainorigin和mainupstream。远程书签remote bookmark的表示法Jujutsu 会记录每个书签在远程上的最后看到的位置类似 Git 的 remote-tracking branches用书签名远程名表示例如jj new mainorigin。该记录在每次jj git fetch/jj git push时更新且 jj 不提供手动编辑这些记录的方式详见 docs/bookmarks.md 的 Remotes and tracked bookmarks 小节。相关源码佐证trunk()等 revset 别名与配置项的定义见默认配置文件 cli/src/config/revsets.toml。其中内置的trunk()默认值已经涵盖origin和upstream上的常见主干名[revset-aliases] trunk() latest( remote_bookmarks(exact:main, exact:origin) | remote_bookmarks(exact:master, exact:origin) | remote_bookmarks(exact:trunk, exact:origin) | remote_bookmarks(exact:main, exact:upstream) | remote_bookmarks(exact:master, exact:upstream) | remote_bookmarks(exact:trunk, exact:upstream) | root() ) 注意文件中的注释trunk() can be overridden as 这正是本指南中两种工作流都要覆盖trunk()别名的原因——用mainorigin或mainupstream明确指定哪个远程书签定义了你仓库的主干。工作流一GitHub 式 fork 向上游贡献代码这是最经典的场景upstream是权威上游仓库origin是你自己的 fork用来推送贡献通常是发起 Pull Request 的入口。典型操作从upstreamfetch 获取最新变更。将mainpush 到origin以保持 fork 与上游同步。将my-featurepush 到origin然后向上游仓库发起 Pull Request。配置步骤为此场景你需要跟踪mainupstream这样每次从upstreamfetch 时本地main书签都会被更新。跟踪mainorigin这样执行jj git push时fork 的main书签会被更新。将mainupstream设为trunk()别名使其成为不可变immutable主干。# 默认同时从两个远程 fetch $ jj config set --repo git.fetch [upstream, origin] # 默认只向 fork push $ jj config set --repo git.push origin # 跟踪两个远程的 main 书签 $ jj bookmark track main # 上游仓库定义主干 $ jj config set --repo revset-aliases.trunk() mainupstream配置参数深度解析git.fetch配置jj git fetch不带--remote参数时默认拉取哪些远程。取值可以是一个远程名也可以是一个字符串数组一次拉取多个远程。fetch.rs 源码 中的文档说明If no remotes are specified, fetches the remotes specified by thegit.fetchsetting. If that is not configured and there are multiple remotes, the remote named origin will be used.其解析实现位于 fetch.rs 的resolve_default_fetch_remotes附近通过settings.get::VecString(git.fetch)读取并用parse_union_name_patterns解析。git.push配置jj git push不带--remote参数时默认推送的目标。与git.fetch不同git.push目前只能是一个单一远程不能是数组docs/config.md 中明确说明。push.rs 源码 显示其回退逻辑先读git.push设置未配置时若仓库只有一个远程则使用该远程。字符串模式git.fetch和git.push的值默认按 glob 语法匹配远程名也支持其他 string pattern 语法例如jj config set --repo git.fetch regex:^(remote|upstream)或jj config set --repo git.fetch [remote*, upstream*]详见 docs/config.md。书签跟踪命令说明jj bookmark track main会跟踪所有匹配main的远程书签即同时跟踪mainorigin和mainupstream。track.rs 源码 显示该命令接受BOOKMARK[REMOTE]形式的参数BOOKMARK默认按 glob 语法匹配书签名。BOOKMARKREMOTE精确解析为一个远程书签。--remote REMOTE选项可以限定只在指定远程上跟踪。此外源码还规定了一些使用约束不能混用bookmark模式与bookmarkremote符号--remote也不能与bookmarkremote符号同时使用track.rs 中的校验逻辑。工作流二维护独立仓库周期集成上游变更这是另一种常见场景仓库最初从上游克隆而来但现在main分支上含有不属于上游、未来也可能不会回馈上游的本地变更。角色划分origin是你正在工作的仓库拥有写权限。upstream是你周期性集成变更的来源。典型操作从originfetch 获取最新变更。将书签 push 到origin。将 Pull Request 合并进mainorigin。周期性 fetchmainupstream并将其变更 merge、rebase 或 duplicate 进mainorigin。配置步骤与工作流一的关键区别在于upstream在这里只是集成来源不是主干。因此只跟踪mainorigin本地main只跟随 origin 更新必要时可以推送。不要跟踪mainupstream。将mainorigin设为trunk()别名使其不可变。# 默认只从 origin fetch或按需同时拉取两个远程 $ jj config set --repo git.fetch [origin] # 或者jj config set --repo git.fetch [upstream, origin] # 默认只向 origin push $ jj config set --repo git.push origin # 只跟踪 origin 上的书签 $ jj bookmark track main --remoteorigin $ jj bookmark untrack main --remoteupstream # origin 仓库定义主干 $ jj config set --repo revset-aliases.trunk() mainorigin关键概念跟踪与否的区别正如 docs/bookmarks.md 所解释的跟踪trackmainorigin意味着远程书签与本地main表示同一条分支fetch 时远程的移动会传播到本地main本地不存在则自动创建push 时本地main的移动也会同步回远程。如果两者都发生了移动且一方领先则领先者胜出否则本地书签会进入冲突状态。不跟踪mainupstream意味着上游main的移动只更新mainupstream这个远程记录本身不会触碰你的本地main从而保证你可以在mainorigin上自由管理本地变更再自行决定何时、以何种方式merge/rebase/duplicate把上游变更合入。jj bookmark untrack命令同样支持--remote参数其参数结构与track对称详见 untrack.rs 源码。另外注意如果既要忘记本地书签、又要取消对应远程书签的跟踪应改用jj bookmark forget。补充按远程精细化配置自动跟踪除了手动jj bookmark track/untrack你还可以通过remotes.name.auto-track-bookmarks配置每个远程自动跟踪哪些书签docs/config.md 的 Automatic tracking of bookmarks 小节。对于本工作流的 fork 场景尤其有用[remotes.origin] auto-track-bookmarks * [remotes.upstream] auto-track-bookmarks main即forkorigin上的所有书签自动跟踪上游upstream只自动跟踪main。remotes.name.auto-track-created-bookmarks则只对本地新建的书签生效。类似的remotes.name.fetch-bookmarks/fetch-tags可以控制每个远程默认拉取哪些书签和标签docs/config.md。其他工作流与通用原则其他工作流也可能被支持。以下是一些通用指导trunk()应设置为你通常在其上 rebase 的远程书签。如果你总是基于上游 rebase就把它设为mainupstream如果你的主干在本地仓库自己手里就设为mainorigin。跟踪mainorigin意味着它和main代表同一条分支一方移动另一方应随之移动。如果希望它们自动同步移动就应该跟踪该远程书签如果不希望就不要跟踪。关于trunk()与不可变性的底层原理覆盖trunk()别名并非仅仅影响jj log的默认显示范围。从 cli/src/config/revsets.toml 可以看到trunk()是builtin_immutable_heads()的组成部分builtin_immutable_heads() trunk() | tags() | untracked_remote_bookmarks() | untracked_remote_tags() immutable_heads() builtin_immutable_heads() immutable() ::(immutable_heads() | root()) mutable() ~immutable()也就是说trunk()指定的远程书签会被视为不可变主干immutable headsjj 的自动 rebase 等重写操作不会触碰它及其祖先。因此在工作流一中设置trunk()为mainupstream确保你基于上游主干开发的提交可以自由重写而上游main本身保持稳定。在工作流二中设置trunk()为mainorigin则把你自己的main声明为稳定基线而upstream的main只是一个普通远程书签可以随时集成。trunk()别名的可覆盖性在 cli/src/config/revsets.toml 的注释中明确说明用户配置会覆盖内置默认值。关于默认远程回退的源码细节jj git fetch与jj git push在未配置对应设置时都会回退到 origin 或唯一的远程。源码层面的回退逻辑如下fetch.rs未配置git.fetch且存在多个远程时默认使用名为origin的远程。push.rsgit.push未配置时若存在多个远程默认使用origin。git/mod.rs 的get_single_remote当仓库只有一个远程时无论名称如何fetch/push 都会默认使用它names.len() 1时返回该唯一远程多个远程时返回None走 origin 回退。这解释了为什么示例配置中显式设置git.fetch/git.push是必要的一旦仓库有多个远程默认行为是仅使用origin而你的origin与upstream角色不同必须显式声明 fetch 与 push 的目标。更多参考书签跟踪机制的完整说明含冲突处理docs/bookmarks.md远程相关命令jj git remote list/add/remove/rename/set-url实现见 cli/src/commands/git/remote/与多远程相关的 git 配置项git.fetch、git.push、remotes.name.*详见 docs/config.md如果你的工作流在上述两种场景中未被良好覆盖欢迎参与项目讨论官方 Discord 与 GitHub issue #7072 中有关于增强书签跟踪机制的开放讨论。【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表