In the Git: Keeping in sync post we learned how to merge the orgin/master commits into our local master branch. Then in Git: Effective branching using workflows we learned about how to use branches effectively. What we haven’t yet touched on yet though is rebasing and its affect on merging.

Commit log

Before we get started on merging and rebasing, let’s first see how we can view our git log as we will need to do it throughout this post:

Will@MainPC MINGW64 /f/Will/git-tutorial (master)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3
0a37254 - (4 days ago) Merge remote-tracking branch 'origin/test_branch' - Will Robinson (HEAD -> master, origin/master, develop)
a0ec1b6 - (4 days ago) removed file1.txt - Will Robinson (origin/test_branch)
740a573 - (4 days ago) Add new file - Will

In a nutshell, the above command shows us the last three commits which were made in this repo. If we want to get a little fancier, we can have git draw a graph for us:

Will@MainPC MINGW64 /f/Will/git-tutorial (master)
$ git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3
*   0a37254 - (4 days ago) Merge remote-tracking branch 'origin/test_branch' - Will Robinson (HEAD -> master, origin/master, develop)
|\
| * a0ec1b6 - (4 days ago) removed file1.txt - Will Robinson (origin/test_branch)
| * 740a573 - (4 days ago) Add new file - Will

Note: The above commands were taken from this StackOverflow thread. As per the screenshots on StackOverflow, the output is colour coded which definitely helps!

You’re probably wondering what the *| and \ characters represent. They’re used to show us the branches and commits which have been created in this repo. By sticking to a git workflow, your log will be tidy and easy to follow. If you don’t, it’s highly likely your log is already or soon will be a complete mess! But I digress…

Creating a branch

Let’s start by creating a new branch off master called develop:

Will@MainPC MINGW64 /f/Will/git-tutorial (master)
$ git checkout -b develop
Switched to a new branch 'develop'

Now let’s make it track remotely:

$ git push -u origin develop
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote:   https://gitlab.com/OzNetNerd/git-tutorial/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote:
To https://gitlab.com/OzNetNerd/git-tutorial.git
 * [new branch]      develop -> develop
Branch develop set up to track remote branch develop from origin.

Finally, let’s confirm that it is indeed being tracked remotely:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git branch -avv
* develop                    0a37254 [origin/develop] Merge remote-tracking branch 'origin/test_branch'
  master                     0a37254 [origin/master] Merge remote-tracking branch 'origin/test_branch'
  remotes/origin/develop     0a37254 Merge remote-tracking branch 'origin/test_branch'
  remotes/origin/master      0a37254 Merge remote-tracking branch 'origin/test_branch'

Great, the above tells us that develop is tracking origin/develop. We’re good to go!

Merging

Let’s now delve into the whole reason (or at least, one of the reasons) for this post - Merging.

As its name suggests, performing a merge results in two branches being merged. While it might sound easy enough, that isn’t the end of the story. The state of the two branches (the origin and local branches) determines the way in which they will be merged. Let’s take a look at how to initiate a Fast Forward merge, as well as a Recursive merge.

Fast Forward

Fast Forward merges are very straightforward (pun intended!). They can be used when there is no divergence between the remotely tracked origin branch and our local branch.

It’s known as a Fast Forward merge because git is able to simply move the branch’s pointer forward to the tip of the merged branch. It’s as simple as that. This is in contrast to other merging methods whereby complex merging strategies are required.

The benefit of a Fast Forward merge is that it keeps your git log graph linear/clean. Let’s now look at an example.

Below is what our newly created develop branch looks like:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3
0a37254 - (4 days ago) Merge remote-tracking branch 'origin/test_branch' - Will Robinson (HEAD -> develop, origin/master, origin/develop, master)
a0ec1b6 - (4 days ago) removed file1.txt - Will Robinson (origin/test_branch)
740a573 - (4 days ago) Add new file - Will

At this point in time, develop and origin/develop are in sync. However, let’s say we go to lunch and when we come back, John has made a few commits and performed a push  to the origin/develop branch:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git fetch
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From https://gitlab.com/OzNetNerd/git-tutorial
   0a37254..a655b2f  develop    -> origin/develop

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3
a655b2f - (57 seconds ago) Add new file: script2.py - John (origin/develop)
c64c510 - (81 seconds ago) Add new file: script1.py - John
0a37254 - (4 days ago) Merge remote-tracking branch 'origin/test_branch' - Will Robinson (HEAD -> develop, origin/master, master)

In the above output we can see that the fetch command was used to sync our machine’s copy of origin/develop with the remote server’s version. Because we saw new commits come through, we then looked at the git log and saw there were in fact two new commits.

So now our origin/develop has been updated, but our local develop branch still hasn’t. Because we haven’t made any commits to our local branch, we can see that the path between develop and origin/develop is straight:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3 --graph
* a655b2f - (4 minutes ago) Add new file: script2.py - John (origin/develop)
* c64c510 - (4 minutes ago) Add new file: script1.py - John
*   0a37254 - (4 days ago) Merge remote-tracking branch 'origin/test_branch' - Will Robinson (HEAD -> develop, origin/master, master)

As a result of this, if we do a git merge or a git pull (which, as mentioned in the Git: Keeping in sync post, does a git fetch and git merge in a single command), it will result in a Fast Forward merge:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git merge
Updating 0a37254..a655b2f
Fast-forward
 script1.py | 0
 script2.py | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 script1.py
 create mode 100644 script2.py

Let’s now take a look at what our git log looks like:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3
a655b2f - (12 minutes ago) Add new file: script2.py - John (HEAD -> develop, origin/develop)
c64c510 - (12 minutes ago) Add new file: script1.py - John
0a37254 - (4 days ago) Merge remote-tracking branch 'origin/test_branch' - Will Robinson (origin/master, master)

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3 --graph
* a655b2f - (12 minutes ago) Add new file: script2.py - John (HEAD -> develop, origin/develop)
* c64c510 - (12 minutes ago) Add new file: script1.py - John
*   0a37254 - (4 days ago) Merge remote-tracking branch 'origin/test_branch' - Will Robinson (origin/master, master)

Excellent, develop and origin/develop are in sync, and we’ve got a tidy graph log.

Recursive merge

As mentioned previously in this post, a Fast Forward merge can only take place when there’s no divergence between the origin and local branches. Let’s see what happens when they do diverge.

Using the same example as before, let’s say John made a few commits and used push to send them to the origin/develop branch. We then do a git fetch and check git status as well as git log to find out how many commits were made:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git status
On branch develop
Your branch is behind 'origin/develop' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git fetch
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From https://gitlab.com/OzNetNerd/git-tutorial
   a655b2f..b5c11ab  develop    -> origin/develop

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3
b5c11ab - (2 minutes ago) Add new file: script4.py - John (origin/develop)
5ff754d - (2 minutes ago) Add new file: script3.py - John
a655b2f - (29 minutes ago) Add new file: script2.py - John (HEAD -> develop)

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3 --graph
* b5c11ab - (2 minutes ago) Add new file: script4.py - John (origin/develop)
* 5ff754d - (3 minutes ago) Add new file: script3.py - John
* a655b2f - (29 minutes ago) Add new file: script2.py - John (HEAD -> develop)

git tells us that we’re two commits behind origin/develop. Instead of doing a git merge like we did last time, this time we make a couple of commits of our own:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ touch new_script1.py

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git add .

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git commit -m 'Added file: new_script1.py'
[develop e21cdc2] Added file: new_script1.py
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 new_script1.py

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ touch new_script2.py

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git add .

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git commit -m 'Added file: new_script2.py'
[develop 4ea7d92] Added file: new_script2.py
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 new_script2.py

Let’s now take a look at the git status and git log outputs:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git status
On branch develop
Your branch and 'origin/develop' have diverged,
and have 2 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -5 --graph
* 4ea7d92 - (2 minutes ago) Added file: new_script2.py - Will (HEAD -> develop)
* e21cdc2 - (2 minutes ago) Added file: new_script1.py - Will
| * b5c11ab - (8 minutes ago) Add new file: script4.py - John (origin/develop)
| * 5ff754d - (8 minutes ago) Add new file: script3.py - John
|/
* a655b2f - (35 minutes ago) Add new file: script2.py - John

There are two important pieces of information in this output:

  1. git tells us that our develop branch has diverged from origin/develop.
  2. Our git log graph isn’t linear like it was last time. We can see that our develop branch diverged from origin/develop at commit a655b2f .

The good news is that we can still use our trusty git merge (or git pull) command to bring our local back into sync with the origin branch. However, due to the divergence, a Recursive merge will be used instead of a Fast Forward merge:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git merge

Merge made by the 'recursive' strategy.
 script3.py | 0
 script4.py | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 script3.py
 create mode 100644 script4.py

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git push
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 671 bytes | 671.00 KiB/s, done.
Total 6 (delta 3), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote:   https://gitlab.com/OzNetNerd/git-tutorial/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote:
To https://gitlab.com/OzNetNerd/git-tutorial.git
   b5c11ab..7ae9fcf  develop -> develop

Let's now take a look at our `git log` outputs:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -5
7ae9fcf - (5 minutes ago) Merge remote-tracking branch 'refs/remotes/origin/develop' into develop - Will (HEAD -> develop, origin/develop)
4ea7d92 - (18 minutes ago) Added file: new_script2.py - Will
e21cdc2 - (18 minutes ago) Added file: new_script1.py - Will
b5c11ab - (24 minutes ago) Add new file: script4.py - John
5ff754d - (25 minutes ago) Add new file: script3.py - John

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -6 --graph
*   7ae9fcf - (5 minutes ago) Merge remote-tracking branch 'refs/remotes/origin/develop' into develop - Will (HEAD -> develop, origin/develop)
|\
| * b5c11ab - (24 minutes ago) Add new file: script4.py - John
| * 5ff754d - (25 minutes ago) Add new file: script3.py - John
* | 4ea7d92 - (18 minutes ago) Added file: new_script2.py - Will
* | e21cdc2 - (18 minutes ago) Added file: new_script1.py - Will
|/
* a655b2f - (52 minutes ago) Add new file: script2.py - John

As we can see, 7ae9fcf is a merge commit and has resulted in our local develop branch and the origin/develop branch being brought back into sync.

Rebasing

While the two preceding merging sections resulted in the same outcome, they took two different paths to get there. It’s important to note that some prefer to avoid the Recursive merging strategy because it pollutes the log history and goes against their chosen git workflow.

You might be thinking though, “are you telling me I have to do a git fetch and git merge  or a git pull every single time I’m about to do a git push just so I can avoid polluting my git log?!”. The answer to that question, thankfully, is no. This is where rebasing comes into play.

What rebasing does is it puts your local commits at the end of the remote (origin) commits, therefore creating a linear path resulting in the allowance of a Fast Forward merge. Wow, that was a bit of a mouthful, but rest assured it’s much easier than it sounds.

As with the previous example, let’s say John has made a couple of commits and used push to send them to origin/develop. We then make a change and commit it. We’re then ready to push our changes to origin/develop but find that there’s a divergence:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ touch new_script3.py

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git add .

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git commit -m 'Add new file: new_script3.py'
[develop eed15d9] Add new file: new_script3.py
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 new_script3.py

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git fetch
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From https://gitlab.com/OzNetNerd/git-tutorial
   7ae9fcf..f693496  develop    -> origin/develop

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git status
On branch develop
Your branch and 'origin/develop' have diverged,
and have 1 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean

As we saw in the Recursive merge section of this post, if we do a git merge now we’ll end up with an untidy git log graph. Let’s then do a rebase instead:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: Add new file: new_script3.py

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git push
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 251 bytes | 251.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote:   https://gitlab.com/OzNetNerd/git-tutorial/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote:
To https://gitlab.com/OzNetNerd/git-tutorial.git
   f693496..f9ac684  develop -> develop

Let’s now take a look at our git log outputs:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -9
f9ac684 - (23 minutes ago) Add new file: new_script3.py - Will (HEAD -> develop, origin/develop)
f693496 - (27 minutes ago) Delete script4.py - John
c4fbeba - (27 minutes ago) Delete script3.py - John
7ae9fcf - (49 minutes ago) Merge remote-tracking branch 'refs/remotes/origin/develop' into develop - Will
4ea7d92 - (61 minutes ago) Added file: new_script2.py - Will
e21cdc2 - (62 minutes ago) Added file: new_script1.py - Will
b5c11ab - (68 minutes ago) Add new file: script4.py - John
5ff754d - (68 minutes ago) Add new file: script3.py - John
a655b2f - (2 hours ago) Add new file: script2.py - John

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -9 --graph
* f9ac684 - (24 minutes ago) Add new file: new_script3.py - Will (HEAD -> develop, origin/develop)
* f693496 - (27 minutes ago) Delete script4.py - John
* c4fbeba - (27 minutes ago) Delete script3.py - John
*   7ae9fcf - (49 minutes ago) Merge remote-tracking branch 'refs/remotes/origin/develop' into develop - Will
|\
| * b5c11ab - (68 minutes ago) Add new file: script4.py - John
| * 5ff754d - (68 minutes ago) Add new file: script3.py - John
* | 4ea7d92 - (61 minutes ago) Added file: new_script2.py - Will
* | e21cdc2 - (62 minutes ago) Added file: new_script1.py - Will
|/
* a655b2f - (2 hours ago) Add new file: script2.py - John

Hooray! We’ve managed to merge the branches even though they were diverged, while still maintaining a linear (clean) history.

How does rebasing work?

Rebasing gets its name from the fact that it changes the commit which your subsequent commits are based off - in other words, your commits are rebased onto another commit.

Let’s take a look at another example. Let’s say the following commits were made in this order:

       
Commit: Author: Filename: Branch:
1 John menu.py origin/delveop
2 Will module.py develop
3 John food.py origin/develop

The git log outputs confirm that the above is correct:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -4
9ec5884 - (70 seconds ago) Add new file: food.py - John (origin/develop)
108334e - (2 minutes ago) Add new file: module.py - Will (HEAD -> develop)
3feff89 - (2 minutes ago) Add new file: menu.py - John
f9ac684 - (40 minutes ago) Add new file: new_script3.py - Will

$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -4 --graph
* 9ec5884 - (54 seconds ago) Add new file: food.py - John (origin/develop)
* 3feff89 - (2 minutes ago) Add new file: menu.py - John
| * 108334e - (89 seconds ago) Add new file: module.py - Will (HEAD -> develop)
|/
f9ac684 - (40 minutes ago) Add new file: new_script3.py - Will

(It’s worth noting that although the first output makes it appear that the local develop branch includes the 3feff89 commit, the second output shows that it is in fact on a separate branch.)

Let’s have a look at the git status output:

$ git status
On branch develop
Your branch and 'origin/develop' have diverged,
and have 1 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean

OK, no surprises there. Let’s now do the rebase and see what happens:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: Add new file: module.py

$ git push
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 246 bytes | 246.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote:
remote: To create a merge request for develop, visit:
remote:   https://gitlab.com/OzNetNerd/git-tutorial/merge_requests/new?merge_request%5Bsource_branch%5D=develop
remote:
To https://gitlab.com/OzNetNerd/git-tutorial.git
   9ec5884..b50dab5  develop -> develop

And finally, let’s take a look at our git log outputs:

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3
b50dab5 - (28 minutes ago) Add new file: module.py - Will (HEAD -> develop, origin/develop)
9ec5884 - (28 minutes ago) Add new file: food.py - John
3feff89 - (28 minutes ago) Add new file: menu.py - John

Will@MainPC MINGW64 /f/Will/git-tutorial (develop)
$ git log --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all -3 --graph
* b50dab5 - (28 minutes ago) Add new file: module.py - Will (HEAD -> develop, origin/develop)
* 9ec5884 - (28 minutes ago) Add new file: food.py - John
* 3feff89 - (29 minutes ago) Add new file: menu.py - John

Wait a minute, what happened to our git log graph? Last time we checked it there was a diverge. And, why is our module.py commit at the tip of the branch? Shouldn’t it be in the middle of John’s two commits given that it was the second commit to be made out of the three?

These mysterious happenings are due to the way in which rebasing works. Because we rebased origin/develop onto our local develop branch, git removes commits, brings our develop branch into sync with the origin/develop branch and then re-applies our commits to the tip of the newly synced branch.

As we saw above, this results in two things:

  • A linear log (as was the case with a Fast Forward merge)
  • Our local commits, regardless of whether they were made before and/or after the remote’s commits, will be re-committed as if they were always committed after the origin’s commits

As always, if you have any questions or have a topic that you would like me to discuss, please feel free to post a comment at the bottom of this blog entry, e-mail at will@oznetnerd.com, or drop me a message on Reddit (OzNetNerd).

Note: The opinions expressed in this blog are my own and not those of my employer.

Tags: ,

Categories:

Updated:

Leave a comment