Git format-patch/bundle for human-readable sneakernet "pull/push"

标签 git git-workflow git-am git-bundle

我有两个房间,我在其中使用 git 维护一些源代码,一个是进行大部分开发的“开发”房间,另一个是我们实际使用软件的“部署”房间。不可避免地,部署室也会发生一些变化。我希望两个房间在 git 中共享相同的历史记录。

限制:

  1. 出于安全原因,这两个房间没有联网。
  2. 只有文本文件(人类可读)可以离开部署室。

使用 git bundle 将更改移动到部署室很简单,并跟踪我们进入部署室的最后一次提交。由于仅限文本的限制,将更改移出房间更加困难。

目标: 在我的两个未连接的房间之间来回移动提交,就好像 git pull发生了,,两个房间的 SHA1 散列值相同。

到目前为止:

  • 我试过了 git format-patch将更改从部署移回开发,但这不会记录 merge ,因此需要为每个连续的更改集生成不同的补丁集,以及如何重现发生在两者之间的确切 merge 提交的一些记录。有讨论about making diffs for merge commits ,但这似乎并没有捕捉到实际的祖先,只有变化。看来补丁的格式可能不够丰富,无法提供必要的信息。

  • 一些 bundle-to-text 脚本可用于将 bundle 转换为非压缩的和人类可读的(ish)格式,(然后在下载后再次返回)但我没有发现这样的证据脚本存在。

  • 也许可以编写一个脚本来遍历从某个共同祖先到最新提交的历史记录,然后 a) 制作补丁或 b) 重新创建一些众所周知的引用的 merge 。

    <

回退:我总是可以将来自部署室的提交压缩成一个原始补丁并破坏历史记录,但随后从 dev->deploy 进一步下载会破坏任何现有的工作副本。不理想。

更新: 我相信git fast-export可以做我需要的,尽管大多数示例都在整个存储库上工作,而不是像 git bundle 这样的部分历史记录.我有一个工作玩具示例,我可以在其中将部分历史记录导出到过时的克隆中,但它需要我手动编辑快速导出输出,以便添加 from <sha1>第一次提交。如果不进行此修改,导入会创建不同的 sha1,然后会提示 Not updating refs/heads/master (new tip <hash> does not contain <master's hash>) .

更新 2: 我的git fast-export解决方案确实有效,但它存在带宽问题,因为它通过提供全新文件而不是与以前文件的差异来工作。这是 Not Acceptable ,因为我实际上必须阅读所有这些额外的行。

最佳答案

我从未找到完美的解决方案,但我们现在所做的似乎奏效了。主要缺点是部署室中的提交最初有一个 SHA1,然后在与开发室 merge 后更改为不同的 SHA1。好消息是 git 很容易识别它们,因为相同的提交可以通过它们 merge

  • 我们必须跟踪 3 个检查点:
    • dev/master 开发室里有最新的开发。
    • deploy/master 在 deploy room 有最新的开发。
    • dev_deploy_common 这是两个历史共享的最后一次提交。

.

  1. 当我们将代码从开发移动到部署(使用 bundle )时,我们将提交作为部署室中 dev_deploy_common 分支的一部分引入(git pulldev_deploy_common),然后从 deploy/master 执行 git merge dev_deploy_common 并解决冲突。

  2. 当我们将代码从 deploy 移动到 dev(必须是文本文件)时,我们需要执行一些额外的步骤:

  3. 首先,我们将 deploy/master rebase 到 dev_deploy_common 上,这样我们所有的补丁都是连续的。这通常很容易,因为我们已经处理了在将 bundle 从开发部署到部署时发生的 merge 期间的任何冲突。

  4. 然后我们使用

    生成一个补丁集
    git format-patch -M25 -C25 --find-copies-harder -k --ignore-if-in-upstream
    

    -M25 -C25 --find-copies-harder 选项只是减小了输出文本的大小。 -k 选项保持提交主题完整。 --ignore-if-in-upstream 将我们的提交限制为自 dev_deploy_common 以来的新提交。

    结果是 patchset.txt 补丁集合。该文件可以进行人工审查,然后移至开发室。

  5. 在开发室中,我们使用以下命令导入补丁集:

    git am -k -3 --keep-cr --committer-date-is-author-date patchset.txt
    

    不幸的是,即使我们使用了所有我们可以使用的命令来保持补丁完全相同,一些属性还是发生了变化,主要是提交者。因此,“相同”的提交在开发室和部署室中将具有不同的 SHA1。这种差异将持续存在,直到我们将 bundle 移回部署室。

  6. 将包从开发转移到部署时,merge 操作(通常)会识别相同的补丁并无缝地将提交替换为开发历史中的提交。请参阅第 1 步。

关于Git format-patch/bundle for human-readable sneakernet "pull/push",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18216071/

相关文章:

git - 将损坏的松散对象修复为 git 中的提交

git - 我应该如何组织我的 Git 存储库和分支来创建一个网站的多个版本?

git am 应该忽略以 "[]"开头的提交消息中的某些内容吗?

git - 如何 'git-am' 应用使用 'git-format-patch --no-prefix' 创建的补丁?

git - 打补丁的时候有什么方法可以解决冲突吗?

git - 如何在第一个版本的 master 分支上创建 Github pull request

git - 为什么 cherry-pick 之后的 rebase 不会两次应用相同的提交?

Git:我看不到最后一次提交或者推送

git - 是否可以告诉 Github 我的分支已 merge 到上游 master 中?

git - "cherry-pick a merge"的最简单方法