Standalone Developer and Git: How to Sync Your Local Repo Across Multiple Machines with a Remote Repository and SSH on Linux

You are a programmer, and you’ve been using git recently after you watched Linus Torvalds speak bitterly against CVS and SVN at Google’s Tech Talk last year. And, although you have git working nicely on your main box, you have multiple computers at your disposal (in your home), and you would like it if you could sync your main git repo from your main box.

Enter the remote git repository. (From now on, I’ll call my main box the remote box, and all newly to-be-synced machines local box.)

First, the requirements: apt-get install ssh. Do this on all your local boxes. To work without passwords every time you invoke ssh with git in the future, follow these steps. When it tells you to do ssh-keygen -t dsa, realize that you have to run this command on your local box (not your remote box), and NOT while logged into an SSH session. I.e., run the ssh-keygen command from your terminal. Also, you only need to follow the instructions until it says “OpenSSH to Commercial SSH”.

So now that you got SSH working smoothly across all your local boxes, it’s time to set up the git repository (“repo”) on your remote box.

  1. Either get your hands on the remote box, or use your newly-acquired SSH powers to log into it, and create two new directories, /home/<username>/git, and /home/<username>/git/myappname.git. Do it in Thunar or a terminal or wherever.
  2. Now, go into the myappname.git directory. Now type git init –bare. This will create a “bare” repo, that will eventually track all the changes. Think of it as the new “head” or “master” branch, from which all of your machines will eventually pull from. I will call this the remote repo from now on.
  3. I’ve thus far assumed that you only have 1 repository for your 1 application that you have been developing, alone, on your remote box. So before we do anything, make sure you and I are on the same page: you have the newly created bare repo from step #2, and you also have a local folder with all your source code (which served as your one and only git repo before reading this blog post). So far, so good. Now, go to this folder containing the existing git repo for your project. From here, you need to tell git that you’d like to sync this local repo with your newly created remote repo (myappname.git from step #1). The idea is to make the remote repo updated with all the changes thus far you’ve made on your local repo, with git-push, and then, from all your local boxes, do a git-pull. So from your local repo containing all your source code, type git remote add origin /home/<username>/git/myappname.git. If you decided to go the SSH route in step #1, the command would be git remote add origin ssh://username@serverURL/home/<username>/git/myappname.git. Here, origin is the nickname of the remote repo, and will be used later on with git-push and git-pull.
  4. Now, let’s actually get this remote repo up-to-date with our local repo! First, make sure that you’re on the master branch (or any other branch that’s nice and clean). We will push this branch to our remote repo. Type git-push origin master (or git push origin master if you don’t like hyphens).
  5. Almost there! Right now, your remote repo has everything you need to create a copy of the just-pushed-repo-from-step-4 on all your local boxes. Let’s do that now. From your local box type git clone ssh://username@serverURL/home/<username>/git/myappname.git. This will create a directory named myappname from your current directory, with all the source code and goodies!
  6. Lastly, let’s edit our .git/config file on ALL MACHINES (both remote and local boxes), by adding the following lines:
    [branch "master"]
        remote = origin
        merge = refs/heads/master
  7. That’s it! Now, from your local box, work and commit away!! When you’re done, be sure to push to the remote repo with git push origin master (or whatever branch name you are working on). For more info, type git remote show origin, and git will tell you which branches are tracked remotely. For our scenario, it would show the master branch as being tracked remotely. And, don’t forget to do git pull when you’re on a different box, to make sure you’re starting your work from the most recent changes.

So there you go. I read these links to write this post: ssh, git remote repos, default git push and pull. Now, all of your local boxes will function as essentially 1 repo, as long as you git push from 1 local box, and then immediately git pull from all the rest of your boxes. You also get the added benefit of having your source code copied across many machines — a good way of preventing data loss. You could probably even write a bash script so that, from 1 machine, you could execute git pull across all your other boxes to get updated, using SSH.

UPDATE October 27, 2008: Here is a transcript of the speech that Torvalds gave at the Tech Talk, for those of you who hate flash movies (like me).

FYI: Text Files from Linux to Windows XP Notepad

Sometimes when you open up in Windows XP a text file that was created by someone using Linux (e.g., an open source project developer), you’ll get a really ugly block of solid text, with the lines all wrapped around each other. For a long time, I used to get ticked off at whoever had created this file. Well, now that I’ve gotten into programming (Ruby a while back, and now, C++), I’ve now realized that it’s really Windows’ fault, not Linux’s.

In Linux, if you press ENTER to type text on a new line, the program inserts an invisible character called a newline character. This character is represented as ‘\n’ by the program. When you open up the text file later, the text editor will look at all the newline characters, and create a new line each time it finds them.

In Windows XP, and for example in Notepad (and other simple applications), the program expects two characters to denote a newline — the regular ‘\n’ AND another character, the carriage return character, or ‘\r’. Isn’t this redundant and unnecessary? If we’re editing a text file — the only thing we need is a newline character, not a newline AND a carriage return, to denote the beginning of the next line of text.

So take your frustration to Windows. Linux wins once again.