Easy Version Control: Git on Dropbox

The problem: you need to share files with people on an ad hoc basis for a project.

One choice is sharing files with Dropbox. On the plus side of Dropbox is it’s ease of use, however, there is a drawback that if you work on the same files you get “My conflicted copy of x” spawning everywhere and making a mess. If you are coding you will trip over other author’ changes.

To work around that problem you need version control. But that can come with baggage. You’ll need a server to run a git/svn/cvs (infrastructure), or a project on GitHub/sourceforge/google code (open source requirement, or pro account). Some projects don’t have these resources or freedoms, so they do without version control, but there is another way…

You can run the best version control software from inside a Dropbox folder! (or Google Drive) Running git from a Dropbox folder does not require spending money, having a server or open sourcing files. Because git compresses its repositories, it also reduces your Dropbox quota usage. Awesome! And it is easy to install. In this article I will show you how to set everything up properly, and give you a quick user guide to git incase you (or your collaborators)  have not used it before. By the end you should be able to setup and use git like a true intermediate.

Installation

Let ~/Dropbox/ be a directory in your Dropbox system (syncs with everyone the folder is shared with)

So you have a local project on

  ~/myproject/

that you want to share with everybody. Initialise the .git database with

  cd ~/myproject/
  git init

then add everything in the current directory into the git version control (add a .gitignore filter first if you want one)

  git add .
  git commit -m "Yo my first commit"

clone the database and send it to a Dropbox folder to create ~/Dropbox/myproject/

  cd ~/Dropbox/
  git clone --bare -n ~/myproject/

NOTE: You now have the version control setup, but ~/myproject is UPSTREAM of ~/Dropbox/myproject/ Move it elsewhere for now (and delete it later)

  mv ~/myproject/ ~/myproject-backup/

Clone the repository

the directory ~/myproject will be created and will be the working copy that is actively edited on every team members local machine

  cd ~
  git clone ~/Dropbox/myproject/

Tada! Now some basics of git to get everyone started

Add/Update a file

Use git status copiously and understand it

create a file call test.txt

  cd ~/myproject/
  git status
  git add test.txt
  git status
  git commit -m "test I can add stuff"
  git status

At this point the file test.txt is known by the git database locally but not by the Dropbox system (“Your branch is ahead of ‘origin/master’ by 1 commit.”). So you’re collaborators can’t access it until you push it.

  git push

Note that after a push the Dropbox will show some activity as the ~/Dropbox folder has just been written to. Once everyone’s Dropbox has synced they can pull it. If you can’t push it might because someone else has modified the repository and you need to do a pull first.

The git philosophy is commit often (locally) every atomic piece of functionality you do. When you are ready to share a collections of changes with everybody, do a push.

Pull everyones changes

To pull the repo (kinda like svn update), and merge with your local changes

  cd ~/myproject
  git pull

Merge resolution (God forbid)

 From /home/tom/Dropbox/myproject
 c642398..2609f26 master -> origin/master
 Auto-merging test.txt
 CONFLICT (content): Merge conflict in test.txt
 Automatic merge failed; fix conflicts and then commit the result.

I don’t expect this to happen often as when git merges it normally does a good job. There is clever stuff you can do when you have problems. However, the main reaction of users in the wild when confronted by merge problems is to delete all changes except one master copy. This is how you do that style of merge conflict (the one everyone can understand) on the computer with the master copy.

If you have just done a git pull and a load of muck has appeared on you beloved ~/myproject/. Go back to its state before the git pull

  git reset --hard

double check there are no merge gunk with:-

  grep -r "<<<"

To inform your local database of the servers information, *without messing with your working copy*

  git fetch

To get our local changes to the project to be favoured over the servers. We merge using a non-default merge stratergy called ours.

  git merge -s ours origin/master

No we can push that over the server.

  git push

Let the pulling begin…

Keeping crap out with a .gitignore

add a file to

  gedit ~/myproject/.gitignore

each line can be a pattern of files to ignore e.g.

*.pyc
 *.o
 bin/*
 .*.swp

Temp files in a Dropbox can cause lots of conflicts. These are exactly the kind of files you want to match with a pattern in the .gitignore

I find I have one master .gitignore I just keep adding to every project I work with. Think of it as a baby, it reflects your characteristics, make it nice!

Conclusion

Congratulations! You can now setup Git in a Dropbox account, and can even fix merges in a basic way. Git can get a lot more powerful if you want, or you can leave it at that. If things go horribly wrong you can roll back to earlier states. If you want a usable permission model then the next logical step is a gitolite server (but you do need a server then).

I recently switched a 2 person python project from just sharing development files in a Dropbox folder to running git in Dropbox. Just from excluding compiled python .pyc files we reduced our conflict ridden Dropbox folder from 250Mb to 150Mb. After this was compressed to a bare repository the whole project fitted into a 23Mb folder in our Dropbox. Yes, it compressed by a factor of x10.

Of course the real gain was in productivty from having vesion control, and its all possible without a server or money in an agile way (1 hour).

Footnote: For the windows instructions replace ~ with C: and make sure you remember git was created by Linux Torvalds of Linux fame if it strays into conversation.

9 thoughts on “Easy Version Control: Git on Dropbox

  • “You’ll need a server to run a git/svn/cvs (infrastructure)”

    No, you don’t for git, and this is important. Git is designed as a distributed version control system. Any repository can push and pull to any other. The use of central server in the same way as with svn is a common model, particularly where one official state of the project is desired, such as in a company, but it’s not necessary.

    You can push and pull repos directly to each other over ssh or https. Other ways to synchronise git repositories include email and XMPP. Emailing patches is well supported by git. I also came across this project to push over xmpp (e.g. Google Talk): http://joeyh.name/blog/entry/git_push_over_XMPP/

    • If you want 24 hour integration you need those services running on a server 24/7… which is my point. OK, if you want to be pedantic one way for a 3 person team without a central server is for A, B and C need to run ssh servers on their local machines. 2 of the 3 will need their computers turned on at the same time, with their IP addresses publicly available to be able to sync with each other. Setting up such a system will take *much* longer than an hour, and every person will have to do it instead of just one…

      On the other hand Dropbox is on all the time and that means ad hoc groups can share stuff around even when people are asleep. Git on Dropbox is a practical solution for people with limited time and expertise.

  • What happens when two people are pushing to the dropbox repository simultaneously? It seems that you would get conflicts in the internal git files, causing quite a mess.

  • Hey, this is great, thanks, I will try it now to write my thesis (which is still ahead, but better first get used to the backup system, right?)

    While trying to implement I ran into the problem that I couldn’t push at first, as I used the option -bare instead of –bare.
    Might wanna correct that typo so other people don’t run into the problem.

    Thanks for the how-to!
    Tristan

Leave a Reply

Your email address will not be published. Required fields are marked *

72 − 71 =