简体   繁体   English

当我是唯一一个在两个相关分支上工作时,我应该使用git rebase而不是git merge

[英]Should I use git rebase instead of git merge when I am the only working on the two concerned branches

Say the rebase involves two branches A and B . 假设rebase涉及两个分支AB I am the only one making changes to those branches but there are other people who have pulled those branches just to view what's going on (reviewing). 我是唯一一个对这些分支机构进行更改的人,但还有其他人只是为了查看正在发生的事情(审查)而取消了这些分支机构。 They have not made / will not make any changes to those branches at all. 他们根本没有对这些分支进行任何修改。 Considering the pros/cons of rebase vs merge, rebasing is clearly the better option for 考虑到rebase vs merge的优缺点,变基显然是更好的选择

Now, The git document on rebase mentions the golden rule about rebasing 现在,关于rebase的git文档提到了关于变基的黄金法则

The golden rule of git rebase is to never use it on public branches. git rebase的黄金法则是永远不要在公共分支上使用它。

and explains why it can be dangerous. 并解释为什么它可能是危险的。

I understand the differences between rebase and merge and how things can go wrong in situations when there are other developers committing to the parent branch. 我理解rebase和merge之间的区别以及当其他开发人员提交到父分支时情况会出现问题。

Should I avoid this even when I am the only developer to those two branches concerned with rebasing ? 即使我是那两个关于变基的分支机构的唯一开发人员,我是否应该避免这种情况? What are the things that could go wrong after I force push after rebasing and the other team members try to pull those branches (again just to view them, they haven't made any changes)? 在重新定位之后强行推动并且其他团队成员试图拉动那些分支(再次只是为了查看它们,他们没有做出任何改变)之后会出现什么问题?

To determine whether to use rebase or merge, you first need to understand how they work. 要确定是使用rebase还是合并,首先需要了解它们的工作原理。

In git commits are chain of linked list with latter commit having reference to previous commit. 在git中, 提交是链表的链,后面的提交引用了先前的提交。

C1<-C2<-C3<-C4

When two branches merge a new merge commit is created (represented below by M1) 当两个分支合并时, 创建一个新的合并提交 (由下面的M1表示)

C1<-C2<-C3
 \        \
  \       M1
   \      /
   C4<-C5

which has reference for commits which are merging. 其中包含正在合并的提交的引用。 Here history is no more a linked list . 历史不再是一个链表 It has become a directed acyclic graph. 它已成为有向无环图。

Rebase works in a bit different way Rebase以不同的方式工作

C1<-C2<-C3 branch1
  \  
       C4<-C5 branch2

#On branch2
git rebase branch1

  C1<-C2<-C3<-C4'<-C5'

Rebase has created two new commits C4' and C5' instead of C4 and C5 and moved branch pointer to C5'. Rebase 创建了两个新的提交C4'和C5'而不是C4和C5,并将分支指针移动到C5'。 Here history is clean linked list (as your branch commits are recreated and applied over to branch with which rebase is done), but two new commits are created, means history changed for branch2 (earlier which was C1<-C4<-C5). 这里的历史记录是干净的链表 (因为你的分支提交被重新创建并应用到完成了rebase的分支),但是创建了两个新的提交,意味着为branch2更改了历史 (之前是C1 <-C4 <-C5)。 So you have to do force push every time you do a rebase. 因此,每次进行变形时都必须强制推动。

Now to answer your question: 现在回答你的问题:

  1. Should I avoid this even when I am the only developer to those two branches concerned with rebasing? 即使我是那两个关于变基的分支机构的唯一开发人员,我是否应该避免这种情况? In best practice it is always good to rebase your feature branch with parent branch and then merge your feature branch into parent branch , as feature branch is your own branch but parent branch will have other developers commits as well, which can get lost if you rebase your parent branch with feature branch without taking pull from remote. 在最佳实践中,最好使用父分支重新定义您的功能分支,然后将您的功能分支合并到父分支 ,因为功能分支是您自己的分支,但父分支也会有其他开发人员提交,如果您重新设置,这可能会丢失你的父分支与功能分支没有从远程拉。

  2. What are the things that could go wrong after I force push after rebasing and the other team members try to pull those brances? 在重新定位之后强行推动并且其他团队成员试图拉动那些不同的东西后,可能会出现什么问题? It will go pretty bad as force push, push whatever history you have on your local system to remote . 随着强制推动它会变得非常糟糕, 将您在本地系统上的任何历史记录推送到远程 If you don't use force push then your push will get rejected incase of mismatched history and commit transition and you will be asked to take the pull. 如果你不使用强制推送,那么你的推送将被拒绝,因为历史不匹配并提交转换,你将被要求采取拉动。 Also if you have force pushed on parent branch which had some other developers commit and same was not pulled on your local machine, then that commit is lost. 此外,如果您在父分支上强制推送其他开发人员提交并且未在本地计算机上提取,则该提交将丢失。

If other developer tries to pull from remote, he will get a tree conflict as his local history will not mach with remote. 如果其他开发人员试图从远程进行拉取,他将会遇到树冲突,因为他的本地历史记录不会远程使用。

A problem could arise when the reviewers pull your code. 当审阅者提取您的代码时,可能会出现问题。

Git will fetch the rebased commits and try to merge it with reviewer's branch. Git将获取重新提交的提交并尝试将其与审阅者的分支合并。

This will either create a merge commit - if everything goes well or it will lead to a merge conflict. 这将创建一个合并提交 - 如果一切顺利或将导致合并冲突。

Because git has no way of knowing if the new commits are rebased or completely different, it will keep old pre-rebase commits and merge it with post-rebase commits. 因为git无法知道新提交是重新设置还是完全不同,所以它将保留旧的pre-rebase提交并将其与post-rebase提交合并。 In either case, the commit history on their machines will always be different from yours even if the code is the same. 在任何一种情况下,即使代码相同,其机器上的提交历史也将始终与您的不同。

There is an expanded version of your "golden rule" on rebasing: 关于变基的“黄金法则”有一个扩展版本:

The golden rule of git rebase is to never use it on public branches. git rebase的黄金法则是永远不要在公共分支上使用它。

The expanded version goes like this: Only use rebase, or other force-push type motions, on branch names where all users of that name expect the behavior that results . 扩展版本如下所示: 仅对分支名称使用rebase或其他强制推送类型的运动,其中该名称的所有用户都期望产生的行为 This is because each such user may have to take some action to recover from such an operation (an "upstream rebase"): namely, he or she may have to "rescue" his or her commits. 这是因为每个这样的用户可能必须采取一些动作来从这种操作中恢复(“上游变基”):即,他或她可能必须“拯救”他或她的提交。 If all users are prepared to do so, and know to look for such cases, they won't be surprised by the problem. 如果所有用户都准备这样做,并且知道寻找这样的情况,他们就不会对这个问题感到惊讶。

In other words, if you have a team of, say, five programmers, and all five of you agree that the "pu" ("proposed update" or "pickup" branch) gets rebased all the time, it's fine to rebase the pu branch. 换句话说,如果你有一个团队,比如五个程序员,并且你们五个人都同意“pu”(“建议的更新”或“拾取”分支)一直被重新定位,那么改变pu是没关系的。科。 If one of you is OK with rebasing "develop" but four are not , it's not OK to rebase the "develop" branch. 如果你们中的一个是与基础重建“发展”,但四个是也不行,它不是确定以变基的“开发”分支。

Since you are the sole user and developer working with A and B, it's up to you to decide whether you agree with yourself as to whether it is OK to rebase A and/or B. 由于您是唯一使用A和B的用户和开发人员,因此由您自行决定是否同意自己是否可以重新定义A和/或B.

What are the things that could go wrong after I force push after rebasing and the other team members try to pull those branches (again just to view them, they haven't made any changes)? 在重新定位之后强行推动并且其他团队成员试图拉动那些分支(再次只是为了查看它们,他们没有做出任何改变)之后会出现什么问题?

Nothing can really go "wrong". 没有什么能真正“出错”。 The worst thing that can happen is that the "viewers" will have unnecessary trouble with merging since your newly force-pushed commits may look completely different and now pulling (ie fetching and merging) them results in merge conflicts . 可能发生的最糟糕的事情是“观察者”在合并时会遇到不必要的麻烦,因为你们新推出的强制提交可能看起来完全不同,现在拉动(即获取和合并)它们会导致合并冲突

Should I avoid this even when I am the only developer to those two branches concerned with rebasing? 即使我是那两个关于变基的分支机构的唯一开发人员,我是否应该避免这种情况?

While rebasing allows you to have a tidy and linear git history and definitely has its benefits, here are some thoughts on why "merging" sometimes could be preferable over "rebasing", even though you are in "write"-control over your branches: 虽然变调允许你有一个整洁和线性的git历史并且肯定有它的好处,但这里有一些想法为什么“合并”有时可能优于“变基”,即使你在“写”控制你的分支:

1) To avoid irreversible code deletions resulting from wrong decisions during merge conflicts. 1)避免在合并冲突期间由错误决策导致的不可逆代码删除。

Example: Say you have been working on your feature branch A for two weeks and now you stop working on it and instead continue on branch B for two weeks. 示例:假设您已经在功能分支A工作了两周,现在您停止工作,而是继续在分支B工作两周。 Now after some time you feel it is time to work on branch A again and for some reason you need changes contained in B incorporated into A so you decide to rebase your branch A onto B . 现在经过一段时间后,您觉得是时候再次在分支A上工作了,由于某种原因,您需要将B包含的更改合并到A因此您决定将分支A重新绑定到B In the course of this rebase several merge conflicts arise. 在这个变革的过程中出现了几个合并冲突。 Due to poor judgement or by mere accident, you remove parts of your code in A to solve the conflics in favour of the incoming changes. 由于判断力差或仅仅出现意外,您可以删除A中的部分代码以解决有利于传入更改的冲突。 Now you continue and complete your rebase and force push your code to your remote's origin/A . 现在,您继续并完成您的rebase并强制将您的代码推送到遥控器的origin/A Suddenly you realize that you deleted parts of your code in branch A that were important and shouldn't have been deleted. 突然间,您意识到您删除了分支A中代码的部分重要且不应删除的代码。 However, since rebase rewrites history, unlike a merge, you cannot simply revert the rebase and your code is lost. 但是,由于rebase重写历史记录,与合并不同,您不能简单地还原rebase并且代码丢失。

The situation described above is especially problematic if you tell juniors in your team to always prefer rebase over merge and they accidentally delete their code by making wrong decisions in the course of merge-conflicts, especially when rebasing their branch onto the master . 如果你告诉你的团队中的小辈总是喜欢重组而不是通过在合并冲突过程中做出错误的决定来删除他们的代码,特别是在将他们的分支重新定位到master上时,上述情况尤其成问题。

Of course a solution to this problem apart from using git merge would be to make a backup branch before performing a rebase. 当然,除了使用git merge之外,解决这个问题的方法是在执行rebase之前建立备份分支。

2) To avoid solving too many conflicts while interactively rebasing. 2)避免在交互式变基时解决太多冲突。

When your feature branch contains several commits, ie you moved code around quite a bit and maybe even back and forth, then rebasing may take much longer than a merge, because a rebase will go in sequence (!) through your branch's commits one by one and stops at every conflict that is discovered. 当您的功能分支包含多个提交时,即您将代码移动了很多甚至可能来回,然后重新定位可能需要比合并更长的时间,因为rebase将按顺序 (!) 顺序通过您的分支提交并在每次发现的冲突中停止。 With a merge, you will only compare the current state, ie the HEAD , of your feature branch with the HEAD of the branch you are rebasing onto (eg the master ) and it might be that there are no conflicts at all when performing a merge while there could be some conflicts when doing a rebase. 通过合并,您只需将功能分支的当前状态(即HEAD与您要重新绑定到的分支的HEAD (例如master )进行比较,并且可能在执行合并时根本没有冲突虽然在做一个rebase时可能会有一些冲突。 So in this sense, a merge potentially saves you some time. 所以在这个意义上,合并可能会为您节省一些时间。

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

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