从 git 迁移到 Perforce
我的任务是迁移我的团队和源从 git 到 Perforce,我正在寻找有关如何将 git 历史记录转移到 p4 的想法。
我很乐意只移动主分支。然而,即使这样也被证明是有问题的。
我正在使用很棒的 git-p4 工具。我在 p4 工作区中创建一个目标区域,并使用 git p4 clone //depot/StuffFromGit 开始在 git-p4 中跟踪它。我将 git 存储库的所有更改移植到 git-p4 克隆中。然后我可以 git p4 Submit 并完成,所有更改都将推送到 p4。
当 git 历史记录看起来像这样,漂亮且线性时,它会很好用:
A---B---C---D
问题来自于多个人在该项目上工作。即使他们在 master 上工作,仍然会创建分裂和合并的分支。尽管如此,git-p4 勇敢地处理了这个问题:
A---B---C---E
\--D--/
git p4 遍历 OK,按顺序提交 ABCDE(或 ABDCE,任一者的历史优先)。
例如,当 C 和 D 都更改同一个文件,而 E 是真正的诚实合并时,就会出现问题。 git p4 rebase
在这里失败;它会倒回提交,但在播放期间它会首先应用 C,然后尝试 D 并发现冲突。然后它会停下来,要求我合并。嗯,E 包含合并,但它要求我手动合并! 'git p4 Submit' 将以类似的方式失败,只是现在 p4 拒绝合并前的更改。
Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... Auto-merging main.cpp CONFLICT (content): Merge conflict in main.cpp Failed to merge in the changes. Patch failed at 0005 Changing main
所以现在我被困住了。有没有办法清理 git 历史记录或让 git-p4 理解它?合并的存在令人沮丧。
我的想法:
- 使用 git filter-branch 删除所有提到的冲突文件。我会得到历史评论,尽管遗漏了许多文件更改。由于历史记录中有大约 3000 次提交,我最终会删除所有关键(繁忙)文件的历史记录。在过滤文件导入结束时,我将通过执行 HEAD 的最终提交来添加丢失的文件。
- 转储历史记录,对 HEAD 进行一次 p4 提交(简单但悲伤)。
- 不转向 p4:我已经尽可能长时间地研究这个想法。
没有一个是真正伟大的。关于如何 git 'gt p4 rebase' 或 'git p4 Submit' 工作有什么想法吗?
I have the task of migrating my team & source from git to Perforce, and I'm looking for ideas on how to move the git history into p4.
I would be happy moving master branch only. However, even that is proving problematic.
I'm using the wonderful git-p4 tool. I create an destination area in my p4 workspace, and use git p4 clone //depot/StuffFromGit
to start tracking it in git-p4. I graft all my git repository's changes into the git-p4 clone. I can then git p4 submit
and be done, all the changes are pushed to p4.
It works great when the git history looks like this, nice and linear:
A---B---C---D
The problem comes with multiple people working on the project. Even though they are working on master, that still creates branches that split and merge. Still, git-p4 bravely handles this:
A---B---C---E
\--D--/
git p4 traverses OK, committing ABCDE in order (or ABDCE, either person's history first).
The problem comes when, for example, C and D both change the same file, and E is a real-honest-to-goodness merge. git p4 rebase
fails here; it'll rewind the commits, but during playback it'll apply C first, then attempt D and find a conflict. It'll then stop, asking me to merge. Well, E contains the merge but it's asking me to hand-merge! 'git p4 submit' will fail in a similar way, only now it's p4 rejecting the pre-merge change.
Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... Auto-merging main.cpp CONFLICT (content): Merge conflict in main.cpp Failed to merge in the changes. Patch failed at 0005 Changing main
So now I'm stuck. Is there a way to sanitize the git history or to get git-p4 to understand it? It's frustrating as the merges are there.
Thoughts I've had:
- Use git filter-branch to remove all mention of conflicting files. I'd get the history comments across, though missing many file changes. With about 3000 commits in the history, I would wind up removing all of the key (busy) files' history. At the end of the filtered-files import, I'd add the missing files back by doing a final commit of the HEAD.
- Dump the history, do a single p4 commit of the HEAD (simple but sad).
- Not move to p4: I've worked that idea for as long as possible.
None of which are really great. Any ideas on how to git 'gt p4 rebase' or 'git p4 submit' to work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
“扔掉旧历史”的选项并不像听起来那么糟糕:你可以将 git 存储库永远保留在它旁边,以防有人需要挖掘旧的东西。不幸的是,没有办法在 svn 和 p4 等旧式线性系统中表示 git 的复杂历史视图。
回顾旧历史的主要原因是像“git annotate”这样的东西(我假设 p4 有类似的工具)。如果这就是您想要的,那么也许您真正想做的是将所有合并提交压缩为仅其父项之一(因此它们看起来像单个提交而不是合并)。这更像是 svn 和 p4 在它们自己的历史模型中记录的内容,其中合并看起来就像线性流中的单个提交。您可以使用 git-filter-branch 等来完成此操作。当然,这会丢失子分支上发生的所有历史记录......但 p4 用户习惯于没有这些信息。
The option of "just throw away the old history" is not as bad as it sounds: you can just keep your git repo alongside it forever, in case anyone needs to dig through the old stuff. Unfortunately, there is just no way to represent git's complex view of history in old-style linear systems like svn and p4.
The main reason to look back into old history is for things like 'git annotate' (I assume p4 has a similar tool). If that's all you want, then maybe what you really want to do is squash all your merge commits down to only one of their parents (so they look like a single commit instead of a merge). That's more like what svn and p4 would have recorded in their own history model, where merges just look like a single commit in the linear stream. You can probably do this with git-filter-branch or the like. Of course, this would lose all the history that happened on sub-branches... but p4 users are used to not having that information.
您检查过“裁缝”工具吗?它是为同步不同的 VCS:es 而构建的。它应该有 Perforce 支持。
顺便说一句,我的第一反应是认真质疑这个决定,但我想你已经这样做了。
Have you checked out the tool "tailor"? It's build for synchronizing different VCS:es. It's supposed to have Perforce-support.
As a side-note, my first reaction would be to seriously question the decision, but I guess you've already done that.
您看过 Perforce Fusion 吗?
大约 7-8 年前我也曾提出过类似的问题,我们基本上将所有高级开发人员召集在一起,并告诉推动这个想法的经理,他已经疯了。
也就是说 - https://www.perforce.com/perforce/ r15.3/手册/git-fusion/
Have you looked at Perforce Fusion?
I had a similar ask around 7-8 years ago, and we basically rallied all of the senior devs together, and told the manager pushing this idea that he was off his rocker.
That said - https://www.perforce.com/perforce/r15.3/manuals/git-fusion/
我认为你应该尝试使用 Tortoise SVN,然后考虑单分支更新或者你可以说迁移。为了安全起见,请确保克隆所有转储。
祝你好运 !
I think you should try with Tortoise SVN and then Hg considering the single branch update or you can say migration. Make sure you have all the dump cloned to be on the safe side.
Good Luck !