git插入子目录的历史变化

标签 git merge github

我知道这听起来像是一个奇怪的问题..

我在 github 上有一个仓库 https://github.com/milovanderlinden/NLExtract

它有一个子目录“bag”,源自:https://github.com/MinIenM/BAG-Extract

在创建 NLExtract 的过程中,我们意外地忽略了在维护历史记录的同时正确 merge BAG-Extract。

为了维护对原作者的认可,我想获取从 BAG-Extract 到 NLExtract/bag 的完整提交历史记录。

这可能吗?关于如何进行“历史注入(inject)”有任何提示吗?

最佳答案

我想我可以帮助你,因为我以前也需要做类似的事情。

缺点是我的解决方案需要重写一些历史记录。如果你有很多合作者,这将是痛苦的,因为每个人的历史都会改变。据我所知,实际上没有任何解决办法,因为即使是像在当前根之前添加父提交这样简单的事情也会更改提交消息或我们的旧根,从而更改其 SHA,从而影响其子项的父字段,它会更改其 SHA,等等。

从你在 github 上的存储库来看,你似乎只有几个贡献者,所以这并不是那么令人毛骨悚然。

我还假设包存储库位于 https://github.com/MinIenM/BAG-Extract自从您读入以来,尚未取得任何进展,从读取您的提交日期和 BAG-Extract 提交来看,我认为情况就是如此。

因为听起来您的目标只是给予信任,所以子树 merge 可能适合您。

我们基本上会执行以下操作:

  1. 读入 BAG-Extract 作为新分支。它不会有共同的历史。
  2. 确定您在历史记录中的哪个位置引入了 bag 子目录。我们称之为“bagin”
  3. 添加一个新的 merge 提交,该提交将最后一个 BAG-Extract 提交和来自 (2) 的提交作为父级。这将是一个子树 merge ,因此想法是两个父级的不同之处仅在于其中一个以子树为前缀(例如 bag/)
  4. 将所有帖子“bagin”历史记录重新设置到此 merge 对象上。

这里有一些代码可以做到这一点。为了安全起见,我会将内容克隆到一个新的存储库,如果事情没有按计划进行,您可以将其丢弃

git clone <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e09071a2e09071a061b0c400d0103" rel="noreferrer noopener nofollow">[email protected]</a>:milovanderline/NLExtract
git log -- bag #Identify the first commit where "bag" enters. It starts with 78575
git checkout 78575 -b bagin
git remote add bag <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c3a4aab783a4aab7abb6a1eda0acae" rel="noreferrer noopener nofollow">[email protected]</a>:MinIenM/BAG-Extract
git fetch bag
git checkout bagin -b baginmerge
git merge bag/master -s subtree #Create the new merge object. baginmerge now points to the merge object. bagin, which hasn't moved, now has two children, one is the merge object, the other is your old history.
git rebase --onto baginmerge bagin master -p #Calculate the diffs from bagin to master, and replay them onto baginmerge. The -p flag tells rebase to preserve merges.

事实上,我已经 fork 了您的存储库并完成了上述步骤。在我的存储库中 https://github.com/dankessler/NLExtract你会发现一个名为 rebased_master 的新分支。请随意将其 pull 入。不幸的是,从您的网络图来看,人们已经从您的存储库中 fork 出来了,这可能会搞砸他们,但他们应该能够从内容开始重新设置或从任何 future 的更新中挑选您的提交应该是相同的,只是它们的 SHA 发生了变化。

如果您查看http://help.github.com/subtree-merge/子树 merge 策略大部分相似,因为如果您愿意,这应该使您能够从 BAG-Extract 中引入 future 的开发。

我可以想到另一种策略,让它看起来好像 bag 的开发最初是作为您的存储库的子树发生的(但具有正确的作者 ID),但这可能不是您想要的正在寻找。这样做的好处是,像 git Blame 之类的实用程序可能会工作得更好,但它要复杂得多,并且需要 git filter-branch ,我通常听说应该尽可能避免使用。不过,如果您想走这条路,请告诉我,我会更详细地解释。

祝你好运,欢呼!

关于git插入子目录的历史变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9505462/

相关文章:

git - 列出来自单个远程的 git 分支

visual-studio - 将当前代码推送到现有的 GitHub 存储库

git - 如何使用 gitcherry 获取提交者电子邮件?

linux - 如何将发布文件转换为 git repo

git - 使用 'git worktree' 将 git 2.5 用于多个工作目录的工作流程

git : New branch is pointing to the dev branch

r - 简单但不容易的合并任务

r - 在 R 中按范围合并 - 应用循环

jenkins - 位桶服务器 : Merge check - Minimum successful builds not enabling merge even after the condition is satisfied

git - git中如何自动排除某些文件类型?