26 December 2015

Keeping up to date with a forked Github repository

Ok, you have made your first pull request and it has been accepted along other pull requests from others contributers or maybe you're still working on your fork but forked repository is receiving updates you want to take to your fork. In those two case you want to import all new commits received in forked repository to your fork one.

Removing your fork repository and recloning the forked one is not a solution because you may have code unfinished that you'd lose if you remove your repository. Working in that way is messy and prone to errors.

There's another way far better than that but to be honest it is not evident looking only to the Github web interface. The trick is to import commits to forked repository into your local copy of your forked repository and merging there the changes and pushing them to your Github repository afterwards.

At first glance it might look overcomplicated but it is logical if you consider your Github repository as a definitive one leaving your local copy as the place where you mess with things.

As I said before, to proceed that way I haven't found any evident way through Github web interface. Even Pycharm lacks a feature needed to do the process entirely through GUI, so you'll have to type something in console. Thankfully the thing is solved with just a few commands.

First step involves adding forked Github repository as a remote source of your local repository. As an example I'll show the output for my local copy of my fork version of vdist. This very step is the one you cannot do visually through GUI in Pycharm. To see which sources your git repository has type:

dante@Camelot:~/vdist$ git remote -v origin https://github.com/dante-signal31/vdist.git (fetch) origin https://github.com/dante-signal31/vdist.git (push)

You can see I call origin to my fork repository in Github. Now lets add original forked repository to my git sources. Say we want call original forked repository as upstream:

dante@Camelot:~/vdist$ git remote add upstream https://github.com/objectified/vdist.git dante@Camelot:~/vdist$ git remote -v origin https://github.com/dante-signal31/vdist.git (fetch) origin https://github.com/dante-signal31/vdist.git (push) upstream https://github.com/objectified/vdist.git (fetch) upstream https://github.com/objectified/vdist.git (push)

You can see that forked repository is now among my local git repository like upstream.

To download any change from forked repository without actually applying them in local repository you should use git fetch:

dante@Camelot:~/vdist$ git fetch upstream remote: Counting objects: 1, done. remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 1 De https://github.com/objectified/vdist * [new branch] master -> upstream/master

You can do this last one step from Pycharm GUI using "VCS-> Git-> Fetch" menu.

Downloaded changes are stored by default in upstream/master branch. You can review them and if you agree with them you can apply to your local master branch doing:

dante@Camelot:~/vdist$ git checkout master Switched to branch 'master' dante@Camelot:~/vdist$ git merge upstream/master

Now, your local master branch and the one from forked repository are synced. What you need to do is update your Github fork repository with a push:

dante@Camelot:~/vdist$ git push origin master

The good news are that you only need to add upstream repository just once and afterwards you can operate over it as usual even through Pycharm GUI as it detects the new remote branches as soon as you ask her to do a fetch from all sources.