Git is usually used in synchronization with GitHub — the former is a source code management system and the latter is a website where you can share/contribute Git repositories with the larger internet community.

For those wanting to get started with GitHub, I've written this Instructable: Introduction to GitHub.

But, what if you want to keep your repositories private? The usual answer is that you have to pay for this service. Boo.

A lot of us have code-in-progress that we want to properly put onto the Git system, but ins't ready for public consumption. Nor do we want to pay for the service of private hosting.

However, using the Raspberry Pi, you can set up your own Git server on your home network.

This Instructable will cover setting up your Raspberry Pi as a Git server with repositories saved onto an external USB thumb drive. My example uses the Mac OS, but can be extended to other platforms as well.

You should already have Git installed on your laptop and know the fundamentals of how to use it. Check out the Introduction to GitHub Instructable if this is not the case.

I've used two sources to figure out how to set up GitPi: a guide  by Thomas Loughlin and one by Monkey Hacks.

They're both good, but neither one did exactly what I wanted or explained it fully, which is one reason I wanted to write this Instructable.

Step 1: Set up your Raspberry Pi for ssh

First, setup a Raspberry Pi for ssh access and that it's on your home wifi network, which means that you can log into it from your laptop.

I wrote this Instructable: Ultimate Raspberry Pi Configuration Guide, which covers how to do this.

Once you go through these steps, you'll be able to transfer files to your Raspberry Pi via the Terminal application.

Note: I'm using a Mac for this Instructable, but you can extend this to other platforms.

Step 2: Init the USB thumb drive

We will save all the Git repositories onto a USB thumb drive, rather than the Raspberry Pi's SD card.

This will give you an independent storage drive for your Git repositories, which is easily-readable on your laptop.

Open Disk Utility. Erase the USB drive, format as MS-DOS (FAT) and call the volume GITPI. I also use a labelmaker to affix a label on the back so it doesn't get mixed up with my other USB thumb drives.

Mine is 16gb, which should be plenty.

Step 3: Run latest package updates

Connect via ssh into your PI. My IP address for the SD card for this is Yours may be different — just change the address accordingly.

Open the Terminal window and on the command line, type:
ssh pi@
Run the latest package update and upgrades, just to make sure everything is current.

First the update:
sudo apt-get update
Then the upgrade:
sudo apt-get upgrade
Then reboot:
sudo reboot

Step 4: Install Git on the Raspberry Pi

Install git:
sudo apt-get install wget git-core
You'll see terminal output. In this case, the packages were already installed (maybe with the update/upgrade from last step), but you see some sort of success at this point.

Now, turn off the Raspberry Pi by unplugging the micro USB power cable.

Step 5: Permanently mounting the USB drive

Put the formatted USB drive into the Raspberry Pi. And turn the Pi back on.

I'm not sure if this matters, but I always leave the wi-fi dongle in the lower USB port and use the upper one for the external USB drive/keyboard/other things.

Wait a few seconds and then ssh back into the Pi.
ssh pi@
What we then type in;
mkdir usbdrv
What we are going to set up is a mount point — a way to always map this directory to the USB drive.

now, type in:
sudo blkid
check out output — we are looking for the USB drive device info, which is easy to identify because we called it GITPI when we initialized it.

Mine reads:
/dev/sda1: LABEL="GITPI" UUID="6D34-1514" TYPE="vfat"

This should be the similar on yours: /dev/sda1 is the USB thumb drive device.

Now, we are going to edit what is called the file systems table to make the USB drive map into the usbdrv directory

Type in:
sudo nano /etc/fstab
Here is the tricky part. We are going to modify the fstab file so that this device maps to the usbdrv directory.

add the line to the end of the file (you can copy and paste this line)

/dev/sda1 /home/pi/usbdrv vfat uid=pi,gid=pi,umask=0022,sync,auto,nosuid,rw,nouser 0 0

important: this is 1 line, not broken up over two lines (the Instructable is doing weird things to the formatting).

What this does is to map the /dev/sda1 device — any thumb USB drive to the usbdrv directory. The flags are ones that I cribbed from the Thomas Loughlin guide. Admittedly, I'm not sure exactly what they do, except for allow the drive to be a read-write drive and not tied to a specific user.

Cntl-X, Y, Return to save.

Then restart:
sudo reboot

If you want to learn more about drive-mapping and mounting, this eLinux Guide has a lot more information.

Step 6: Test the USB transfer

After your Pi reboots, you'll have to ssh into it again.

Then, on the command line:
nano usbdrv/test.txt
This will create a text file in the usbdrv directory — which is actually the USB thumb drive itself called test.txt. Put some text in the file, like mine pictured here.

Cntl-X, Y, Enter to save

At the command line:
ls usbdrv
And you'll see a lone file, test.txt.

Turn off the Raspberry Pi. Pull the thumb drive and mount it onto your laptop.

Presto! You can read the text file on your laptop. Delete the file, pull the drive, put it back into your Raspberry Pi and power the Pi back up.

The cool thing is that the Git repositories can be read by your computer and are not tied to the Pi. The usbdrv will always mount to whatever USB drive you put into the Pi. If you have source code overflow problems, you can always swap out USB thumb drives.

Step 7: Set up your Pi Git directory

This Instructable doesn't go over Git repositories in general, so I'm going to assume you have your local (on your laptop) Git repository configured.

I'm currently developing a Twitterbot called justdiedbot, which you will hear more of down the the road. It's not as morbid as it sounds, and this is part of my ongoing "Bot Collective" project, which is a series of Twitterbots.

Just to show how it's done it, here are my steps for local Git configuration. Open a separate Terminal window and type in (using your source directory, not mine).
cd /Users/scottkildall/PythonScripts/justdiedbot
git init
Now, do a similar thing on your Raspberry Pi. In a second Terminal window, ssh back into the Pi. We are going to create a directory called justdiedbot and initialize it with Git. Once again, substitute your source directory names rather than using mine.
mkdir usbdrv/justdiedbot.git
cd usbdrv/justdiedbot.git
git init --bare
This creates a new directory with a .git extension and an empty Git repository. For the geeks in the audience, here is a detailed discussion of what the --bare flag does.

You'll repeat this step for each source code directory that you'll be using for your GitPi activity.

Note: some readers of this Instructable have reported that you need to call "sudo" before the git init steps, so if you have permissions errors, type in: "sudo git init"

Step 8: Add the remote to the Pi

Now, back to your 1st Terminal window — the one that matches your local (laptop).

First, navigate into you local directory, for example:
cd /Users/scottkildall/PythonScripts/justdiedbot
Of course, you should type in your local directory path. One trick with the Finder is that you can drag-and-drop the folder to complete the path, typing in 'cd ' and then drag the folder into the Terminal window.

Add a remote to the pi. A remote essentially is a shortcut to a longer URL/path. The user is pi@ — the same one that we are using for ssh.

Make sure to substitute your Pi's IP address and your own source code-named .git directory instead of mine. Type in (once again, subbing your own IP address and source directory)
git remote add pi pi@
You only have to add the remote one time. From here on out, we will refer to this remote as pi.

Step 9: Push the code onto the Pi

Simple, type in:
git add .
git commit -m "initial commit"
git push pi master
This will add all the files in the justdiedbot directory, commit the adds with the message, then push them onto your GitPi.

You'll see some output, showing (hopefully) the successful results.


Step 10: Done! Take a look

If you put the USB thumb drive back onto your laptop, you'll have access to all the Git files, seen here.

For future source code management for a project, simply repeat step 9.

To add more projects, repeat source code steps 7-9.

This is completely compatible with GitHub, since you'll be using a different remote for GitHub, so when you're ready to go public, you can put your repositories on GitHub and still use your Pi as your home backup.

I hope this was helpful!
Scott Kildall

For more on Raspberry Pi code and other projects, you can find me here:
@kildall or www.kildall.com/blog
hi<br><br>i tried it but with few changes. when adding your pi to the git, instead of the above code... do the following<br><br>git remote add pi ssh://pi@192.168.1.x:/path/to/git<br><br>add the &quot;ssh://&quot; beforehand or you will get an error message. if you're using custom port other than 22, just do this<br><br>git remote add pi ssh://pi@192.168.1.x:119/path/to/git<br><br>where 119 is your custom ssh port<br><br>hope that makes sense.
<p>Thank you so much! Got a private git server!</p>
<p>Caution! This guide in combination with raspbian Jessie ruined my day!</p><p>If the entries in /etc/fstab are wrong, Jessie will only boot into &quot;emergency mode&quot;, in which you can't connect to it via ssh. With no USB keyboard and micro SD card reader at hand, i'm pretty much locked out of my pi right now :(.</p><p>So i strongly suggest to double check the /etc/fstab entries before rebooting. The mounts specified in the files should in fact be executed once you save the file. Check if the mount can be executed with </p><p>sudo mount -a</p><p>before rebooting!</p>
<p>You can also add the 'nofail' flag to the entry, it should boot through anyways.</p><p>I've never had problems since I started using that flag.</p>
<p>At step 4 you instruct to turn off the RPI by unplugging it : doing this may CORRUPT THE SD CARD. You must turning it off with the command : &quot;sudo halt&quot; and THEN unplugging it.<br>Please modify your guide.</p>
<p>Amazing Tutorial. Thank you for this, I was able to get a usb stick gitting on my pi in 30min. No permissions problems either!</p>
<p>Thanks!</p><p>Works great!</p>
<p>Hi @kilall,</p><p>Its a great guide to set up a git server.</p><p>I have made a script to create project folders by keeping this file in the home folder and making it executable by &quot;chmod a+x create_project.sh&quot; and running it by following command</p><p>ssh pi@&lt;raspberrypi's IP&gt; ./create_project.sh &lt;project_name&gt;</p><p><a href="https://www.dropbox.com/s/u77ydkhbjp4hdkm/create_project.sh?dl=0" rel="nofollow">https://www.dropbox.com/s/u77ydkhbjp4hdkm/create_p...</a></p>
<p>Was able to couple this with an external drive project using an authenticated share. Great tutorial! Thanks for sharing this.</p>
<p>Hi, thx you for this tutorial.</p><p>It's work very well on my first test.</p><p>But I try to create another project and I ve this error :</p><p>&quot;src refspec master does not match any&quot;.</p><p>I miss something? Where I can search?</p><p>Thx you for your support.</p>
This looks like an error with git, as opposed to the Pi more generally.<br><br>Did you try any of these solutions here? I've never actually seen this before, but I do know that git can be an ornery beast at times.<br> <br>http://stackoverflow.com/questions/5802426/git-error-src-refspec-master-does-not-match-any<br><br>http://stackoverflow.com/questions/10568641/git-error-src-refspec-master-does-not-match-any<br><br>
<p>Well I already try this solution yesterday but doesn't work :</p><p><a href="http://stackoverflow.com/questions/5802426/git-error-src-refspec-master-does-not-match-any" rel="nofollow">http://stackoverflow.com/questions/5802426/git-err...</a></p><p>I retry today and now it's fix my problem. I Suppose I made a mistake yersterday.</p><p>Anyway, thx you for your support, and sry for my bad english ;)</p>
Nice instructable! One question &mdash; wouldn't formatting the USB drive as FAT reduce Git's performance? On UNIX systems (like what's run on Raspberry Pis), Git takes advantage of hard links, which FAT file systems don't allow for (unless exFAT or vFAT do?). You might be better off using ext4 or even HFS+.
<p>Good point and good advice. I didn't know about the performance issues with FAT.</p><p>The main reason I stuck with the FAT file system was that it was the easiest for cross-platform compatibility.</p>
<p>In Step 7,Not able to create project repository project.git without sudo, in your step 6, you have used sudo to create test file, so it worked. Also, the ownership of usbdrv directory is taken by root everytime I boot pi.</p>
<p>Thanks, I adjusted the Instructables text to reflect your notes.</p>
<p>In Step 7,Not able to create project repository project.git without sudo, in your step 6, you have used sudo to create test file, so it worked. Also, the ownership of usbdrv directory is taken by root everytime I boot pi.</p>
<p>In Step 7,Not able to create project repository project.git without sudo, in your step 6, you have used sudo to create test file, so it worked. Also, the ownership of usbdrv directory is taken by root everytime I boot pi.</p>
<p>In Step 7,Not able to create project repository project.git without sudo, in your step 6, you have used sudo to create test file, so it worked. Also, the ownership of usbdrv directory is taken by root everytime I boot pi.</p>
<p>I notice you have not added anything about security and using public keys? How do you you handle that?</p>
<p>Here is a handy tip. The UUID does not change, even if you insert the disk into a different USB slot. This makes it a good idea to use the following format in /etc/fstab</p><p>UUID=df963a07-0d4e-41f4-a5e0-1a638f41f31d /mnt/usb/ ext2 defaults,......</p>
<p>Before you unplug the micro USB power supply remember to issue the command</p><p> `sudo shutdown -h now`</p><p>or</p><p> `sudo init 0`</p><p>to make sure the disks are sycned unmounted.</p>
<p>Just wanted to point out here that initialising the repository on the &quot;laptop&quot; is not necessary.</p><p>If you've initialised the bare repository on your Pi, you can simply clone it onto your &quot;laptop&quot; without any further configuration.</p><p>Using your example, you can just run the below command:</p><p>`git clone pi@`</p><p>It saves having the perform any of the localised initialisation steps from this and the previous step; correct me if I'm wrong!</p>
<p>Hey thanks for posting this :D My pi is already a web server and a platform for any custom servers I write, but now a code repository as well! </p>
<p>Another awesome tutorial, thanks Scott. Between this and your Ultimate guide I'm all set! I would like to learn more about the pi still and was wondering if you had a good resource for instructions on navigating and managing file structures via command line (ssh)? I'm having a hard time getting those skills down.</p>
<p>hey, apologies for the slow response. I was off-the-grid for a couple weeks.</p><p>I use just some basic commands to move around: ls to see files, cd to move between directories, scp to copy from your computer to the Pi, cp and mv to copy or move files, etc. Some of the wildcards are helpful, too, like *.</p><p>Usually what I do is to search for what I want to do and then use that command. For the Pi, basic Linux commands are just about all of what you need. </p>
<p>very useful !!!!</p>
<p>Great article. Very clear and well thought out. I hit one small snag in step 8: I kept getting errors (e.g. &quot;fatal: Not a git repository (or any of the parent directories): .git&quot; and &quot;GIT_DISCOVERY_ACROSS_FILESYSTEM&quot;) until I figured out that I had to be in an existing local repo folder before executing the &quot;git remote add...&quot; command. (Guess the &quot;Not a git repository&quot; clued me in ;) Once I moved into a (local) repo folder, the command worked great. Thanks again for a nice tutorial.</p>
Thanks for the feedback.<br><br>Good catch! I added a few sentences about navigating into the local directory.

About This Instructable




Bio: Scott Kildall is an artist who indulges in network performances and creative coding. He currently is an artist-in-residence at Autodesk.
More by scottkildall:CNC: Fusion 360 to OMAX Waterjet Strewn Fields: Waterjet Etching Into Stone Pier 9 Resource: Setting up 2D profiles for CNC in Fusion 360 
Add instructable to: