WHAT

Pretend you just spent a few minutes, hours, or days trying something out, and now you want to get the project off your janky laptop’s hard drive that you just know is gonna die soon.

You’ve been tracking work with git locally because it is trivial to set up:

$ cd myproject

$ vi README # pretend this is your brilliant code.

$ git init

$ git add *

$ git commit -a -m "Let's get this party started"

Now you want a single file that has your whole project and all the commits you’ve made.

You can use git bundle for this! Here is how:

$ cd myproject

$ git bundle create myproject.bundle --all

$ scp myproject.bundle example.com:/tmp/

If it helps, you can think of git bundle as kind of like tar or zip or even webpack. Those are all things that convert a big tree of stuff and spit out a single doodad.

HOW

Here is how to make a single file with everything from all branches:

$ git bundle create myproject.bundle --all

Or you can make a single file (a bundle) that has only the master branch:

$ git bundle create myproject.bundle master

Or make one just with whatever branch you’re working in now:

$ git bundle create myproject.HEAD.bundle HEAD

Now move the bundle to a remote box via scp or rsync or whatever other method you want.

You might ask why you would use rsync or scp, because they both copy a file over a secure tunnel. The only advantage of rsync is that it checks if the file needs to be copied again:

$ rsync -e ssh --verbose myproject.bundle example.com:/tmp/myproject.bundle

sent 2,793 bytes received 35 bytes 377.07 bytes/sec

total size is 2,705 speedup is 0.96

$ rsync -e ssh --verbose myproject.bundle example.com:/tmp/myproject.bundle

sent 100 bytes received 59 bytes 16.74 bytes/sec

total size is 2,705 speedup is 17.01

See how the second time I ran rsync, it only sent 100 bytes? That’s because it tested if the version of myproject.bundle on example.com was out of sync with the one here. That can really, really help when you’re on a slow connection or working with big files.

Here is how to make a new repo based on that bundle:

$ ssh example.com

$ git clone -b master /tmp/myproject.bundle myproject2

$ cd myproject2

Pretty fresh, right?

Also, the list-heads command is pretty useful for spying on what is inside a bundle file:

$ git bundle create myproject.all-branches.bundle --all

$ git bundle list-heads myproject.all-branches.bundle

5702b7e5d8dd16839850e3fbad44ee69a9411586 refs/heads/master

82a0cd0d59b4929df8ff439cede8a33bbf850cfe refs/heads/more-docs

5702b7e5d8dd16839850e3fbad44ee69a9411586 HEAD

$ git bundle create myproject.master.bundle master

$ git bundle list-heads myproject.master.bundle

5702b7e5d8dd16839850e3fbad44ee69a9411586 refs/heads/master

$ git bundle create myproject.HEAD.bundle HEAD

$ git bundle list-heads myproject.HEAD.bundle

5702b7e5d8dd16839850e3fbad44ee69a9411586 HEAD

Unless you use --all , you won’t get all your branches in your bundle! Sometimes, that’s exactly what you want. But for rookies, usually, you’re just trying to ship everything.

WHY

First of all, you can’t beat how easy it is to make a bundle and ship it:

$ git bundle create myproject.bundle --all

$ scp myproject.bundle example.com:/tmp/

Second, sure, usually, I would make a new repository on some hosted service like github or bitbucket or gitlab. And I might also make a private repository on a box I rent from Linode (that link has my referral code) or AWS EC2 or Digital Ocean.

But maybe I’m in a coffeeshop with slow wifi, and my friend is sitting right next to me, and I want to share the code with him or her, and it seems crazy for us both to communicate by sending packets around the world.

Also, Using git bundle vs pushing to a remote repository ain’t an either-or thing!

There is nothing wrong with setting up a few cron jobs to run git bundle to create some bundle files and shove them to AWS S3 or dropbox or wherever, even though you’re still paying that exorbitant github bill.