7

完成后git-p4 clone --use-clientspec,我想在 clientspec 中添加一个额外的条目,并将添加的条目的当前状态导入我的 Git 存储库。

在我扩展 clientspec 之后,agit-p4 rebase什么都不做(可能是因为自上次提交的更改以来没有新的相关更改列表,我所做的只是更新 clientspec)

我尝试做 a git-p4 sync --use-client-spec,但这抱怨快速导入失败,因为新提示不包含我的初始提交。

有没有办法扩展客户端规范,而不必git-p4 clone从头开始一个新的 Git 存储库?

4

2 回答 2

5

在撰写本文时,我找不到git-p4直接从 Perforce 客户端规范导入其他路径的方法。但是,我相信我已经设计了一种手动操作并获得git-p4荣誉的方法。

免责声明:我对以下步骤可能造成的任何损害不承担任何责任。首先备份你的.git树可能是个好主意。

这个想法

正如您所说,仅添加到 Perforce 客户端规范的路径并执行git p4 rebase初始操作不会做任何事情。但是,我注意到git p4 rebase将在 Perforce 中修改后从该路径添加文件,并且如果新路径在git-p4depot-paths列表中。(depot-paths是提供给的仓库路径的初始列表git p4 clone。)因此您需要:

  1. 将新路径的初始副本获取到您的 Git 存储库中。
  2. 欺骗git-p4相信它自己添加了初始副本。
  3. git-p4新路径包含在其depot-paths列表中。

因此,您可以从 Perforce 同步文件的副本,确保它们与已从 Perforce 导入的文件一致,然后您可以明确地将它们添加到您的 Git 存储库。

git-p4显然不会将其depot-paths列表或最后导入的 Perforce 更改编号存储在 Git 提交消息中以外的任何地方,因此您可以git-p4通过在自己的提交消息中复制其元数据来进行欺骗。

最后,您可以移动p4/master(和p4/HEAD,它是 的别名p4/master)指向您的新提交,以便将来的git p4 rebase命令将该提交视为从 Perforce 导入的内容。

一步步

  1. 查看对应的提交p4/master。确保您没有任何暂存或未暂存的更改。如果你这样做,就把它们藏起来。

  2. 将新路径添加到git-p4. 在下面的步骤中,我将其称为//depot/new/path/.

  3. 运行git log以查看您上次导入的 Perforce 更改的提交消息。它将有一条如下所示的行:

    [git-p4: depot-paths = "//depot/tree/": change = 12345]

    记下 Perforce 更改编号。

  4. 在您的 Perforce 客户端中,将您添加的路径同步到该更改编号。例如:p4 sync //depot/new/path/...@12345

  5. 递归地将那些新同步的文件从 Perforce 客户端复制到 Git 存储库中的相应位置。(如果有符号链接,这里可能需要注意。)

  6. 在 Git 存储库中的新路径上运行git add

  7. 运行git commit。您可以在提交消息中说出您想要的任何内容(例如“从 CLN 12345 初始导入 //depot/new/path/”)。但是,在消息的末尾,您必须复制git-p4您之前观察到的元数据行:

    [git-p4: depot-paths = "//depot/tree/": change = 12345]

    如果//depot/new/path/不是 的子目录//depot/tree,则必须修改depot-paths添加新路径:

    [git-p4: depot-paths = "//depot/new/path/,//depot/tree/": change = 12345]

    depot-paths列表必须按ASCII 值排序(即,//depot/foo-bar/应该在 之前//depot/foo/bar/)。

  8. 再跑git log。确认git-p4提交消息中的行看起来像来自导入的 Perforce 更改的行。记下您提交的 SHA1 哈希。

  9. 导航到 Git 存储库的根目录。编辑.git/refs/remotes/p4/master. 删除列出的旧 SHA1 哈希并将其替换为您提交的 SHA1 哈希。(如果.git/refs/remotes/p4/master不存在,请检查.git/packed-refs并更新那里的相应行。)

现在您的 Git 存储库包含//depot/new/path/来自更改 12345 的文件的副本,它应该从未来的 Perforce 更改中获取对这些文件的任何更改。

其他一些注意事项

  • 显然,只有在您导入这些文件的提交之后,新路径才会存在于您的 Git 存储库中,因此git bisect如果它跨越该边界并涉及这些文件,它将没有用。

  • 由于修改后的文件如果包含在您的 Perforce 客户端规范中(并且包含在git-p4'sdepot-paths中)会自动添加,因此在某些情况下您可能会避免所有这些工作。例如,如果您事先知道有人将向 Perforce 软件仓库添加一个新目录,并且该目录已包含在您depot-paths的客户端规范中,但您的客户端规范中没有,您可以抢先将其添加到您的 Perforce 客户端规范中。然后,您应该能够在它实际添加到 Perforce 后自动获得该新路径。

  • 或者,您可以将新路径添加到您的 Perforce 客户端规范,然后提交涉及该路径中所有文件的 Perforce 更改。但是,我建议这样做,因为这可能会对其他人造成干扰(想象一下,如果其他人都这样做了)。我提到它只是为了完整性。

于 2015-05-16T18:08:32.910 回答
1

@jamesdlin 的回答对我有用。在研究如何解决这个问题的想法时,我遇到了其他几个有趣的 stackoverflow 答案。我想知道它们是否可以结合起来创建一个优雅的解决方案。我在这里提到这个想法,以防它对其他人有所帮助。这个想法是如何将提交从一个 Git 存储库复制到另一个?并从一个 git repo 中的 git clone 多个 p4 路径中借用了一个想法。

  1. 从 p4 客户端 Pa 开始,它被镜像到 git repo Ga 中。获取添加到客户端 Pa 的一组路径,并创建一个仅映射这些路径的新 p4 客户端 Pb。
  2. 接下来创建一个克隆 p4 客户端 Pb 的新 git repo Gb。git repo Gb 可以在任何临时位置创建,完成后将被丢弃。git p4 clone newstuff ...etc...
  3. 回到 Ga,为 Gb 添加一个新的遥控器。git remote add newstuff /path/to/newstuff
  4. 按照如何将提交从一个 Git 存储库复制到另一个?. 在这些说明中使用樱桃挑选。或使用git merge,--allow-unrelated-histories如果需要。
于 2019-02-16T21:51:57.077 回答