DEV Community

Cover image for πŸ€• Git Visualized: Forked a Repo, Now The Original Has More Commits
Saqib Ameen for daily.dev

Posted on

πŸ€• Git Visualized: Forked a Repo, Now The Original Has More Commits

Let's consider a scenario where you are contributing to an open-source project.

  1. You forked a project.
  2. You cloned the repository.
  3. You made some changes.
  4. You pushed the changes.
  5. Time to create a pull request β€” but the original master branch has more commits now. πŸ€•

What to do now? You might have struggled with this scenario at some time in your career. Most of the beginners still do.

To all those struggling, this guide will help you handle such a situation and help you understand the underlying concepts of git as well. So let's get started!

πŸ‘¨β€πŸ’» Current State of Git Branches

Below is the visualization of the current scenario.

visualization of branches in git

For those who are not familiar with the concepts of upstream, it's not the local or the forked one, it points to the original repository on GitHub. It is not set by default. You need to manually link your cloned repo with upstream.

🎯 Pointing to The Upstream

For the sake of convenience let's assume two repos:

Original β€” https://github.com/dailydotdev/daily
Fork β€” https://github.com/saqibameen/daily

Below is the git command to do it.

# Add Upstream Remote.
git remote add upstream https://github.com/dailydotdev/daily.git

# Fetch latest updates from it.
git fetch upstream
Enter fullscreen mode Exit fullscreen mode

Remember that, those updates will be in upstream/[BRANCH_NAME]. With that done, now your remote pointers in local repo look like below:

The Remote Branch Links

At this stage, we have upstream/master available locally and we need to bring the new commits (namely, E and F in our diagram) to our feature branch. We have two options here:

  • Merge
  • Rebase

Both can be used to obtain the end result β€” get the latest updates from upstream/master and keep our commits as well.

πŸ”— Using git merge

Make sure you are on the feature branch. Use the following command to do the merge:

# Merge upstream/master to feature branch. 
git merge upstream/master
Enter fullscreen mode Exit fullscreen mode

If there are any conflicts in the merge, resolve them. Otherwise, just write the merge-commit message and you are all set. Behind the scene, your feature branch looks like this. The last commit is the merge commit that you do whenever you perform a merge.

Git merge resultant feat branch

Just a little convoluted history, which you might not want. All you want is your changes on top of the upstream/master followed by a push origin and a pull request.

πŸ— Using git rebase

git rebase is something I find a perfect fit for such a scenario. With it, you get a clean git history and nothing more. So, instead of the git merge, you can do the following:

# Rebase feature branch on top of upstream/master
git rebase upstream/master
Enter fullscreen mode Exit fullscreen mode

Now, take a look at how the feature branch looks like:

Use of git rebase

Did you notice the stars(*) on top of commit C and D? If you are not familiar with git rebase, I used them to indicate that these commits are a copy of the original commits C & D.

πŸ€” Take a look at the feature branch β€” probably exactly what we need for PR; not anything more. Perfect!

UPDATE:
You can also use the following command to achieve this all in one command.

git pull upstream master --rebase
Enter fullscreen mode Exit fullscreen mode

πŸš€ Push the changes

Let's see in both cases how git push works. After that, we only need to create a PR.

# Push changes to the origin. 

#In case of merge
git push origin feature

# In case of rebasing
git push --force origin feature
Enter fullscreen mode Exit fullscreen mode

Did you notice the --force flag in case of rebasing? It is because we are re-writing history. πŸ™ˆ

The feature branch initially had the following commits:

A β€” B β€” C β€” D
Enter fullscreen mode Exit fullscreen mode

With rebase, we changed it to:

A β€” B β€” E β€” F β€” C* β€” D*
Enter fullscreen mode Exit fullscreen mode

So, not only we created copies of C, and D commits, we also put E, and F at their original positions: git history is changed. That's why we need --force flag. Otherwise, you might get an error.

Because of the fact that git rebase copies commits and changes history, don't use it when you shared those commits with the team. Be careful while using it. A perfect scenario is when you haven't shared your work with anyone.

πŸ™Œ Wrap Up!

Learning through use-cases is the best way to master anything. You don't only solve that problem but also get to understand the usage of tech involved in the process.

I hope this post will help you not only get through this situation but also understand how git merge and git rebase differ and where to use them. If you have any questions, feel free to drop them in the comments section below.


πŸ‘‹ Follow us on Twitter to stay up-to-date!

Thanks to Daily, developers can focus on code instead of searching for news. Get immediate access to all these posts and much more just by opening a new tab.

Daily Poster

Top comments (5)

Collapse
 
hyftar profile image
Simon Landry

Nice post! You could also talk about git pull upstream master --rebase which does the rebase automatically 😊

Collapse
 
saqibameen profile image
Saqib Ameen

Hey @hyftar ,

Thank you so much for stopping by and sharing this. That's definitely a quick way of achieving this. I'll add it to the article. The goal here was to actually help beginners understand and conceptualize each step separately.

Collapse
 
ponyjackal profile image
ponyjackal

Thanks for your posting

Collapse
 
jackfr0st13 profile image
Deepak Choudhary

Nice post man !! Keep the good work coming.

Collapse
 
sillydadddy_96 profile image
siLLyDaDDy

Nice post ..thanks