Git pull.rebase this is a possibly dangerous operation

不羁岁月 提交于 2019-11-26 20:38:24

问题


In the git-config documentation the information about pull.rebase:

pull.rebase

When true, rebase branches on top of the fetched branch, instead of merging the default branch from the default remote when "git pull" is run. See "branch..rebase" for setting this on a per-branch basis.

NOTE: this is a possibly dangerous operation; do not use it unless you understand the implications (see git-rebase(1) for details).

Could anybody describe in details what does "NOTE: this is a possibly dangerous operation; do not use it unless you understand the implications (see git-rebase(1) for details)" mean?


回答1:


Let's say you have these Git repositories:

  • your private repo, sitting on your work computer;
  • your public repo, you, hosted somewhere;
  • a main repo, origin, which is the main development tree.

You're working on something and made two commits A and B. You published them to your public repo. In the same time, origin has one other commit Z.

     /-A-B master, you/master
o-o-o
     \-Z origin/master

Now let's say one colleague needs your two commits to begin a new feature. He pulls your branch from your public repo and makes some commits on top of that.

          /-C-D-E colleague/master
     /-A-B master, you/master
o-o-o
     \-Z origin/master

You now want to add your two, completely tested, commits on top of origin/master. You fetch from origin and make a rebase (which is equivalent to git pull --rebase or git pull with the pull.rebase option set). That creates two new commits. You push them to your public repo and to origin. To complicate things further, let's say a new commit F is pushed to origin after that.

     /-A-B-C-D-E colleague/master
o-o-o
     \-Z-A'-B'-F master, you/master, origin/master

Now the problem is that your colleague has some work based on two "deprecated" commits, and to avoid further complications (conflicts when merging, messing up history) he must rebase his branch on top of B' (let's say he doesn't want F). You need to tell him about that, or else maybe he won't notice what you've done.

            /-C-D-E colleague/master
o-o-o-Z-A'-B'-F master, you/master, origin/master

If you didn't tell him, later he would merge his branch back into origin, and the history would look like this:

     /-A-B-C-D-E
o-o-o           \
     \-Z-A'-B'-F-M colleague/master, origin/master

You have twice the A and B commits, though with different names. The history becomes harder to read, and you will run into awful merging conflicts. And remember this example is quite simple. If there are tens of people working on the project, and origin is moving fast, the history will soon become a complete mess.

If it's only one colleague it's probably fine. But if you can't know exactly who pulled from you, you can't know who you have to warn. It's especially true in open source development.

The main rule is: don't rebase commits you've already published. If A and B were only in your private repo, rebasing is fine and is probably the best thing to do, because it makes the history simpler and meaningful. A diverging history is only meaningful when the branch has a good reason to exist (e.g. a feature branch).




回答2:


Rebase is a command that's used to rewrite your commit history, and rewriting commits causes their SHA IDs to change. Rebasing your own private commits that no one else has based their own work off of (i.e. made commits on top of) is fine.

However, you run into trouble when you rebase shared public history, because other people who have the old history that you rebased are forced to sync up or redo their commits on top of the new history (which can potentially be a difficult process), or try to resolve the old history with the new one, which will certainly produce conflicts. From the official Linux Kernel Git documentation for rebase:

Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea: anyone downstream of it is forced to manually fix their history.

Thus, you should not rebase commits unless you're sure that no one else shares those commits that you're rebasing.

That said, you should really learn to rebase though, both interactively and non-interactively, because it's the most powerful and effective tool in Git's arsenal, and if you don't know how to use it, then you're not using Git effectively.

You can learn more about rebasing from the Rewriting History section of the free online Pro Git book, and of course the official Linux Kernel Git documentation for rebase is excellent as well.




回答3:


It is worth to mention that an "evil change" from an "evil merge" can be lost silently while rebasing an "evil merge" containing an "evil change" which does not conflict with other commits.



来源:https://stackoverflow.com/questions/18137918/git-pull-rebase-this-is-a-possibly-dangerous-operation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!