Skip to content

Commit c37043c

Browse files
committed
Interesting rebases, tightened
Also mentioned `git pull --rebase` and `pull.rebase`.
1 parent 6ee2f73 commit c37043c

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

en/book/03-git-branching/chapter3.asc

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -677,9 +677,8 @@ Suppose you decide that you want to merge your client-side changes into your mai
677677
$ git rebase --onto master server client
678678
----
679679

680-
This basically says, ``Check out the client branch, figure out the patches from the common ancestor of the `client` and `server` branches, and then replay them onto `master`.'' It’s a bit complex; but the result, shown in <<rbdiag_f>>, is pretty cool.
680+
This basically says, ``Check out the client branch, figure out the patches from the common ancestor of the `client` and `server` branches, and then replay them onto `master`.'' It’s a bit complex, but the result is pretty cool.
681681

682-
[[rbdiag_f]]
683682
.Rebasing a topic branch off another topic branch
684683
image::images/18333fig0332-tn.png[Rebasing a topic branch off another topic branch.]
685684

@@ -738,15 +737,13 @@ If you follow that guideline, you’ll be fine. If you don’t, people will hate
738737

739738
When you rebase stuff, you’re abandoning existing commits and creating new ones that are similar but different. If you push commits somewhere and others pull them down and base work on them, and then you rewrite those commits with `git rebase` and push them up again, your collaborators will have to re-merge their work and things will get messy when you try to pull their work back into yours.
740739

741-
Let’s look at an example of how rebasing work that you’ve made public can cause problems. Suppose you clone from a central server and then do some work off that. Your commit history looks like <<rbdiag_j>>.
740+
Let’s look at an example of how rebasing work that you’ve made public can cause problems. Suppose you clone from a central server and then do some work off that. Your commit history looks like this:
742741

743-
[[rbdiag_j]]
744742
.Clone a repository, and base some work on it
745743
image::images/18333fig0336-tn.png[Clone a repository, and base some work on it.]
746744

747-
Now, someone else does more work that includes a merge, and pushes that work to the central server. You fetch them and merge the new remote branch into your work, making your history look something like <<rbdiag_k>>.
745+
Now, someone else does more work that includes a merge, and pushes that work to the central server. You fetch them and merge the new remote branch into your work, making your history look something like this:
748746

749-
[[rbdiag_k]]
750747
.Fetch more commits, and merge them into your work
751748
image::images/18333fig0337-tn.png[Fetch more commits, and merge them into your work.]
752749

@@ -755,14 +752,28 @@ Next, the person who pushed the merged work decides to go back and rebase their
755752
.Someone pushes rebased commits, abandoning commits you’ve based your work on
756753
image::images/18333fig0338-tn.png[Someone pushes rebased commits, abandoning commits you’ve based your work on.]
757754

758-
At this point, you have to merge this work in again, even though you’ve already done so. Rebasing changes the SHA-1 hashes of these commits so to Git they look like new commits, when in fact you already have the C4 work in your history.
755+
Now you're both in a pickle.
756+
If you do a `git pull`, you'll create a merge commit which includes both lines of history, and your repository will look like this:
759757

760758
.You merge in the same work again into a new merge commit
761759
image::images/18333fig0339-tn.png[You merge in the same work again into a new merge commit.]
762760

763-
You have to merge that work in at some point so you can keep up with the other developer in the future. After you do that, your commit history will contain both the C4 and C4' commits, which have different SHA-1 hashes but introduce the same work and have the same commit message. If you run a `git log` when your history looks like this, you’ll see two commits that have the same author date and message, which will be confusing. Furthermore, if you push this history back up to the server, you’ll reintroduce all those rebased commits to the central server, which can further confuse people.
761+
If you run a `git log` when your history looks like this, you’ll see two commits that have the same author, date, and message, which will be confusing.
762+
Furthermore, if you push this history back up to the server, you’ll reintroduce all those rebased commits to the central server, which can further confuse people.
763+
It's pretty safe to assume that the other developer doesn't want C4 and C6 to be in the history; that's why she rebased in the first place.
764+
765+
Fortunately, Git has a feature to make this easier.
766+
If you use the `--rebase` flag to `git pull`, Git will do a fetch (which updates the remote branch to C4') followed by a _rebase_, rather than a merge.
767+
This is exactly what you want; your local commits will follow the new remote commits in a straight line, and the abandoned commits will stay lost.
768+
769+
In fact, this functionality is so useful, that you can make that flag the default; simply do `git config --global pull.rebase true`.
770+
This will do a tiny rebase every time you type `git pull`, effectively making the `--rebase` flag the default.
771+
If your workflow includes making local merges, set this configuration value to `preserve` rather than `true`, and `git pull` won't flatten your merge commits.
764772

765773
If you treat rebasing as a way to clean up and work with commits before you push them, and if you only rebase commits that have never been available publicly, then you’ll be fine. 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.
774+
So don't do it.
775+
776+
But if you do, tell everyone who's working on that branch to `git pull --rebase`.
766777

767778
==== Rebase vs. Merge
768779

0 commit comments

Comments
 (0)