Another conflict: resolving conflicts in git that occur when using rebase.
Tags: git, newbie, beginners
Published: 2019-10-17 01:46:19

## Background

This interactive tutorial about the resolution of conflicts in git is a continuation of my first blog in the series titled _And then we resolve a merge conflict..._. If you have not read it, please check it out [here.](https://dev.to/nubian_geekess/and-then-a-conflict-2eli)

The aim of this tutorial is to show how you can use rebasing as an alternative to merging so to combine to branches in git. It will demonstrate how you resolve conflicts that occur thereof.

## Intro to rebasing
Every commit in github is based on its preceding commit. When you trace the history you realize that every commit has an ancestor.
Practically this is shown by that whenever you log the history of a branch, all the commits are listed in chronological order. With first commit at the bottom and the most recent commit which is the HEAD at the top.
Now, what rebasing does is it rewrites history of your current branch, through assigning a commit of your choice as the ancestor of the HEAD.

## Now, let's get started

As indicated in the first blog to get started, we create a repo on github and initialize it with a README. Then clone it locally on my machine. After that, I open the project on an editor. My editor of choice is Visual Studio Code.

I  then create and check out a new branch called _list-interests_. And create _bio.txt_. In _bio.txt_ I add a list of my personal interests. Then voila: 

![code screenshot](https://thepracticaldev.s3.amazonaws.com/i/0t8fdikm5m3rvxlr31dc.png)

To stage the changes, on the terminal I run the command, 
```git add .```

Then to commit the changes to my local repo I run the command,
```git commit -m "Adds interests to bio"```

Then to look up the history of the _list-interests_ branch, on the terminal I run the command;
```git log --oneline```

The result:
```
5d944ac (HEAD -> list-interests) Adds interest to bio
305d937 (origin/master, origin/HEAD, master) Initial commit
```

Now let's imagine that a bunch of devs was assigned to this project. One dev, in particular, was assigned to add an intro to the bio. The dev successfully created the intro and then proceed to merge it to master.

To mimic that, on the terminal run the command,
```git checkout -```

The command above listed above allows you to navigate to the branch you were in before you checked out your current branch.

On _master_ I then create the file _bio.txt_. Then add a basic intro about myself.

![screenshot of codeblock](https://thepracticaldev.s3.amazonaws.com/i/20focxl3d59b2p1tsbrf.png)

I then add the changes to the staging area by running the command below on the terminal.
```git add .```

To add the changes to my  local repo,
```git commit -m "Adds intro to bio"```

Then I log the history by running the command;
```git log --oneline```

The output:
```
4586948 (HEAD -> master) Adds intro to bio
305d937 (origin/master, origin/HEAD) Initial commit
```

Then to sync _master_ to my _origin/master_ which is the  branch that corresponds to _master_ on the remote repository;
```git push ```

I then check out the branch _list-interests_ to continue.
If you log the history of the branch _list-interests_ you will realize that it was based on the old version of _master_ that did not have the intro. I intend to rebase it to the new version of _master_ so as to include the intro.                     

To do that on the terminal I then run the command;
```git rebase master```

On the terminal I get the error message:
```
First, rewinding head to replay your work on top of it...
Applying: Adds interest to bio
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
CONFLICT (add/add): Merge conflict in bio.txt
Auto-merging bio.txt
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0001 Adds interest to bio
"git add/rm <conflicted_files>", then run "git rebase --continue".        
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
```
The above message informs me that git failed to merge then provides me commands I can use to resolve the issue.

On the editor, this is what is there:

![screenshot of codeblock](https://thepracticaldev.s3.amazonaws.com/i/s140yydyfyxfgupma6ym.png)

Because I want to keep both the changes, I select the option _Accept Both Changes_ on VS code.

To continue I then add the change to the staging area, by running the command;
```git add .```

Then on the terminal, I  run the command;
```git rebase --continue```

Then get the message
```
Applying: Adds interest to bio
```
Under the hood when you rebase, git basically rewinds fetches the tip of _master_, places it in the position of the last commit of the branch you had checked out, then applies the tip of _list_interests_ on _master_.

To visualize it imagine your history was a deck of cards, a stack. You pop the topmost card which is the HEAD of your current branch, in its place you push the HEAD of _master_ then finally you push the HEAD of the current branch in its rightful position.

If you have conflicts you resolve them and then stage the changes. But instead of making a new merge commit when you run the command _git rebase --continue_ the changes are applied to the HEAD, which in this case had the message _Adds interests to bio_. When you log the history you get:
```
1a378f3 (HEAD -> list-interests) Adds interest to bio
4586948 (origin/master, origin/HEAD, master) Adds intro to bio
305d937 Initial commit
```

I have successfully made a rebase. Rebasing offers a clean way to combine diverging branches and its main advantage is the history is kept linear, unlike when you do merge commits.

I then sync my local and remote. Make a pull request. Then merge my pull request to _origin/master_. On  my local I checkout _master_ then on the terminal run the command;
```git pull```
So as to sync _master_ to _origin/master_. Then voila:

![screenshot of codeblock](https://thepracticaldev.s3.amazonaws.com/i/hkvzfhdgaz0ohexcvck5.png)

With that done, hopefully, you now have an understanding of how rebasing works in git. We now proceed to the main business of the day which is using rebasing to implement what we did on the [first blog](https://dev.to/nubian_geekess/and-then-a-conflict-2eli ) in the series.

Well, I would love to add a new feature to my bio. This time I will add a list of programming languages I have worked on. To do that I create and check out a new branch called _list-languages_. On the terminal, I run the command,
```git checkout -b list-languages```

Then I edit _bio.txt_ by adding a list of programming languages.

![screenshot of codeblock](https://thepracticaldev.s3.amazonaws.com/i/wpplvusgsy52k3wtpekd.png)

To proceed I then add the changes to the staging area by  running the command;
```git add .```

To commit the changes to my local repo, on the terminal I then run the command;
```"git commit -m "Adds programming languages to bio"```

To create a branch on the remote corresponding to _list--languages_ and push changes associated with it. On the terminal I then run the command;
```git push --set-upstream origin list-languages```

I just realized I made a blooper on my bio. Instead of adding C++, I meant to add C. But in the same regard, I want to keep my commit message. 

So back on my editor, I edit my bio.

![screenshot of code block](https://thepracticaldev.s3.amazonaws.com/i/7968tagpiwjffcfy92m2.png)

Now to stage the changes I run:
```git add .```

And to commit to my local, on my terminal I run the command:
```git commit --amend --no-edit```

As we know from the first tutorial _git commit --amend --no-edit_, alters the history of the branch. We end up with a scenario whereby the local and remote diverge from each other with the remote branch always leading.

When I attempt to sync my local and remote using:
```git push```

I  get this message as a response:
```
To github.com:JackieBinya/git-tut-2.git
! [rejected]        list-languages -> list-languages (non-fast-forward)
error: failed to push some refs to 'git@github.com:JackieBinya/git-tut-2.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

Before we proceed let's take a quick look at the history of the branch _list-languages_, using the command:
```git log --oneline```

The output:
```
c0fa933 (HEAD -> list-languages) Adds programming languages to bio
d2c5e0f (origin/master, origin/HEAD, master) Merge pull request #1 from JackieBinya/list-interests
1a378f3 (origin/list-interests, list-interests) Adds interest to bio
4586948 Adds intro to bio
305d937 Initial commit
```

Basically when I run the command _git push_. Under the hood git attempts to sync my local _list-languages_ to the corresponding branch on the remote _origin/list-languages_. Git is clever enough to realize that the branches have diverged, the remote is ahead of the local branch so it suggests I pull changes on the remote to my local, resolve any conflicts and push again.

To resolve the issue highlighted I run the command: 
```git pull --rebase```

I added the flag _--rebase_ to the _git pull_ command so as to rebase the HEAD of my local on the tip of _origin/list-laguages_. This offers an alternative to merging branches.

On my editor this is what my file looks like:

![screenshot of codeblock](https://thepracticaldev.s3.amazonaws.com/i/dljclocd8wl0h84y05ex.png)

To resolve the conflict, on VS Code I select the option to keep incoming changes. I then add the changes to the staging area then run the command;
```_git rebase --continue_```

This is what _bio.txt_ looks like on my editor:

![screenshot of codeblock](https://thepracticaldev.s3.amazonaws.com/i/p1814pamnh50jvbd6915.png)

When I log the history on the terminal I get the output below:
```
b584e1c (HEAD -> list-languages) Adds programming languages to bio
7b06700 (origin/list-languages) Adds programming languages to bio
d2c5e0f (origin/master, origin/HEAD, master) Merge pull request #1 from JackieBinya/list-interests
1a378f3 (origin/list-interests, list-interests) Adds interest to bio
4586948 Adds intro to bio
305d937 Initial commit
```

I then sync my local and remote. Make a PR then merge it to _master_.

Finally my bio:
{% gist https://gist.github.com/JackieBinya/e308108940e959157448c517aee21b71 %}

_Thank you for reading my article._