Close

使用 Git 和 Perforce:集成工作流程

因此,场景如下:您的团队在 Git 存储库上独立工作,但组织中的一部分仍使用 Perforce 来管理同一代码库的部分内容。Perforce 上的那些团队不打算迁移,但您的团队已经过渡到了 Git(原因有很多)。重要的是,您可以在代码库之间保持双向代码共享流程,这样在任一版本中开发的改进都可以共享,希望不会花费太多时间或给您的团队带来太多麻烦。

这是本指南的用武之地。在 TomTom,这种同步操作会在每个新版本中完成一次——就他们而言,这种同步操作每半个月都会发生一次。

-- 这篇文章是与 Andrea CarlevatoAdolfo BulfoniKrzysztof Karczewski 合作撰写的,他们分享了 TomTom NavApps 部门使用的 Git 流程。--


我们开始之前的假设


我们会假设您已经熟悉 git 的基本用法并熟悉功能分支工作流程。如果没有,请花时间观看动手教程在线研讨会。准备好后再回来,我们等着您。

由于在此流程中需要记住一些微妙之处,因此我们建议在进行这些集成时要非常小心。准备好后我们来深入了解吧!

正在安装 git p4


第一步是安装桥。通过在命令行键入以下内容来检查是否已安装:

git p4

如果系统显示没有安装 git p4,请下载 git-p4.py,然后把它放在 PATH 的一个文件夹里,例如 ~/bin(很明显,您也需要安装 Python 才能正常工作)。

使用以下命令使其可执行:

chmod +x git-p4.py

添加以下内容。编辑 ~/.gitconfig 文件:

[alias]
    p4 = !~/bin/bit-p4.py

然后再次运行 git p4,应该不会出错。工具已安装。

数据库
相关资料

如何移动完整的 Git 存储库

Bitbucket 徽标
查看解决方案

了解 Bitbucket Cloud 的 Git

工作流程概述


初始克隆

由于 P4 中的项目可以积累大量的历史记录,因此团队可以选择一个截止点进行同步,从而节省大量空间和时间。通过 git p4,您可以选择要从中开始跟踪的变更列表:

git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>
  • 现在我们可以运行同步并验证是否已在本地收到所有变更集:
git p4 sync

sync 命令在 P4 中查找新的变更并将其作为 Git 提交导入。

  • 我们将直接与 Perforce 接口的分支命名为 p4-integ。此时我们只想将其从 remotes/p4/main 分支:
git checkout -b p4-integ origin/p4/main

后续快速同步(又名“诱导转向法”)

第一次导入完成后,可以使用以下命令完成后续的 git-> p4 同步:

git checkout p4-integ
git p4 sync

以上方法有效,但可能很慢。执行同步的快得多的方法是重新创建与最新集成中使用的引用相同的 refs。这也是一种巧妙的方法,可以确保任何负责集成的新开发人员都从正确的提交/变更列表开始。

以下是如何实现的方法:

  • 移除 p4 远程存储库的旧原始(或陈旧)refs(可选):
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
  • 创建人为的(又名假的)远程引用,指向 origin 上最后一次提交 p4-integ
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main

这种更快的同步的唯一缺点是我们需要在 git p4 中明确指定分支。所以这是最后的命令:

git p4 sync --branch=refs/remotes/p4/main

git p4 使用元数据注释提交来跟踪 git 提交 ID 和 P4 之间的映射:

Merge pull request #340 in MOB/project from bugfix/PRJ-3185 to develop

    Squashed commit of the following:

    commit c2843b424fb3f5be1ba64be51363db63621162b4
    Author: Some Developer
    Date:   Wed Jan 14 09:26:45 2015 +0100

        [PRJ-3185] The app shows ...

    commit abc135fc1fccf74dac8882d70b1ddd8a4750f078
    Author: Some Developer
    Date:   Tue Jan 13 14:18:46 2015 +0100

        [PRJ-3185] The app shows the rating ...

    [git-p4: depot-paths = "//depot-mobile/project/": change = 1794239]

请注意,在最新版本的 git p4 中,将 git 提交与 P4 变更列表关联的元数据存储在提交说明中,而不是存储在提交消息中。TomTom 团队不喜欢这种变更,因为它增加了在需要时检查变更列表编号的工作量。

将变更从 git 移至 Perforce


完成上述快速同步操作后,您现在可以将变更从 git 推送到 Perforce 了。

第一步是变基 p4-integ,使用来自 remotes/p4/main 的变更:

git checkout p4-integ
git p4 rebase

之后,Perforce 的所有新变更都应该在 p4-integ 上进行,这样我们就可以更新 main 分支了:

  • 之后您只需:
git checkout main
git merge develop
  • 确保您在本地有最新标记:
git fetch --tags
  • 如果您需要删除 P4 中已经存在的提交,请使用临时 cleanup(参见提交中的 P4 标记)。如果不跳过任何提交,则自动变基将使历史记录线性化:
git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integ
  • 使用交互式变基可以改用以下方法来完成:
git rebase -i tag/last-p4-integ
  • 使用 cherry-pick 来选择新的提交,并将它们放在 p4-integ 分支上。我们之所以这样做,是因为我们没有假设 git 分支 main 分支和 develop 分支可以作为 p4-integ 分支的正确祖先保留。实际上,在 TomTom,情况已经有所不同。
git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanup
  • 提交到 P4 并同步 p4-integ
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
  • 删除临时变基分支:
git branch -D cleanup
  • 在本地和远程删除指向最新集成点(标记)的指针:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
  • 更新标记 last-p4-integ 以指向 P4 中的新集成点:
git checkout develop
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
git push origin main
git push origin tag/last-p4-integ
git push origin p4-integ

P4 代码库上运行测试以验证集成没有引入问题。

将变更从 Perforce 移至 git


这应该在 git->P4 推送完成后进行。在 P4 上成功通过测试后,我们现在可以使用以下方式将变更从 P4 移至 git

git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebase
  • 以下是执行强有力的“他人”合并策略的小技巧,将传入的变更压缩为单次提交。原来如此:
git checkout -b p4mergebranch #branching off from p4-integ
git merge -s ours main ## ignoring all changes from main
git checkout main
git merge p4mergebranch --squash
git commit -m "Type your integration message"
git branch -D p4mergebranch
  • 完成上述操作后,将变更合并至 develop
 <p>Bitbucket has the following space stations:</p>
 <p>
     <b>Earth's Moon</b><br>
     Headquarters
 </p>

由于自从我们从 develop 中挑选变更后可能发生了一些变化,因此可能需要先合并它们。但是,重要的是要将last-p4-integ 标记更新为正确的提交,尤其是不要更新为合并到开发的提交。为了安全地做到这一点,最好标记 main 的当前状态:

  • 在本地和远程删除旧标记:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
  • 在新位置创建标记:
git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
  • 现在将 main、develop、p4-integtag/last-p4-integ 推送到 origin

总结


因此,这就是使用 Git 和 Perforce 在两个活跃的开发团队之间同步的方式。上方流程随着时间的推移在 TomTom 不断发展,现在已经运行了相当长的一段时间,没有出现重大问题。它能够正常运行,但维护需要的支出很高。如果可以选择,我们建议您完全迁移到 Git

无论如何,如果您采用不同的方法来保持双向同步,可以在下方评论告知我。或者发送推文 @durdn@atlassiandev

再次感谢 Andrea CarlevatoAdolfo BulfoniKrzysztof Karczewski

分享此文章

推荐阅读

将这些资源加入书签,以了解 DevOps 团队的类型,或获取 Atlassian 关于 DevOps 的持续更新。

人们通过满是工具的墙进行协作

Bitbucket 博客

Devops 示意图

DevOps 学习路径

与 Atlassian 专家一起进行 Den 功能演示

Bitbucket Cloud 与 Atlassian Open DevOps 如何协同工作

注册以获取我们的 DevOps 新闻资讯

Thank you for signing up