我正在与一些学生一起领导一个项目,我们在私人 GitHub 存储库中使用 Jupyter 笔记本进行解释和测试用例。最初,我们提交了所有笔记本,包括输出,但由于文件太大,这变得不切实际。我们使用
nbstripout
实现了 git 过滤器,以自动从新提交中删除输出,但旧输出仍然会扰乱历史记录。
我计划使用
git-filter-repo
从历史记录中删除所有 Jupyter 笔记本输出。然而,我主要关心的是如何使重写的历史与学生的本地更改相协调,而不会让他们失去工作或面临复杂的合并冲突。
到目前为止我所发现的似乎表明,如果不大规模扰乱每个人的历史,就不可能做到这一点(例如,@torek的这个答案)。
所以...让我们假设,为了简单起见,您保留一个分支,所有工作都被合并...并且用户从中创建自己的分支。假设在您的存储库中,该分支称为
X
。从中创建一个名为 X-old
的新分支并将其推送到远程存储库中。
所以,你运行
git filter-repo
,你会得到一个 X
分支,它是 1 比 1,每次提交一次提交,相当于 X-old
但它没有不好的东西。您将这个新分支强制推入远程,以便远程X
现在清除了您从历史记录中删除的文件......现在真正的乐趣开始了。
当运行
git fetch
时,您的每个学生都能够看到这两个分支,他们所需要做的就是 move 他们在 X-old
之上私有的其他分支,以将他们的提交放在上面X
的顶部(新的 X
)。
这样做是这样的:
git rebase origin/X-old some-branch --onto origin/X
读起来是这样的:“
git
,请问您能否将构成 some-branch
历史的提交(那些在 origin/X-old
中不是)放在上面?完成后,
origin/X
将 some-branch
移动到这项工作的最后一次提交?如果你为我这样做,这里有 20 个。”
并且 tadaaaaaaaaa 你在新的
X
之上有了一个分支,他们可以像往常一样继续工作。
极端情况:
git rebase --interactive
将它们从这些提交中删除。关于如何做到这一点有很多答案。git remove
这些文件,因为不需要跟踪它们。