我们的团队正在用PHP做几个项目。我们错误地将一个项目的文件夹提交给了另一个项目。现在,我们想从项目中删除特定的提交。如果我们从项目中删除特定的文件夹/提交,那么我们的项目就没有问题了。
如果我们只是删除文件夹并在当前位置发出新的commit,那么文件夹会被删除,但它会保留在Git的历史记录中。所以,我们希望将它从refs,历史记录和Git的其他内容中完全删除。
我们也可以创建一个单独的分支,但是作者的提交引用会丢失。我们只想删除那个特定的提交。我们在重写历史或重新建立基础方面没有问题,但不知道如何做到这一点。
在项目中,我们已经完成了136次提交,并希望删除第76次提交。
5d39775b //136th commit
a4df5ee9 //135th commit
6971cf35 //134th commit
.....
....
162f833c //76th commit
32603274 //75th commit
.....
....
9770059 //1st commit
7条答案
按热度按时间uqjltbpv1#
在master分支中,您可以交互式地变基:
这将在违规提交之前的提交的基础上进行重定。现在只需从列表中删除违规提交,保存并退出编辑器(*nix平台中的默认值是vi)。
这将使你的分支在有问题的提交之前的提交之上重新定基,而没有它,这似乎是你试图实现的。
yhuiod9q2#
我已经尝试了所有提供的方法,即rebase和cherry-pick。我在这里提供有关尝试的方法和我所做的事情的完整信息,以帮助更好地了解事情
准备工作
为了检查我做了哪些最好的事情:
1.首先,我们使用Git Repo的干净副本。通常,每当我们存储或做其他事情时,Git也会存储在本地Git数据库中。因此,该Git数据库没有任何本地或临时内容。
1.我已经计算了文件夹. git占用的总字节数。由于repo是干净的,所以这里的最小字节数是正确的。为了更深入地了解,我已经记下了磁盘上占用的字节数和字节数。因为两者是不同的东西,它们是:
1.如果你使用的是Windows并且安装了任何防病毒软件,那么你必须禁用Active/真实的time模式。Git需要快速访问I/O文件检查。当Git创建文件时,会发生什么?Active模式锁定新的Created文件以检查病毒,当Git试图重新访问时,由于防病毒软件锁定而失败。如果失败,你必须从1重新启动进程。
方法一- Rebase
在re-based方法中,可以通过两种方式来实现。一种是通过--onto,另一种是使用-i。
-i方法
我使用了以下命令:
它打开了vim编辑器,我看到了从162 f833 c开始而不是从master开始的提交列表。
我删除了一行,这样提交就会丢失,保存文件并退出编辑器,当我退出时,它开始重新设置为显示:
然后试图检查日志,看看提交是否丢失,在日志中我找不到我要删除的提交。意味着成功完成了命令。我试图检查状态为:
因为提交被删除了,但是在它所派生的远程上需要被推送。所以,强制推送提交以覆盖先前的代码。
之后,我删除了本地repo,并重新获取了repo和它显示的大小:
--onto方法
在浏览了许多博客和手册后,我发现了一个博客here,它让我真正知道如何使用它。所以我使用的命令是:
输出为:
然后试图检查日志,看看提交是否丢失,在日志中我找不到我要删除的提交。意味着成功完成了命令。我试图检查状态为:
因此,与单一的命令,所有的事情都做了,然后我做了一个强制推动检查字节等,因为前面
之后,我删除了本地repo,并重新获取了repo和它显示的大小:
将-i VS --转换为
因此,在执行rebase方法之后。我真的很赞成--onto方法来删除中间的提交,因为它是单个命令,而且字节数也比-i方法略高。真正的好处是我们不必在--onto方法中做额外的事情。
方法二- Cherry-pick
Cherry-pick非常好的方法,但是要运行许多命令,在运行命令时必须小心。
它向我展示了repo的日志,因为我们需要一次又一次地查看它。从这个repo中识别出你想要删除的提交,并复制SHA Key,最后一个好的提交意味着识别出我们不想改变任何事情的提交。所以,下一个命令是
生成的输出:
所以,到上次Good commit为止,我们已经创建了一个新的分支。所以,到上次Good commit为止的事情没有改变。我再次运行以下命令来查看所有的good commit:
我已经删除了世界--所有的作为,我想查看提交的分支修复只.因为它显示了我良好的提交到正确标记.现在,下一个命令是要谨慎使用,因为它是包括坏的提交作为起点和终点最后一次提交完成,它将是:
输出:
这个命令的作用是重新提交所有提交,从上面提供的第一次提交(162 f833)到最后一次提交(5d39775)。因此,sha commits值将相应地改变,因为它一个接一个地重新提交。现在是时候查看日志了:
输出为:
所以,查看图让我们知道,它已经重新提交了所有的提交,除了坏的提交。显示你所有的旧的sha键与新的键。如果一切都是正确的,我们必须使修复分支作为主分支,并删除主分支:
并输出为:
首先 checkout master分支,这样我们就可以覆盖master分支上的更改。然后
并输出为:
它会丢弃好的提交后的提交,现在我们必须将修复分支与master合并:
并输出为:
现在,如果你查看日志,它不会显示错误的提交,所有的事情都已经完成了。
之后,我删除了本地repo,并重新获取了repo和它显示的大小:
命令排序
重定基数--到[第一个]
Cherry Pick [第二张]
Rebase -i [第三个]
我想优先给予git rebase --onto命令,因为它可以轻松地用单个命令完成任务。
mjqavswn3#
可以使用交互式变基。
因为你想删除的提交有sha1 162f833c,那么就执行
git rebase -i 162f833c^
一个文本编辑器将打开一个提交列表。只需删除与您想要删除、保存和关闭的提交相对应的行。
作为一个安全网,当我做这类事情的时候,我喜欢先在我的HEAD上放一个标签,这样如果出了问题,我就可以 checkout 这个标签并检索我的初始状态。
inb24sb24#
您可以通过以下方式自动删除提交并重写历史(其中
${ref_to_delete}
是您要删除的提交,并假设master
是它所在的分支):如果使用远程仓库,则必须使用
-f
执行push
:fkvaft9z5#
你也可以使用
git cherry-pick
来实现:git rebase
可能更好,所以至少我展示了在git中通常有多种方法。毕竟,rebase是如此强大,以至于“git中所有有意义的操作都可以用rebase命令来表达”(Linus Torvalds)。b91juud36#
git rebase -i 32603274..这将显示一个巨大的提交列表。
pick 162f833c .. pick ...
将第一次提交更改为d 162 f833 c..
保存它
这将仅丢弃第76次提交
knpiaxh17#
有些仓库会被管理员保护,以防止更改历史记录,就像我的例子一样,为此我不得不使用git revert
git revert 162f833c
这也更安全,因为如果你想把它带回来,你仍然有错误的提交。如果你想把它带回来,你只需要做:
git cherry-pick 162f833c