git - 仅保留最后三个 git 提交。完全删除其他所有内容

标签 git

下面是 git 历史树,其中突出显示了我想要保留的三个提交。我怎样才能让其他一切都消失,就好像它们从未存在过一样?

Branches and merges and sh*t

我尝试使用 here 中的答案但我不断收到以下信息:

fatal: Needed a single revision
Does not point to a valid commit: e147db0477dbb21e74615f4bfff06378b7d269c8^

最佳答案

三个突出显示的提交中的第一个是 merge 。如果你保留它,你必须(实际上,这不是一个选项)保留你不想要的 5 个提交。 (浅克隆可以忽略它们,直到加深,但它们在逻辑上仍然存在,即使不是物理上的。)

因此,您需要做的是进行一个新的提交,您可以指向 masterorigin/master ,这与 merge “一样好”,但它本身并不是 merge ,并且只是将三个提交保留的中间作为其父级。

“清理”和“前端完善”提交可以保持原样;他们只需要一个指向他们的新提交,该提交使用相同的作为 merge 。 (你也可以保留原来的提交消息,或者创建一个新的。)Git 就是 git,有很多方法可以实现这一点。最少命令的方法是使用 git commit-tree 1但是让我们看一个我认为更直接、更容易理解的方法。

首先,我们首先创建一个新分支,指向第二个要保留的提交,即“前端完善”分支。 (这也假设当前工作树是干净的。)

$ git branch newmaster master^2   # master^ if 1st parent 
$ git checkout newmaster

现在我们想要使用与 merge 一起存储的源树来进行新的提交,这本身并不是 merge 。我们首先清除所有内容(以便在 merge 期间删除的所有文件在完成后仍保持删除状态 - 如果您确定没有删除任何内容,则可以跳过此步骤)。然后,我们检查与 master 上最新提交相关的所有文件。 ,即 merge 结果。这假设您位于顶级目录:

$ git rm -r .               # empties work-tree and index
$ git checkout master -- .  # repopulates work-tree and index

这种形式的checkout从给定的提交( master 的最尖端提交)中提取给定的路径 - 在本例中为 . ,这是存储库的顶层,因此包含提交中的每个路径。每个提取的文件在提取过程中也会输入到索引中,因此我们现在已经准备好新的提交了。

唯一剩下要做的就是恢复 merge 的消息(如果需要):

$ git log -1 master > /tmp/msg

(或类似的),然后:

$ git commit

这在 newmaster 上进行了新的提交,其父级是“前端抛光”提交,其父级是“清理”,没有更多父级。现在你只需要把它设为分支 master ,这非常简单:

$ git branch -D master   # forcibly discard old master entirely
$ git branch -m master   # rename newmaster to master

此时您可以强制推送到 origin替换master在服务器上(但要确保共享服务器版本的其他人都同意这一点,并且没有新的提交需要担心)。当服务器的 master已更新,您的origin/master (从服务器复制回来)将指向您的 master再次(此时您可以像往常一样将您的 master 的上游设置为 origin/master)。


作为引用,这只需要 2 到 4 个 git 命令,具体取决于您想要保留多少、您想要从头开始编写多少以及您如何在此处计算命令:

$ git log -1 --format=%B master > /tmp/logmsg

(现在根据需要编辑/tmp/logmsg)

$ newid=$(git commit-tree -p master^{tree} < /tmp/logmsg)

(此时,请确保它有效,例如 git show $newid )

$ git update-ref -m "reset to new non-merge tip" master $newid

(现在 master 指向只有一个父级的新复制提交)。

关于git - 仅保留最后三个 git 提交。完全删除其他所有内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33622518/

相关文章:

Git merge : is it possible to avoid auto-merge for non fast-forwarded files?

angular - 没有 npm 更新 Angular 10 的 git 新分支

Windows 版 Git - 无法克隆存储库

git - 我如何正确地可视化我的 git 仓库?

java - maven 版本 :prepare for Spring Boot 2. 3.1.RELEASE 的问题

git - 将完整的 GIT 引用转换为明确的短引用

git - Git Bash 中的西里尔字母

git - 在 Git 中不断提示输入 SSH 密码

git - 是否有可能 'git diff' 2 个字符串?

git - 如何删除 SSH key ?