How to explain “git pull --rebase” in simple terms?

筅森魡賤 提交于 2019-12-04 04:11:43

I see two things that could be clarified: You are focusing on the state of a file in the two branches, but a better way to consider what is going on is in terms of the changesets that have occurred. The second issue is that git pull is shorthand for two operations: git fetch, and git merge. Yes, you write that you "don't want to use words like fetch", but that's not an "advanced concept". If you want to understand what's going on, you need to start there.

  • git fetch essentially informs the local repo of changes that it did not know about.

  • git merge unifies the newly arrived changes with your local changes.

The catch is that if things have been happening on both repos without synchronization, they may have diverged:

... b--o--o--o--o  (remote)
     \
      x--x--x      (local)

The above shows time left to right; the rightmost point is the most recent. So the newly arrived changes are modifications to an older state of the files, the one marked "b".

  • git pull, i.e. plain git merge, will merge the most recent state of the two branches as best as it can.

  • git pull --rebase will pretend that your changes were made not to the state marked "b", but to the most current remote state. In other words it will try to rewrite history so that it looks like this:

    ... b--o--o--o--o              (remote)
                     \
                      x--x--x      (local)
    

That's the difference. One consequence is that if you don't rebase, the history of your repo contains some states (which you can rewind to in the future, if you want) where the "x" changes were applied but the "o" changes are absent. After rebasing, there is no such place in the repository.

Simple: as long as your work is local (meaning it has not been pushed), a git pull --rebase will serve to replay your local work on top of an updated history.

git fetch will update said history with the latest commits of the remote repo (origin/master for instance).
Then your work (your local commits of your master branch) will be replayed one by one (which is what a rebase does) on top of that updated history.

The idea is that, when you want to push, said push will be very simple, and will need no merge, since your commits are simply new commits done on top of origin/master.

Note that you can hide that rebase part entirely since Git 2.6:

git config pull.rebase true
git config rebase.autoStash true

And even if the rebase does not goes well and you have to abort, Git will restore the stashed current work for you since Git 2.10.

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