1

I'm reading the Pro Git book and get stuck on rebasing.

Below is the scenario:

Step 1 enter image description here

Step 2 enter image description here

We can see that the remote did a rebasing, (not a good practice, because someone else might work based on it).

Then the author says:

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:

enter image description here

I do not understand why git pull will automatically merge C4 and C7, because we know that normally git pull does not do merges for you and you have to merge by yourself, so why in this case does git pull merge for you?

Edit:

Sorry, I typed and thinked too fast,I was talking about git fetch that doesn't automatically merge, git pull does merge and git pull = git fetch + git merge.

So my question is, why the author says:

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.

I'm really confused, if the developer didn't do rebasing after the merge so we have the picture in step 1 as the beginning, , then the developer added a new commit called C8 right after C6, then if I call git pull on my computer, C8 will still need to be merged with C7, so it will have to re-merge work anyway, it cannot be avoided and things will get messy, so what's the problem with that?

  • 2
    Who says `git pull` normally doesn't do merges? That's exactly what it does. It first does a `fetch` and then a `merge`. – Jonathan Wakely Sep 25 '19 at 14:41
  • @JonathanWakely sorry I was talking about git fetch, I have edited my question, please have a look, thanks –  Sep 25 '19 at 14:55

6 Answers6

2

I think you're just misunderstanding what the book says.

so it will have to re-merge work anyway, it cannot be avoided and things will get messy, so what's the problem with that?

That's not things getting messy, that's just doing a merge. A merge is not messy, a merge is easy. There's no problem with that.

The messy case is when other people have a copy of your repo and you rewrite your repo's history by rebasing, then you try to merge from the other person's copy. Their copy still contains your old commits that no longer exist in your repo, because you have equivalent, but not identical commits created by rebasing. It gets messy because it will try to merge commits that don't need to be merged.

You're taking the book's description of why things are messy after rebasing, and then trying to understand them in a hypothetical situation without rebasing. Of course it doesn't make sense, because you're considering a completely different situation.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
1

Consider git pull as an alias for git fetch [branch] && git merge [branch]

Mauricio Machado
  • 613
  • 1
  • 5
  • 14
  • sorry I was talking about git fetch, I have edited my question, please have a look, thanks –  Sep 25 '19 at 14:56
0

You should look up this question here Git pull results in extraneous "Merge branch" messages in commit log the user poke explains it very well why the merge happens.

Philipp.E
  • 11
  • 3
  • sorry I was talking about git fetch, I have edited my question, please have a look, thanks –  Sep 25 '19 at 14:56
0

As indicated by Mauricio Machado's answer, by default, a git pull is effectively a fetch and merge operation alias.

You may want to configure the pull to do a rebase instead:

$ git config --global pull.rebase true
gertvdijk
  • 24,056
  • 6
  • 41
  • 67
  • sorry I was talking about git fetch, I have re-edited my question, please have a look, thanks –  Sep 25 '19 at 14:57
0

Rebasing is one of the operations, which allow to modify history. It means that you should not do that on public branches, where you work together with some other developer (develop branch for example).

Why?

Because it will most likely lead to conflicts, which we do not like to resolve, because it's purely manual thing. You can read more about it here: Atlassian Tutorial - Git merge conflicts

On the other hand, it does not mean that you should not use rebase at all. I use it daily to sync my feature branch with develop. I also always use pull with --rebase option.

BugHunter
  • 119
  • 6
0

Things could get messy because if you already pushed a commit, and then you do a rebase locally affecting that commit, that commit will change.

Consider this: Merge adds stuff in front of you while Rebase adds stuff behind you

So if you change stuff behind you, the present changes.

Commits are just a linked list pointing to the previous commit(s), what we call the parents. If you change the parents, that'll change the commit itself, changing its SHA, meaning that's a whole new commit.

Say you have:

[some-branch]   D -> E
                       \
  [HEAD] = A -> B -> C -> E

And you need to get D you can:

REBASE

       [some-branch]   D -> E
                         \
  [HEAD] = A' -> B' -> C' -> D -> E

Or MERGE

[some-branch]   D -> E
                  \
       [HEAD] = D -> A -> B -> C -> E

(There's a merge commit missing there, I know)

Why it gets messy? Because if you pushed your branch before getting D and someone started to work from it, their local branch and the pushed (remote) one have diverged, and fixing it's messy, considering they realize what's happening right away.

Why it's cleaner? It does not create a Merge Commit, and results in a much cleaner and legible history. Only safe if you're absolutely sure that you're the only one working in that branch.

The way to go? Just do a merge of the branch having the commits you want, that'll create a new commit in front of the last one, so once you push, the branches will be compatible.

Community
  • 1
  • 1
Mauricio Machado
  • 613
  • 1
  • 5
  • 14