Introduction to GitInitiated by Klaatu, this open series introduces Git and the concepts behind its use in a collaborative environment.
My git workflow
In this episode of HPR I present the workflow I use to contribute to opensource projects using git. I have no idea if this workflow is something that is commonly used, but it is working for me, so I thought I’d share it with the HPR community.
The first thing I do is fork the project I want to contribute to. This is done on github most of the time, although this workflow can work on gitlab, bitbucket, or even some self hosted git platform.
Once the project is forked, I clone it on my machine :
$ git clone git://server/path/to/myproject.git
Git automatically names my remote project
Then I add a reference to the original project :
$ git remote add upstream https://server/path/to/originalproject.git
Now my local repository references my fork under the name
originand the original project under the name
In this workflow, I never work on the master branch. So, when I need to fix a bug for example, I create a new branch :
$ git checkout -b bugfix
I can then make changes, test my code, make sure everything is ok, stage and commit my changes :
$ git add . $ git commit -m "commit message"
Now I need to push this local branch to my repository on github :
$ git push -u origin bugfix
Since I forked the original project, github knows that
upstreamare linked. If there are no conflicts, github will show me a big green button to create a pull request. Once the pull request is created, I just have to wait for the maintainer to merge it in
upstream’s master branch. Then, I need to sync both my local copy and my fork on github with the original project. In order to do that, on my local copy, I checkout my master branch, fetch
upstream’s changes, and merge them :
$ git checkout master $ git fetch upstream $ git merge upstream/master
Now my local master branch is ahead of
origin’s master branch, so I push those changes to github :
$ git push
I don’t need the
bugfixbranches (the local one and the github one), so I can delete those :
$ git branch -d bugfix $ git push origin -d bugfix
And now, my local repository is even with both
upstream, and I can start again.
To summarize, here’s the complete workflow :
$ git checkout -b myawesomefeature $ git add . $ git commit -m "Awesome commit message" $ git push -u origin myawesomefeature
Create a pull request, wait for the maintainer to merge it.
$ git checkout master $ git fetch upstream $ git merge upstream/master $ git push $ git branch -d myawesomefeature $ git push origin -d myawesomefeature
Tag a commit:$ git tag 0.1 $ git tag 0.1
Delete a tag:$ git tag -d 0.1
Get the latest commit hash:$ git rev-list --tags --max-count=1 94c5715694c5715687a962008dd71191460fc4e32370425a
Get any tag on a commit:$ git describe --tags 94c5715 0.1
Clacke mentioned SparkleShare in episode 2542, and it occurred to me that not everyone knows what Sparkleshare is. So here's a show about it.
To setup SparkleShare, refer to SparkleShare.org. It's available for Linux, Windows, and Mac; great for cross-platform collaboration.
The Linux installer uses FlatPak, so you do need to install that.
Once installed, launch SparkleShare in the usual way. If you have no usual way, you can use this command:$ flatpak run org.sparkleshare.SparkleShare
The first screen asks for your name and email. This doesn't have to be your real name and email, but it is what SparkleShare will use when making commits on your behalf. This name and email will be visible to anyone who can see your online Git repository.
The next screen displays the Sync Remote Project screen. You use this screen any time you want to add another share to your sparkle.
In this episode, I set up two projects: one brand new one using my home server as host, and one that mirrors an existing project on Gitlab.com.
Adding a project from Gitlab
The first thing you must do is give SparkleShare permission to access Gitlab. To do this, click on the SparkleShare icon in your system tray > SparkleShare > Client ID and copy your ID to your clipboard.
Now go to your online Git host and add this "Client ID" to your approved SSH Keys. Where this is located depends on your Git host, but in Gitlab, it's located in the left column of the Settings screen. When your SSH Key has been added, Gitlab displays a key fingerprint (actually just a string of numbers) as confirmation.
The path to your remote Git repository is the part of an URL after the host. It usually starts with your username. For example, if I have a project on Gitlab located at
gitlab.com/notklaatu/foo.gitthen the path that SparkleShare needs is
Click the Add button to add the project to your local SparkleShare folder.
Adding a project hosted on your own server
There are a lot more variables if you're hosting a Git repository on your own server. These are the things that you may need to account for:
Is your local .ssh/config file setting some "invisible" defaults for when you SSH to your server? If so, you may need to modify or add an entry for SparkleShare.
Your SparkleShare auto-generated "Client ID" is located in
Is your SparkleShare SSH key (the "Client ID" in SparkleShare lingo) in your authorized_hosts file?
Does a Git repository exist on your remote server in the location you think it exists?
Use SparkleShare exactly as you would DropBox or the NextCloud Desktop Client: drag-and-drop a file to add it, drag it to the Trash to delete it. All SparkleShare folders sync'd with any given project syncs automatically through the magickalfulness of Git hooks.
This episode is light on actual commands, and mostly a narrative analysis of what git HEAD is and why it matters to you.
Some commands you can try:
$ cat ~/path/to/git/repo/.git/HEAD
$ ls ~/path/to/git/repo/.git/refs $ cat ~/path/to/git/repo/.git/refs/master
These are all the commands covered in this episode. This is not a sequence, it's just all the commands in the episode, listed one after another.
Get changes from the remote repo:
$ git fetch
See all branches:
$ git branch --all
View a remote branch after you have fetched it:
$ git checkout origin/dev
Create a copy of a fetched remote branch in your local repo:
$ git checkout dev
Merge changes from remote origin/master into your local master branch:
$ git merge master origin/master
Fetch and merge automatically:
$ git pull
Create a new branch, and change to it:
$ git checkout -b dev
Merge dev into master:
$ git checkout master $ git merge master dev
Merge master into dev
$ git checkout dev $ git merge dev master
Delete the dev branch:
$ git branch -d dev
Instantiate a git repo:
$ mkdir alice $ cd !$ $ git init
Add a remote:
$ git remote add origin URI_OF_REMOTE
Change a remote:
$ git remote set-url origin NEW_URI
A remote can be a server, it can be a local directory, an NFS share, pretty much whatever you want.
It is a Git convention that the primary remote is called
origin. You don't have to call it that, but it's pretty common.
git add git commit -m "some useful message" git push origin HEAD