我有一个巨大的代码库,有很多变化,我想分支它,并将它推送到一个远程的新分支,但是只推送上个月的变更集,让这个月的第一次变更看起来像是存储库,这意味着我不关心以前的更改。我确信这是可能的,只是不知道它叫什么以及如何做。
4 回答
首先,假设您已经找到了大约一个月前的提交,您希望成为新的第一个提交,可能是git show HEAD@{1.month.ago}
通过git log
. 假设那个提交是f414f31
. 我们还假设您正在处理的分支的名称称为dev
.
你说你希望它看起来以后提交是存储库中的第一个,所以将这个分支保留在同一个存储库中没有真正的意义——根本没有共同的历史。因此,让我们创建一个新的空存储库,以便从头开始:
mkdir squashed-repository
cd squashed-repository
git init
现在让我们添加一个引用旧存储库的远程,并从那里获取所有分支作为新存储库中的远程跟踪分支。
git remote add previous /home/whoever/original-repository/
git fetch previous
现在从月初的提交更新您的工作树和索引:
git checkout f414f31 .
(请注意该.
行末尾的。)
现在从索引的状态创建一个提交:
git commit -m 'A new start.'
现在,您git rebase
可以重播从 afterf414f31
到并包括previous/dev
在您的 new 之上的所有提交master
,当前只有一个提交。
git rebase --onto master b1cbc10e84bb2e2 previous/master
您可能必须在该变基期间修复一些冲突。默认情况下,git rebase
当它重新应用由这些提交引入的更改时,将线性化历史 - 你可以告诉它尝试使用 保留它们-p
,但这可能不起作用。
现在master
这个新存储库中的分支应该是你想要的,所以你可以删除我们创建的远程:
git remote rm previous
我应该说我通常会尽量避免这种类型的历史重写,特别是如果您与任何人共享原始存储库。无论如何,早期的历史记录真的很有用——把它保存在你的存储库中真的很糟糕吗?
如果我正确地收到您的请求,您希望从当前存储库的特定点开始创建一个新存储库。为什么?因为您想保持它的清洁并消除该特定点背后的所有历史记录。现在,这更有可能是一个好主意,这里有一个更好的答案的链接。
这里的关键术语是squash或filter-branch。您只需要先进行备份。
最重要的是,您要求在GitExtensions中做一件非常具体的事情。它不这样做。事实上,它并没有做很多事情......这就是为什么它甚至给你一个命令行按钮。
你会需要它。你需要命令行调整。如果您对此感到不自在,那么您就不走运了。我知道没有 git gui 工具可以为你完成这项工作。
在 op 对他的真实意图发表新评论之前,下面只是我之前(现在是遗产)答案的一部分。
如果不是这样,我们假设有充分的理由“获取代码、分支并部分推送”。然后,您所要做的就是按照马克的指示,就在另一个答案中。
或者,我们假设它是用于备份的。那么,这是一个不好的方法。相反,获取备份工具并使用它。就这么简单。GIT 不是用来备份的,也不应该用于备份,尽管有很多尝试。我强烈建议使用CrashPlan甚至Dropbox(我的推荐链接)。
有一种git checkout --orphan
方法可以创建一个可以以类似方式使用的独立分支,可以节省一些击键。
显然(?),正如其他人所暗示的那样,如果您选择历史的简单线性部分作为基线,事情会更简单。
一种可能的解决方案是使用过滤器分支查询来隔离其自己的存储库中的相关提交(一个月或更短)。
但这意味着推送到一个新的仓库,而不是在现有的仓库中推送一个新的分支。
除非你创建一个不相交的分支(一个新的根提交),没有共同的历史。请参阅“将旧版本的代码添加到 git repo ”。
在这种情况下,您确实会根据结果推送一个新分支filter-branch
(用于拆分回购历史并隔离您想要的更改)。