简体   繁体   English

多少个提交将“ git恢复” <commit_id - SHA code> 在两种情况下删除

[英]How many commits will "git revert <commit_id - SHA code> remove in the 2 scenarios

I have a doubt regarding "git revert" 我对“ git恢复”有疑问

There is no internet connection. 没有互联网连接。 I have made 4 commits by the time the internet connection arrives. 到互联网连接到达时,我已经提交了4次提交。 Then the internet connection arrives. 然后,互联网连接到达。 I have to pull before I push. 我必须先拉才行。 So I pull and it causes Auto merge to happen(without any conflicts). 所以我拉,它会导致自动合并发生(没有任何冲突)。 This merge is created as another (5th commit) Finally I push all the "FIVE" commits on gitlab. 这个合并被创建为另一个(第5次提交)。最后,我将所有“五个”提交推送到gitlab上。

If my manager does "git revert <5th commit SHA>, will all changes from my first commit to the 5th commit go away? If yes, then why? If no, then how many commits will not be there on gitlab when someone else pulls ? 如果我的经理执行了“ git revert <第5次提交SHA>,从我第一次提交到第5次提交的所有更改都将消失吗?如果是,那么为什么?如果不是,那么当其他人拉动时,gitlab上将不存在多少次提交” ?

Note- everything is happening on the Main branch. 注意-一切都在Main分支上进行。 No secondary branches are created here. 此处未创建二级分支。

There are some things you (or your manager) need to understand about revert . 您(或您的经理)需要了解一些有关revert

First, it doesn't delete commits. 首先,它不会删除提交。 It creates a new commit that undoes changes from one or more old commits. 它创建一个新的提交,以撤消对一个或多个旧提交的更改。

Second, if you want to revert a merge commit, you need to also specify which of the merge's parents you want to revert to. 其次,如果要还原合并提交,则还需要指定要将还原的合并父对象。 This matters because your "5th" commit is a merge. 这很重要,因为您的“第5次”提交是合并。

Lastly, if you do revert a merge, it will be hard to re-introduce the undone changes later. 最后,如果您确实还原了合并,则以后很难重新引入撤消的更改。 The documentation states that you are telling git that you will never want the reverted side of the merge. 文档指出您正在告诉git,您将永远不需要合并的还原面。

So what you have after your push is 因此,您的推动力就是

x --- x --- x --- A --- B --- C --- D --- M
             \                          /
               o --- o --- o --- o --- O

The x s are commits you (and the remote) had before you started work. x s是您(和远程用户)开始工作之前所提交的内容。

The o s and O are commits that appeared on the remote while you were "off line". o s和O是在您“脱机”时出现在远程计算机上的提交。

A through D are your commits. AD是您的提交。

M is the merge created by git when you pull ed. M是您pull ed时git创建的合并。 This merge considers D to be parent 1, and O to be parent 2. 此合并将D视为父1,将O视为父2。

Now if you say 现在,如果你说

git revert -m 1 <SHA-of-M> 

this says "revert M to D ". 这说“将M还原为D ”。 That would effectively undo all the o commits as well as O . 这将有效地撤消所有o提交以及O On the other hand, 另一方面,

git revert -m 2 <SHA-of-M>

this says "revert M to O ". 这说“将M还原为O ”。 That would effectively undo A , B , C , and D . 这将有效撤消ABCD

But again, this does not delete commits . 但是同样,这不会删除commits It also does not remove commits from branch history . 它还不会从分支历史记录中删除提交 The result would be 结果将是

x --- x --- x --- A --- B --- C --- D --- M --- W
             \                          /
               o --- o --- o --- o --- O

where the TREE (content) at W matches either the TREE at D or the TREE at O (depending on which -m option you specified). W处的TREE (内容)与DTREEO处的TREE匹配(取决于您指定的-m选项)。

And to reiterate: not only are all the commits from one side of the merge effectively undone, but it isn't so easy to re-do them because git considers them "accounted for" by M . 并重申:不仅有效撤消了合并一侧的所有提交,而且重新执行它们并非易事,因为git认为它们是M

If you (or your manager) are trying to remove "unnecessary commits" from history, then you have to do a history rewrite. 如果您(或您的经理)试图从历史记录中删除“不必要的提交”,则必须重写历史记录。 There are several ways to do that; 有几种方法可以做到这一点。 revert isn't one of them. revert不是其中之一。 Any history rewrite affecting commits that have been pushed has costs associated with it. 任何影响已推送的提交的历史记录重写都会产生相关的成本。 The view that merge commits are "ugly" or "unnecessary" is a matter of opinion; 合并提交是“丑陋”还是“不必要”的观点是一种见解; I question whether the cost is justified in most circumstances. 我怀疑在大多数情况下成本是否合理。 But editorializing aside: 但撇开编辑:

One procedure that would work (assuming your local master is still at M ): 一种可行的程序(假设您的本地master仍位于M ):

1) Create a temporary branch and move it to O 1)创建一个临时分支并将其移至O

git checkout master
git checkout -b o_master
git reset --hard HEAD^2

2) Move master to D 2)将master移到D

git checkout master
git reset --hard HEAD^

3) Use rebase to create a linear history 3)使用rebase创建线性历史记录

git rebase o_master master
git branch -d o_master

You may have to resolve some conflicts during the rebase; 您可能需要解决在重新设置基准时出现的一些冲突。 see the git rebase docs. 请参阅git rebase文档。

This gives the appearance of moving the commits around so you have 这样就产生了移动提交的外观,因此您可以

x --- x --- x -- o --- o --- o --- o --- O --- A' --- B' --- C' --- D'

You have some new commits ( A' through D' ); 您有一些新提交( A'D' ); each is a replacement for one of your original commits ( A through D ). 每个都替换了原始提交( AD )之一。 The code states at A' , B' , and C' are untested and may not compile or may malfunction, which could affect future debugging efforts; A'B'C'处的代码状态未经测试,可能无法编译或出现故障,这可能会影响以后的调试工作; so you should probably test them. 所以您应该测试一下。 The code state at D' should be equivalent to what you had at M before (so presumably it is tested), but this is not 100% guaranteed (for various reasons, but especially if there were conflicts to resolve) so it's best to validate (either test D' as well, or at least diff D' against the original M ). D'的代码状态应该与您之前在M处的代码状态相同(因此可能已经过测试),但这不能100%保证(由于各种原因,尤其是在有冲突要解决的情况下),因此最好进行验证(也可以测试D' ,或者至少与原始M差异D' )。

Next you would do a "force push". 接下来,您将执行“强制推送”。

git push -f

At this point, you have rewritten the remote history. 至此,您已经重写了远程历史记录。 While you still have not deleted any commits, you have removed some old commits from the master ref. 尽管您仍未删除任何提交,但已从master引用中删除了一些旧提交。 This means that all of your coworkers must update, and any work they've done (based on M ) must be rebased to D' . 这意味着您所有的同事都必须更新,并且他们所做的任何工作(基于M )都必须重新基于D' See "recovering from upstream rebase" in the git rebase docs for more details about this issue. 有关此问题的更多详细信息,请参见git rebase文档中的“从上游基础恢复”。

Technically all of the old commits still exist, but they aren't visible by default because you've taken them out of your refs' history. 从技术上讲,所有旧提交仍然存在,但是默认情况下它们是不可见的,因为您已将它们从裁判的历史中删除。 If you need them physically deleted, that's yet another multi-step procedure. 如果您需要将它们物理删除,那又是一个多步骤过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM