我们的团队正在用PHP完成几个项目.我们错误地将One Project的文件夹提交给另一个.现在,我们要从项目中删除该特定提交.如果我们从项目中删除特定的文件夹/提交,那么我们的项目就没有问题.
如果我们只删除文件夹并在当前位置发出新提交,则该文件夹将被删除,但它将保留在Git的历史记录中.因此,我们希望将它从参考,历史和Git中的其他东西中完全删除.
我们也可以创建一个单独的分支,但作者的提交引用将丢失.我们只想删除该特定提交.我们在重写历史记录或重新编写历史记录方面没有任何问题,但不知道如何去做.
在项目中,我们已完成136次提交,并希望删除第76次提交.有关SHA的必要信息如下
5d39775b //136th commit a4df5ee9 //135th commit 6971cf35 //134th commit ..... .... 162f833c //76th commit 32603274 //75th commit ..... .... 9770059 //1st commit
Mureinik.. 22
在您的主分支中,您可以以交互方式重新绑定:
git rebase -i 162f833c^
在违规提交之前,这将在提交时返回顶部.现在只需从列表中删除违规提交,保存并存在编辑器(*nix平台中的默认值为vi).
这将在有问题的那个之前将你的分支重新设置在提交之前,没有它,这似乎是你想要实现的.
我已经尝试了所有提供的方法,例如rebase和cherry-pick.我在这里提供有关我尝试的方法和我所做的事情的完整信息,以帮助理解更好的视图
要检查哪个是最好的,我做了以下事情:
分叉远程仓库,使原件完好无损,并且可以轻松理解.因此,在确定所做的事情是否正确之前,不要做任何原始回购.
首先拍摄了Git Repo的干净副本.通常,每当我们藏匿或做其他也存储在Git中的东西作为本地Git数据库.所以,那个Git数据库没有任何本地或临时的东西.
我已经计算了文件夹.git占用的总字节数.由于repo是干净的,所以这里的最小字节是正确的.为了更进一步深入,我已经记下了所采取的字节和磁盘上的咬合.由于两者都是不同的东西,它们是:
字节 - 7,963,769和磁盘大小 - 8,028,160
如果您使用的是Windows并安装了任何防病毒软件,则必须禁用活动/实时模式.做事情时,Git需要快速访问i/o文件检查.当Git创建文件时会发生什么,活动模式锁定新的Created用于检查病毒,当Git尝试重新访问时由于Antivirus锁定而失败.如果失败,您将从1开始重新开始您的流程.
在重新基础方法中可以通过两种方式完成.一个是通过--onto,另一个是-i.
我使用以下命令:
git rebase -i 162f833c^
它打开了vim编辑器,我看到从162f833c开始的提交列表不是来自master.如果结尾提供以下行.
# Rebase 3260327..5d39775 onto 3260327 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
我删除了一行,以便提交将丢失并保存文件并退出编辑器,当我退出时,它开始重新显示为:
Rebasing ( 1/64) ..(2/64) Successfully rebased and updated refs/heads/master.
然后尝试检查日志以查看提交是否丢失,并且在日志中我找不到要删除的提交.表示成功完成命令.我试图将状态检查为:
# On branch master # Your branch and 'origin/master' have diverged, # and have 64 and 65 different commit(s) each, respectively.
由于提交被删除,但是在需要推送它的远程数据库中.因此,使用force推送提交以覆盖早期的代码.
git push -f
之后,我删除了本地仓库并重新获取了回购及其显示的大小:
bytes 6,831,765 bytes size on disk 6,897,664 bytes
经过许多博客和手册后,我在这里找到了1个博客,它真的让我知道如何使用它.所以我使用的命令是:
git rebase --onto 3260327 79504a5~1
而且输出是:
First, rewinding head to replay your work on top of it... Applying: 77th Message Applying: 78th Message Applying: 79th Message .... Last commit
然后尝试检查日志以查看提交是否丢失,并且在日志中我找不到要删除的提交.表示成功完成命令.我试图将状态检查为:
# On branch master # Your branch and 'origin/master' have diverged, # and have 64 and 65 different commit(s) each, respectively.
因此,使用单个命令完成所有事情,然后我做了一个强制推送来检查字节等,如前所述
git push -f
之后,我删除了本地仓库并重新获取了回购及其显示的大小:
bytes - 6,831,389 size on disk - 6,893,568
因此,做了rebase方法之后.我真的批准了--onto方法来删除之间的提交,因为它是单个命令,并且字节也比-i方法略高一些.真正的优势是我们不必在--onto方法中做更多的事情.
Cherry-pick非常好的方法,但运行许多命令,你必须小心谨慎运行命令.首先,我必须创建一个单独的日志文件
git log --all --decorate --oneline --graph > 1
这向我展示了回购日志,因为我们需要一次又一次地查看它.从此repo中识别您要删除的提交,并将SHA Key复制到最后一个良好的提交意义,从而识别我们不想更改任何内容的提交.那么,下一个命令就是
git checkout 3260327 -b repair
生成输出:
Switched to a new branch 'repair'
所以,直到最后一次Good commit我们创建了一个新的分支.因此,持续良好提交的事情不会改变.我再次运行以下命令来查看所有好的提交:
git log --decorate --oneline --graph > 2
我删除了世界 - 所以,我只想查看分支修复的提交.因为它向我展示了Good Commits,正确标记.现在,谨慎使用下一个命令,因为它包含了错误的提交作为最后一次提交的起点和终点,它将如下:
git cherry-pick 162f833..5d39775
输出:
[repair 9ed3f18] xxxxxx x files changed, xxx insertions(+), xx deletions(-) [repair 7f06d73] xxxxx xx files changed, xxx insertions(+), xx deletions(-) ..... ...
这个命令做了什么,它重新提交所有提交的离开第一次提交,即(162f833)到最后提交(5d39775)提供.因此,sha commit的值会相应地改变,因为它将一个接一个地重新提交.现在是时候查看日志:
git log --all --decorate --oneline --graph > 3
输出为:
* f61a9a5 (HEAD, repair) xxxxxx * 25be3b9 xxxxx * 49be029 xxxxx ....... ....... | * 5d39775 (origin/master, origin/HEAD, master) | * a4df5ee xxxxx | * 6971cf3 xxxxxx | ....... | ....... | * 162f833 xxxx |/ * 3260327 xxxxx ...... * 9770059 xxxxx
因此,查看图表让我们知道它已经重新提交除了错误提交之外的所有提交.用新键显示所有旧的sha键.如果一切都好,我们必须将修复分支作为主分区并删除主分支:
git checkout master
并输出为:
Switched to branch 'master'
首先检查主分支,以便我们可以在主分支上进行更改.然后
git reset --hard 3260327
并输出为:
HEAD is now at 3260327 xxxxx
它将在良好提交后丢弃提交,现在我们必须将修复分支与master合并:
git merge repair
并输出为:
Updating 3260327..40d290d Fast-forward
现在,如果您查看日志,它将不会向您显示错误提交,并且每件事都已完成.我做了一个强制推送来检查字节等,如前所述
git push -f
之后,我删除了本地仓库并重新获取了回购及其显示的大小:
bytes - 6,831,556 size on disk - 6,897,664
Rebase --onto [首页]
bytes - 6,831,389 size on disk - 6,893,568
Cherry Pick [第二名]
bytes - 6,831,556 size on disk - 6,897,664
Rebase -i [第三]
bytes 6,831,765 bytes size on disk 6,897,664 bytes
我想优先考虑git rebase --onto命令,因为事情很容易用单一命令完成.
在您的主分支中,您可以以交互方式重新绑定:
git rebase -i 162f833c^
在违规提交之前,这将在提交时返回顶部.现在只需从列表中删除违规提交,保存并存在编辑器(*nix平台中的默认值为vi).
这将在有问题的那个之前将你的分支重新设置在提交之前,没有它,这似乎是你想要实现的.