4 ms·
I understand why --rebase isn't the default, but in the overwhelming majority of cases, you want to --rebase when pulling. I always tell newbies that they shou
by knowtheory 16y ago
I understand why --rebase isn't the default, but in the overwhelming majority of cases, you want to --rebase when pulling. I always tell newbies that they should default to --rebasing.
- acqq 16y agoWhy isn't --rebase default? Can anybody explain what it actually does and why it's not default, man pages are not clear to me? Every thing is explained by referring to a bunch of other things and there's not a trace of a simple explanation.
- kemiller 16y agoI can't comment on the motivations of the maintainers, but in my experience normal merges can handle more conflicts cases smoothly than rebase. Rebase is also controversial because technically it's rewriting history. I think for the special case of pulling from remote, though, that the tradeoffs are often worth it, but nevertheless, merge is the safer default.
- knowtheory 16y agoNot all history is sacrosanct. REMOTE history is absolutely sacrosanct (A remote being any repository that someone is going to pull from), but you can do whatever you like with your local repository, so long as you only push from it.
- acqq 16y agoOK, but I believe remote repo is there only to be pushed to, so then is there any example of benefit of pull without --rebase if the pull is anyway only done locally? http://progit.org/book/ch3-6.html http://progit.org/book/ch3-6.html Says " If you rebase commits that have already been pushed publicly, and people may have based work on those commits, then you may be in for some frustrating trouble." but not how that can happen at all, provided you always "pull --rebase" and then "push", and if that can happen at all, then what to do.
- kemiller 16y agoSacrosanct? No. But still useful. With a real merge, you get a special commit that summarizes what had to be done to complete the merge. That can come in handy, especially with the sort of bugs that creep in during merges. Rebase will actually change your original commit, which obscures the original intent of the commit and hides the merge. In those cases I'd rather have a slightly messier history but more information about what really happened.
- knowtheory 16y agoOkay, so you have to think about repository state in order to understand rebasing. You share some common history with your remote repository (for the sake of argument lets assume you've got a single remote repo that you and your friends push to). When you make changes and commit them locally, what you're doing is adding new commit nodes to the history tree of your local repository. When you push to the remote repo, the chain/branch of commit nodes from your local repository gets added on to the remote repository's history. BUT, if, while you were working and committing, someone else adds commits to the remote repository... There is now new history in the remote repository that you do not share. What rebasing does, is say "take all the commit nodes from my local branch (remember them), and rewind the history back to the point where my repository was in synch with the remote repository. THEN update my repository with the remote changes, and try and apply all my local commits on top of my newly synched tree." TL;DR: if your commit tree looks like this (where 'H' are commits which you share with the remote repository. 'L' are local commits and 'R' are new commits to the remote repo, which you don't have): H-H-H-H-H-L-L-L-L Your friend pushes his changes so the remote repository now looks like H-H-H-H-H-R-R-R-R Rebasing does this: 1) H-H-H-H-H [snip] L-L-L-L 2) H-H-H-H-H << R-R-R-R 3) H-H-H-H-H-R-R-R-R << L-L-L-L If there are conflicts, Git steps through each of your commits and lets you fix the problems and merge. If there are no conflicts, it just seamlessly merges.
- acqq 16y agoThanks knowtheory, that's exactly what I wanted to read, that git pull --rebase is "take all the commit nodes from my local branch (remember them), and rewind the history back to the point where my repository was in synch with the remote repository. THEN update my repository with the remote changes, and try and apply all my local commits on top of my newly synched tree."" Now what's "git pull" explained in the same terms? Is it "produce errors as if remote were in sync with local even if it's obvious it isn't"? Who needs that? If it's not, then what is a proper description? And is there any scenario in which remote was changed, you want to push there your changes and you wouldn't want "git pull --rebase"? Thanks!
- lincolnq 16y ago"Normal" git development (without rebasing) naturally creates a branching history when two people make changes based off a common root. As was explained above, rebasing causes this branching history to be rewritten into a linear one. The alternative is merging, where you cause Git to record what actually happened -- which is that two changes occurred simultaneously and you explicitly brought them in sync again. Sometimes (often) this is what you want -- it's especially useful for longer-lived branches of work, where having the history of the branch can be valuable in itself. Also, if you share a commit with someone, you can no longer safely rebase it! The reason is that part of the definition of a commit is its set of parents -- the commits it depends on (usually 1, but can be 2 or more for a merge commit). When you rebase, you are rewriting all the parents, so you end up creating a whole stream of new commits and discarding the old ones. If you then attempt to share history with someone who has the old ones, presumably Git will become confused. (I've never actually run into this problem, but I don't use rebasing much.)