I’ve been studying up on Git and how to use it, here.
My goal was to rationalise a somewhat messy local disk folder structure of multiple personal Sparkcore projects, whilst benefitting from Git branches for both personal versioning control and upstream updates – all in a clean, uncluttered manner, on GitHub. (What a mouthful!)
Starting With a Clean Slate (almost – but not cutting ties)
What I now have is ‘my own’ GitHub repository forked from spark/core-firmware, wherein resides only the master branch and one branch for each of my own Sparkcore projects. Currently, it looks like this …
My Rationale or, "Why I did this"
I wanted my own GitHub repository, to contain a record of my local Sparkcore projects. This needed to be a clean affair, so I didn’t want to have copies of all the other branches present on the official Spark core-firmware repository, at the time I forked my own copy.
I will first explain how I use the final result and later how I set it up this way in the first place.
Working on Individual Projects
After cloning a local working copy of my forked repository using
git clone https://github.com/gruvin/core-firmware.git, I can now work on each of two currently published projects using the
git checkout command. It goes something like this …
$ cd ~/sparkcore-forked/core-firmware $ git branch gruvin/chibi-port gruvin/dryer-timer * master
This tells me I am in the master branch of core-firmware.
NOTE: I should never change any files in here, because I want my master branch to always echo the official Spark core-firmware code, without any chances by me.
Now, I have two existing projects, each in their own branch. Let’s do some work on the project I have named gruvin/chibi-port …
$ git checkout gruvin/chibi-port Switched to branch 'gruvin/chibi-port' $ vi src/application.cpp
I chose the naming convention, ‘gruvin/project-name’ only so that should I some day write a new Sparkcore library and offer it as a pull request, I am less likely to collide with some existing branch name, back in the official Spark core-firmware repository. If you don’t like this, you can simply omit the ‘whatever/’ prefix.
After reaching each little milestone win with my code, I want to record my progress in a local commit. I’ll skip the staging process by using the
-a argument to
commit, because I’m lazy …
$ git commit -a -m 'Finally! The radio is sending and receiving pings! Yay \o/'
Later, it comes to pass that my gorgeous wife informs me how it would nice if our IoT-connected clothes dryer had some subtle new feature. So, let’s change to that project and get it done …
$ git checkout gruvin/dryer-timer Switched to branch 'gruvin/dryer-timer' $ vi src/application.cpp
After testing and attaining that state of happiness only a hacker/maker can know, I commit my changes, again just locally …
$ git commit -a -m 'Reduced cool down time from 10 minutes to 5, so clothes come out still a little warm in winter'
Publishing Work to GitHub
When I’m ready to publish my work to GitHub (aka update my off-site backup) I would execute something like …
$ git push origin gruvin/dryer-timer
Bringing in Updates from the Official Spark core-firmware
After I forked my own core-firmware, I added a reference to the official Spark core-firmware repository, so that I can pull in future, external (to me) updates …
$ get remote add upstream https://github.com/spark/core-firmware.git
I can now fetch updates from the official Spark core-firmware repository as follows. Note that this step sucks down the updates, but does not actually apply them to any of my forked branches, yet …
$ git fetch upstream
Now I can apply the updates to one or more of my branches. Let’s sync up my master branch, first …
$ git checkout master Switched to branch 'master' $ git merge upstream/master
I can use the same sort of command to update my other two projects or, having already got my master branch up to date, I can merge that to my other branches, by first checking out the target branch and then using
git merge origin/master.
Grabbing a Light-weight Copy of Just One Project Branch
If I wanted to clone a copy of just my dryer-timer project’s core-firmware folder, skipping all but the most recent history in order to keep the cloned copy as small as possible, I can do something like this …
$ git clone -b gruvin/dryer-timer --single-branch --depth 1 https://github.com/gruvin/core-firmware.git core-dryertimer
… which will result in a folder named core-dryertimer/, containing only the gruvin/dryer-timer project and only the last commit’s worth of history.
How to Delete Unwanted Branches in Your forked Repository
… or how I got my forked repository cleaned out to have only master and my own project branches.
Branches reside in two places – your local working copy and on the GitHub server. You have to delete each copy, separately.
To (forcibly) delete a local working copy branch, the command is
git branch -D unwanted-branch.
To delete the server repository copy of that same branch, the command is
git push origin --delete unwanted-branch
When I first forked spark/core-firmware, there were quite a few branches. It would have been tedious to delete them all, one at a time – twice, once locally and once on the server. BE VERY CAREFUL with this. But here’s how I removed all but the master branch, in just two steps …
First locally …
$ git branch -a | grep -v "master" | cut -f3,4 -d\/ | xargs git branch -D
Then on the GitHub server …
$ git branch -a | grep -v "master" | cut -f3,4 -d\/ | xargs git push origin --delete
cut -f3,4 -d\/ section is there to reduce the full branch names given by
branch -a down to the names required for the delete command. So,
remotes/origin/compile_server2 becomes just
remotes/origin/feature/foo becomes just
We have looked at a method to locally organising Spark projects under versioning control using Git. We’ve seen how to publish our work to our own GitHub repository, which more cleanly contains only our own projects plus the master branch. We saw how to update our forked repository with changes made to the upstream repository, from whence we forked.
“Eat your heart out Subversion. I’m never going back! ” – Gruvin 2014-04-22.