loading...
Cover image for How to keep your forked repository current

How to keep your forked repository current

ranewallin profile image Rane Wallin ・1 min read

Are you new to open source? If so, hopefully you have taken advantage of Hacktoberfest to get your feet wet. It's an exciting feeling to get your first pull request merged into a big project, but what happens next? If you want to keep working on the project, you will need to keep your fork current.

Here are some quick instructions on how to do that from beginning to end.

h/t to GitHub for having very clear instructions on this already. Here's all the steps in one place.

# If you haven't already added an upstream source, set your upstream
# to the fork's original source
git remote add upstream <url_to_original>

# Verify upstream is correct, you should see the URL for the upstream fetch and push
git remote -v

# Get all recent branches and commits from the upstream
git fetch upstream

# Check out your current master branch
git checkout master

# Merge the branches and commits from the upstream
git merge upstream/master

# Push the updated master to your forked remote repository
git push origin master

That's it. You should be up to date and ready to make your next PR.

Cover image by Salvatore G2 on Flickr

Posted on by:

ranewallin profile

Rane Wallin

@ranewallin

I'm a full stack web developer and java engineer. I am currently available for hire.

Discussion

markdown guide
 

I've had this alias in my ~/.gitconfig since about 2009:

pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
 
 

What you can also do is just having feature branches in your fork, and rebase then to master to update. If your confident with rebasing that might be easier.

 

Could you please explain how rebase works? That concept has always confused me.

 

Say you have made one commit, changing two files. In the mean time on master there had been 5 additional commits. To make this easily mergeable you can 'pretend' you applied those two changes after the 5 new commits.
When non of those files where changed in the other 5 commits this will go fine. When there where changes made, there is a conflict and you need to merge you commit that's applied again, with the new commits.
Your rewriting history in such a way that the commits are not ordered strictly in time, but when they where about to be merged.
If you do this before ever merge you get a flat history that is easy to follow.
You can also do some other fancy stuff while rebasing, like changing the commit message, merge multiple commits to one, or skip a commit.
These things will bother make it easier to review a pr, because it's much clearer what you changed compared to a pr with a lot of merges in it, and will keep master cleaner.
I mostly use IntelliJ to rebase, it makes resolving conflict very easy.

Thank you @gklijs for the detailed reply. So when you "pretend" you applied those two changes after the 5 new commits, does it actually do it, or is it only a dry-run? I guess I will need to test this out for myself to really understand how it works..but your explanation helped, I'll come back to this for reference :)

Be sure to push your branch to your fork before you start rebasing. In that case you can always restore the branch in case something goes wrong. After the rebase, make sure all the tests run, and your code (those two changes) are still there. If it's all good you can force push git push -f your local branch to your fork.
If you do it like that there no risk losing something. You shouldn't work with multiple people on the same remote branch, because then there is a risk of losing stuff. Ideally features are small enough to be done by one person. In case you do need to work together on the same branch, and still like to rebase, each person should work in it's own forked branch, and can rebase on the other fork when needed.

Thank you for the tips! Much appreciated!

 

Rebase “replays” your commits (with new commit hash) on the current top of the originating branch. :)

 

Maybe it's just me but I find it's much easier to have origin being... well the original repo and not my fork.

Before I used to clone lots of project where I actually never did any changes. What's the point?

If origin is the original repo, then I just need to checkout master and do git pull

To update a branch where I worked, I just need to do git fetch origin -v && git merge origin/master

I have some zsh aliases to help with it

export GITHUB=$HOME/github

// Usage: $ master
alias master="git fetch origin -v ; git fetch $USER -v ; git checkout -B master origin/master"

// Usage: $ clone jmfayard / buildSrcVersions 
// Will clone https://github.com/jmfayard/buildSrcVersions
function clone() {
    cd $GITHUB
    local ORG=$1 REPO=$3
    git clone https://github.com/${ORG}/${REPO}
    cd ${REPO}
    git remote add ${USER} https://github.com/${USER}/${REPO}
        echo "To fork the repository, open https://github.com/${ORG}/${REPO}/fork"
}
 

I just learnt about a new bot on github that does that for you by automated pull requests.

It's called "pull"

 

Why worry about keeping my fork up to date?

I create all new branches from upstream/master so never a branch out of sync

 

how does this play out ? more like how is it done?

 

This has been a lifesaver, especially for Hacktoberfest - Thank you so much Rane! 🕺

 

Would this work if you have made changes to your local fork and there are conflicts?