初始克隆后扩展`git-p4` clientspec

时间:2014-01-27 09:04:50

标签: git perforce git-p4

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

在我扩展了clientspec之后,git-p4 rebase什么也没做(可能是因为自上次提交的更改以来没有新的相关更改列表,我所做的就是更新客户端规范)

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

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

2 个答案:

答案 0 :(得分:3)

在撰写本文时,我找不到让git-p4直接从Perforce clientspec导入其他路径的方法。但是,我相信我已经设计了一种方法来手动执行此操作并git-p4尊重它。

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

想法

正如您所说,只是添加Perforce clientspec的路径并且最初执行git p4 rebase不会做任何事情。但是,我注意到git p4 rebase会在Perforce中修改文件后添加该路径中的文件,并且新路径位于git-p4的{​​{1}}列表中。 (depot-paths是提供给depot-paths的软件仓库路径的初始列表。)因此,您需要:

  1. 获取新路径的初始副本到您的Git存储库。
  2. 欺骗git p4 clone相信它自己添加了初始副本。
  3. git-p4在其git-p4列表中包含新路径。
  4. 因此,您可以从Perforce同步文件的副本,确保它们与已从Perforce导入的文件保持一致,然后您可以将它们显式添加到您的Git存储库。

    depot-paths显然不存储其git-p4列表,也不会存储除Git提交消息之外的任何位置的最后导入的Perforce更改号,因此您可以通过复制自己的元数据来欺骗depot-paths提交消息。

    最后,您可以移动git-p4(和p4/master,这是p4/HEAD的别名)以指向您的新提交,以便将来的p4/master命令处理该提交作为从Perforce导入的东西。

    一步一步

    1. 查看与git p4 rebase对应的提交。确保您没有任何暂存或未暂停的更改。如果你这样做就藏起来。

    2. 将新路径添加到p4/master使用的Perforce客户端规范。在下面的步骤中,我将其称为git-p4

    3. 运行//depot/new/path/以查看上次导入的Perforce更改中的提交消息。它将有一行看起来像:

      git log

      记下Perforce更改编号。

    4. 在Perforce客户端中,将添加的路径同步到该更改号。例如:[git-p4: depot-paths = "//depot/tree/": change = 12345]

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

    6. 在Git存储库中的新路径上运行p4 sync //depot/new/path/...@12345

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

      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]列表必须按ASCII值排序(即depot-paths应在//depot/foo-bar/之前。

    8. 再次运行//depot/foo/bar/。确认提交消息中的git log行看起来像是导入的Perforce更改中的行。记下您提交的SHA1哈希值。

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

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

      其他一些值得注意的事项

      • 显然,只有在您导入这些文件的提交之后,新路径才会存在于您的Git存储库中,因此//depot/new/path/如果横跨该边界并涉及这些文件,则不会有用。

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

      • 或者,您可以将新路径添加到Perforce clientspec,然后提交触及该路径中所有文件的Perforce更改。然而,我建议这样做,因为这可能会破坏他人(并想象如果其他人都这样做)。我只是为了完整性而提到它。

答案 1 :(得分:1)

@jamesdlin的答案对我有用。在研究如何解决此问题的想法时,我遇到了其他一些有趣的stackoverflow答案。我想知道是否可以将它们组合起来以创建一个优雅的解决方案。我在这里提到这个想法是为了帮助别人。这个想法是How to copy commits from one Git repo to another?中描述的内容的变体,并借鉴了git clone multiple p4 paths in one git repo的想法。

  1. 从p4客户端Pa开始,该客户端已镜像到git repo Gb。采取添加到客户端Pa的一组路径,并创建一个仅映射那些路径的新p4客户端Pb。
  2. 接下来,创建一个新的git repo Gb,以克隆p4客户端Pb。 git repo Gb可以在任何临时位置创建,完成后将被丢弃。 git p4 clone newstuff ...etc...
  3. 回到Ga,将新的遥控器添加到Gb。 git remote add newstuff /path/to/newstuff
  4. 按照How to copy commits from one Git repo to another?中的其余说明进行操作。像在那些说明中一样使用樱桃采摘。或者,如果需要,可以将git merge--allow-unrelated-histories一起使用。