RoyBraam.com

RoyBraam.com

Welcome

8 minutes read

I got some questions about not using ‘–rebase’ when pulling changes and why I add those ‘ugly merge’ commits to that beautiful git repo. I then try to explain that I rather have a complete history then a false one, even if there are some ugly parts in that history. Because i got into this discussion a couple of times i decided to use this as an excuse to start writing a blog.

Just a side note: I’m not telling you shouldn’t use ‘–rebase’ while pulling. I just want to explain what the disadvantages are and why you should not use it always. Sometimes having a clean history is not worth having a incomplete history

Lets say we have 2 guys. Pietje and Jantje (typical Dutch names). They both are working on the ‘only-pull-rebase-project’. As the project name says, they are only allowed to pull changes with ‘–rebase’ to keep the project history clean and readable. They both don’t know why they should do this, but that is what they got told. Jantje clones the remote repo to his local machine

~/local-jantje$ git clone git@github.com:rbraam/only-pull-rebase-project.git
   Cloning into 'only-pull-rebase-project'...
   remote: Counting objects: 3, done.[K
   remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0[K
   Receiving objects: 33% (1/3)
   Receiving objects: 66% (2/3)
   Receiving objects: 100% (3/3)
   Receiving objects: 100% (3/3), done.
   Checking connectivity... done.

Jantje starts working on a new feature for this project. Therefore he makes a feature branch to work on.

~/local-jantje/only-pull-rebase-project$ git checkout -b feature/only-rebase-pull-branch
    Switched to a new branch 'feature/only-rebase-pull-branch'
~/local-jantje/only-pull-rebase-project$ git push
    fatal: The current branch feature/only-rebase-pull-branch has no upstream branch.
    To push the current branch and set the remote as upstream, use

         git push --set-upstream origin feature/only-rebase-pull-branch

Aaaah, yes. Because the remote repository doesn’t have this branch (yet) he needs to set the upstream branch.

~/local-jantje/only-pull-rebase-project$ git push --set-upstream origin feature/only-rebase-pull-branch
    Total 0 (delta 0), reused 0 (delta 0)
    To git@github.com:rbraam/only-pull-rebase-project.git
    * [new branch] feature/only-rebase-pull-branch -> feature/only-rebase-pull-branch
    Branch feature/only-rebase-pull-branch set up to track remote branch feature/only-rebase-pull-branch from origin.

Jantje is happy now because others can also work on this feature in the same branch. He’s not so happy about the weather…. It’s starting to rain…

~/local-jantje/only-pull-rebase-project$ echo "What a rainy morning" > file1.txt
~/local-jantje/only-pull-rebase-project$ git add file1.txt
~/local-jantje/only-pull-rebase-project$ git commit -m "what a rainy morning (first commit)"
   [feature/only-rebase-pull-branch ed60270] what a rainy morning (first commit)
   1 file changed, 1 insertion(+)
   create mode 100644 file1.txt
~/local-jantje/only-pull-rebase-project$ git status
   On branch feature/only-rebase-pull-branch
   Your branch is ahead of 'origin/feature/only-rebase-pull-branch' by 1 commit.
   (use "git push" to publish your local commits)
   nothing to commit, working directory clean

Because of the bad weather his connection dropped and Jantje was not able to push his changes to the remote, tracking branch.

In the afternoon Pietje is also ready to work on the same feature.

~/local-pietje$ git clone git@github.com:rbraam/only-pull-rebase-project.git
   Cloning into 'only-pull-rebase-project'...
   remote: Counting objects: 3, done.[K
   remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0[K
   Receiving objects: 33% (1/3)
   Receiving objects: 66% (2/3)
   Receiving objects: 100% (3/3)
   Receiving objects: 100% (3/3), done.
   Checking connectivity... done.
~/local-pietje$ cd only-pull-rebase-project/
~/local-pietje/only-pull-rebase-project$ git checkout feature/only-rebase-pull-branch
   Branch feature/only-rebase-pull-branch set up to track remote branch feature/only-rebase-pull-branch from origin.
   Switched to a new branch 'feature/only-rebase-pull-branch'
~/local-pietje/only-pull-rebase-project$ git status
   On branch feature/only-rebase-pull-branch
   Your branch is up-to-date with 'origin/feature/only-rebase-pull-branch'.
   nothing to commit, working directory clean

And he also starts working on this new feature.

~/local-pietje/only-pull-rebase-project$ echo "What a rainy afternoon" > file2.txt
~/local-pietje/only-pull-rebase-project$ git add file2.txt
~/local-pietje/only-pull-rebase-project$ git commit -m "What a rainy afternoon"
   [feature/only-rebase-pull-branch f6315ba] What a rainy afternoon
   1 file changed, 1 insertion(+)
   create mode 100644 file2.txt

Pietje is pushing his changes to the remote repo.

~/local-pietje/only-pull-rebase-project$ git push
   Counting objects: 3, done.
   Delta compression using up to 8 threads.
   Compressing objects: 50% (1/2)
   Compressing objects: 100% (2/2)
   Compressing objects: 100% (2/2), done.
   Writing objects: 33% (1/3)
   Writing objects: 66% (2/3)
   Writing objects: 100% (3/3)
   Writing objects: 100% (3/3), 305 bytes | 0 bytes/s, done.
   Total 3 (delta 0), reused 0 (delta 0)
   To git@github.com:rbraam/only-pull-rebase-project.git
   150933d..f6315ba feature/only-rebase-pull-branch -> feature/only-rebase-pull-branch

After some time, Jantje has a connection again and he tries to push his commit to the remote repo.

~/local-jantje/only-pull-rebase-project$ git push
   To git@github.com:rbraam/only-pull-rebase-project.git
   ! [rejected] feature/only-rebase-pull-branch -> feature/only-rebase-pull-branch (fetch first)
   error: failed to push some refs to 'git@github.com:rbraam/only-pull-rebase-project.git'
   hint: Updates were rejected because the remote contains work that you do
   hint: not have locally. This is usually caused by another repository pushing
   hint: to the same ref. You may want to first integrate the remote changes
   hint: (e.g., 'git pull ...') before pushing again.
   hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Hmmm somebody is working on the same branch. Lets pull with a ‘–rebase’, because that’s what the boss wants.

~/local-jantje/only-pull-rebase-project$ git pull --rebase
   remote: Counting objects: 3, done.[K
   remote: Compressing objects: 50% (1/2) [K
   remote: Compressing objects: 100% (2/2) [K
   remote: Compressing objects: 100% (2/2), done.[K
   remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0[K
   Unpacking objects: 33% (1/3)
   Unpacking objects: 66% (2/3)
   Unpacking objects: 100% (3/3)
   Unpacking objects: 100% (3/3), done.
   From github.com:rbraam/only-pull-rebase-project
   150933d..f6315ba feature/only-rebase-pull-branch -> origin/feature/only-rebase-pull-branch
   First, rewinding head to replay your work on top of it...
   Applying: what a rainy morning (first commit)

And again he tries to push his commit

~/local-jantje/only-pull-rebase-project$ git push
   Counting objects: 3, done.
   Delta compression using up to 8 threads.
   Compressing objects: 50% (1/2)
   Compressing objects: 100% (2/2)
   Compressing objects: 100% (2/2), done.
   Writing objects: 33% (1/3)
   Writing objects: 66% (2/3)
   Writing objects: 100% (3/3)
   Writing objects: 100% (3/3), 343 bytes | 0 bytes/s, done.
   Total 3 (delta 0), reused 0 (delta 0)
   To git@github.com:rbraam/only-pull-rebase-project.git
   f6315ba..d54a005 feature/only-rebase-pull-branch -> feature/only-rebase-pull-branch

A hard day working it was…. Lets see the log:

~/local-jantje/only-pull-rebase-project$ git log
   commit d54a005657c179d1bfdeff6d45cf04980b2fffac
   Author: Jantje <jantje@jantje.com>
   Date: Mon Apr 18 09:57:12 2016 +0200

      what a rainy morning (first commit)

  commit f6315ba9f1b9a68e48cd77a09743618b315eaea5
  Author: Pietje <pietje@pietje.com>
  Date: Mon Apr 18 14:58:26 2016 +0200

     What a rainy afternoon

  commit 150933dff06e34c2ed861ceee371fb50142bc738
  Author: Boss <the@boss.com>
  Date: Mon Apr 11 07:53:14 2016 +0200

      first commit, init of project

Hmmm interesting. The timestamps of the commits are correct, but the order is different. Of course it is, because the commit by Jantje is replayed on the commit made by Pietje. Nothing strange, but something you should be aware of.

What if a bug is introduced by Pietje (commit #f6315b), but Jantje knows all worked fine when he worked on that feature in the morning (because of no connection, he ran all the tests local and all where green). So he is sure all worked fine in commit #d54a00…. But actually the bug is introduced ‘earlier’…… So when checking out the commit of Jantje (#d54a00) the test are now also failing in that commit. Jantje thinks he’s going crazy and blames the unstable tests. Pietje is blaming Jantje, it ends up in a fight, both end up in the hospital and there is nobody that works on the desired feature for a month….

So, how does this looks like when not using ‘–rebase’. Jantje types in the following commands again.

~/local-jantje/only-pull-rebase-project$ git checkout -b feature/merge-pull-branch
~/local-jantje/only-pull-rebase-project$ git push --set-upstream origin feature/merge-pull-branch
~/local-jantje/only-pull-rebase-project$ echo "What a sunny morning" > file1.txt
~/local-jantje/only-pull-rebase-project$ git add file1.txt
~/local-jantje/only-pull-rebase-project$ git commit -m "What a sunny morning"

Jantje is again not able to push his commit. Pietje is also doing the same as before.

~/local-pietje/only-pull-rebase-project$ git checkout feature/merge-pull-branch
~/local-pietje/only-pull-rebase-project$ echo "What a sunny afternoon" > file2.txt
~/local-pietje/only-pull-rebase-project$ git add file2.txt
~/local-pietje/only-pull-rebase-project$ git commit -m "What a sunny afternoon"
~/local-pietje/only-pull-rebase-project$ git push

Now Jantje tries to push his changes but is unable to do so, because Pietje pushed his changes. Now he does a pull without ‘–rebase’.

~/local-jantje/only-pull-rebase-project$ git push
  To git@github.com:rbraam/only-rebase-project.git
   ! [rejected] feature/merge-pull-branch -> feature/merge-pull-branch (fetch first)
  error: failed to push some refs to 'git@github.com:rbraam/only-rebase-project.git'
  hint: Updates were rejected because the remote contains work that you do
  hint: not have locally. This is usually caused by another repository pushing
  hint: to the same ref. You may want to first integrate the remote changes
  hint: (e.g., 'git pull ...') before pushing again.
  hint: See the 'Note about fast-forwards' in 'git push --help' for details.
~/local-jantje/only-pull-rebase-project$ git pull

The commit message editor will be opened. Jantje saves the predefined merge message and pushes the 2 commits. (the file1.txt commit and the merge commit). Lets see the log now:

~/local-jantje/only-pull-rebase-project$ git push
~/local-jantje/only-pull-rebase-project$ git log
  commit bfd2f9f3e6716fb1f357f80b604460ab1633fe05
  Merge: 5386457 837c9b8
  Author: Jantje <jantje@jantje.com>
  Date: Tue Apr 19 21:45:07 2016 +0200

    Merge branch 'feature/merge-pull-branch' of github.com:rbraam/only-rebase-project into feature/merge-pull-branch

  commit 837c9b89b9fd6afc01a1370fb5c495f0c8898e83
  Author: Pietje <pietje@pietje.com>
  Date: Mon Apr 19 14:58:26 2016 +0200

    What a sunny afternoon

  commit 538645746577ea6a365fa4cef2db066d9726abda
  Author: Jantje <jantje@jantje.com>
  Date: Mon Apr 19 09:57:12 2016 +0200

    What a sunny morning

  commit 150933dff06e34c2ed861ceee371fb50142bc738
  Author: Boss <the@boss.com>
  Date: Mon Apr 11 07:53:14 2016 +0200

    first commit

Now the order is correct, but there is a merge message. Again Pietje made a bug, the team has no problem finding the commit that introduced the bug, they solved it and everybody is happy.

I hear you saying: But what if Jantje introduced the bug. Yes, it changes things, but at least you have this nice merge commit where you can see what happend and what commits are merged. When doing the ‘–rebase’ all that history is lost….

Conclusion: Think when you are using git. Using ‘–rebase’ is not THE solution to remove all those merge commits. When you have ‘too much’ merge commits rethink your branching strategy. O, and remember those days when we didn’t had git. But used SVN for example. Merging 2 branches was so much fun….

    • None
    • None

Recent posts

Categories

About