1 #+TITLE: Putting Your org Files Under Version Control.
3 #+EMAIL: ian@manor-farm.org
6 #+OPTIONS: H:3 num:nil toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t TeX:t LaTeX:t skip:nil d:(HIDE) tags:not-in-toc
11 Since I discovered org mode it has gradually become my "Information
12 sink" and most of my life seems to have moved into it. I wanted a
13 system that allowed me to move my org files around between different
14 computers which was easy to use and kept my files under version control.
16 I use bzr for my version control, but the system I describe should
17 work with any of the distributed VCS systems, such as Mercurial and
18 git. Since org mode is maintained in git and many org users are using
19 git, I have tried to give examples using both bzr and git.
21 This isn't intended to be an in depth discussion of version control,
22 but more of a quick overview of how you can use a version control
23 system with org to keep various computer in sync and as a backup system.
25 At home I normally work with my org files on an nfs share using one of
26 our desktop computers. The org files themselves are stored on my local
27 server. They are also automatically mirrored with a repository on my Web
30 If I go away before I set off, I will update the local branch of my
31 org files that I keep on my notebook using bzr. If I forget to update
32 my local copy, I can update my notebook repository from my home
33 server, or my web server as long as I have an Internet connection.
35 If I can't connect to the Internet, the org files on my notebook are
36 not usually more than 24 hours out of sync with the copy on my
37 server. I can carry on working and then merge my changes when I get
38 home, or can access the Internet.
41 I am assuming you already have Emacs and org installed. If you are
42 using a Debian based system installing git and bzr is simply a matter
45 #+BEGIN_SRC emacs-shell
46 apt-get install bzr bzrtools
50 If you want to push changes to a remote server, you might also want to
51 install the ncftp client.
54 ** Creating a Repository.
55 The first step is to create a repository in the directory where you
57 #+BEGIN_SRC emacs-shell
65 #+BEGIN_SRC emacs-shell
69 *** Excluding Files from the Repository.
70 You might have things, such as emacs backup files, in your org
71 directory that you don't want included in your VCS. A simple way to
72 avoid them being added is to create a .bzrignore file in the org file
75 In my .bzrignore I simply have:
77 #+BEGIN_SRC emacs-shell
81 With git you can create a .gitignore file, which has a very similar
84 ** Adding Files to Your Repository.
85 Now you need to add your org files to the repository. In the directory
86 where you keep you org files:
88 #+BEGIN_SRC emacs-shell
94 #+BEGIN_SRC emacs-shell
98 ** Committing Changes.
99 Once you have added your files to the repository you need to commit
100 the changes to update the repository:
102 #+BEGIN_SRC emacs-shell
103 bzr commit -m "Imported sources."
108 #+BEGIN_SRC emacs-shell
109 git commit -a -m "Imported sources."
112 Commit makes a snapshot of the working state of the files. You can
113 choose to commit changes at any time. There are several Emacs
114 packages, which will let you do this directly from Emacs. I also run a
115 cron job which commits any changes automatically each evening. The
116 shell script I use is:
118 #+BEGIN_SRC emacs-shell
121 bzr commit -m "automatic commit via cron."
124 If you want to commit files selectively, rather than all uncommited
125 files, you can specify the file names on the command line:
127 #+BEGIN_SRC emacs-shell
128 bzr commit -m "Made some changes." myfile.org another_file.org
131 * Working With Your org Files On More Than One Computer.
132 You will probably want to work on your org files on more than one
133 computer. The traditional method would be to copy all your org files
134 between your various computers. This is error prone and you
135 might end up accidentally overwriting new files with older versions.
137 A better way to synchronise files between your computers is to use
138 your version control system. Not only do your org files get updated,
139 but you also get their complete version history. The steps you need to
140 take to maintain versions of your org files on different computers are
143 Note that there are several methods which you could use, the one I
144 describe works for me.
146 ** Creating a Local Branch.
147 First create a local copy of your org files by making a branch. You
148 can then continue working on your files locally and then use bzr or git to
149 merge changes back to your main copy of org when required.
151 To create an initial working branch on your local computer:
153 #+BEGIN_SRC emacs-shell
154 bzr branch ~nfs/firewall/Documents/org ~/Documents/org
158 #+BEGIN_SRC emacs-shell
159 git clone ~nfs/firewall/Documents/org ~/Documents/org
162 This command creates a local branch on my notebook from the repository
163 on my file server. Note that bzr and git will create the directory for
164 the branch. If the directory already exists you will get an error.
166 The general format of the branch command is:
168 bzr branch location directory
170 bzr understands a wide variety of transport protocols, which you
171 could use to create your initial branch:
173 |------------+-------------------------------------------------------------|
174 | aftp:// | Access using active FTP. |
175 | bzr:// | Fast access using the Bazaar smart server. |
176 | bzr+ssh:// | Fast access using the Bazaar smart server over SSH. |
177 | file:// | Access using the standard filesystem (default) |
178 | ftp:// | Access using passive FTP. |
179 | http:// | Read-only access of branches exported on the web. |
180 | https:// | Read-only access of branches exported on the web using SSL. |
181 | sftp:// | Access using SFTP (most SSH servers provide SFTP). |
182 |------------+-------------------------------------------------------------|
184 You now have a complete copy of your org files from the file server
185 and their version history in ~/Documents/org. You can simply fire up
186 Emacs and work on the org files in that directory.
188 If you use git the syntax is very similar. This example uses ssh:
190 git clone url directory
192 git clone ssh://ian@mycomputer.co.uk/~/Documents/org ~/Documents/org
194 At any point you can commit your changes to the local repository using
197 #+BEGIN_SRC emacs-shell
198 bzr commit -m "Committing changes made on my notebook."
201 ** Merging Changes from a Local Branch to Your Server.
202 When you return back home or to the office, you will probably want to
203 update the copy of org on your local server from your notebook:
205 - First you need to commit any local changes that you have made.
207 - Next you need to use the push command to send your changes back to
208 the server. The basic command is:
210 #+BEGIN_SRC emacs-shell
214 If you don't specify a destination location the push is made to the
215 branch that this branch originated from. If you are the only person
216 working with your org files, the push should update your remote copy
217 without requiring any further action. If there are any conflicts take
218 a look at the bzr manual on Resolving Conflicts for more information
219 on how to fix the conflicts.
221 Note that once the push has completed the it needs to be
222 committed on the server to update your working tree:
224 #+BEGIN_SRC emacs-shell
225 cd ~/nfs/firewall/Documents/org
226 bzr commit -m "Merged changes from my notebook."
229 Up to the point of committing the merge you can choose to throw away
230 any changes by using the revert option in bzr.
232 Git uses the same command:
234 #+BEGIN_SRC emacs-shell
238 Unlike bzr, git will auto commit changes after a merge. If you don't
239 like this behaviour use the --no-commit option to make it behave like
242 ** Updating an Existing Branch of Your org Files.
243 Once you have a local branch on your computer, you can update it from
244 your server at any time using the following command:
246 #+BEGIN_SRC emacs-shell
250 By default pull uses the location where you originally branched
251 from. this will pull any changes from the remote location and merge
252 them with your local copy.
254 The command with git is the same
256 #+BEGIN_SRC emacs-shell
260 * Creating a Central Repository.
261 In order to give your system maximum resilience you may want to create
262 a central repository somewhere off site that is accessible from the
263 Internet. Using an off site server will also increase your backup
266 Typically you will only want to store history and not working copies
267 of your files in your central repository. So you can create the repository with the
270 #+BEGIN_SRC emacs-shell
271 bzr init-repo --no-trees sftp://myserver.com/bzr/myrepo
274 You can now use bzr to push your local branch to the central
277 #+BEGIN_SRC emacs-shell
279 bzr push sftp://myserver.com/bzr/myrepo/org-files
282 Git is a bit more complicated. See http://www.netsplit.com/?p=192 for
283 a laconic view of the problems. The first time you want to push your
284 changes to a remote server you need to create the bare repository on
287 #+BEGIN_SRC emacs-shell
288 git clone --bare . ssh://myserver.com/git-repo/org.git
291 Once you have created the remote repo, you should be able to push
292 subsequent changes using:
294 #+BEGIN_SRC emacs-shell
295 git-push push origin master
297 ** Using a USB Stick as a Central Repository.
298 You can create a central repository on a USB stick. You might want to
299 do this if you take files between your home and work computers and
300 can't use the internet to synchronize your files because there is a
303 There are some special considerations required when using a usb stick:
305 - You need to specify that you can used mixed case in filenames, or
306 you will have problems creating names like HEAD with git. Note this
307 is only a problem with usb sticks formatted as FAT or VFAT.
309 If you are using the gnome desktop fire up gconf-editor and navigate to
310 system->storage->default\_options->vfat. Edit the key "mount_options"
311 and change its value to [shortname=mixed,uid=].
313 This option is the default with recent versions of Ubuntu such as
316 *** Creating the Repository on the USB Stick.
317 Using bzr to create a bare repository:
319 #+BEGIN_SRC emacs-shell
320 bzr init-repo --no-trees /media/disk/bzr-repo
323 Now populate the repository with your org files:
325 #+BEGIN_SRC emacs-shell
326 bzr push file:///media/disk/bzr-repo
329 Using git the comand is:
331 #+BEGIN_SRC emacs-shell
332 git clone --bare ~/Documents/org /media/disk/org.git
335 Once you have made the initial push you can sync your changes to the
338 #+BEGIN_SRC shell-script
341 # bzr will default to using the saved initial location,
342 # so you don't need to specify a location.
346 #+BEGIN_SRC emacs-shell
347 git push origin master
350 The git example assumes that the remote on the usb stick is named
351 "origin" (the default) and the branch that you want to push from is
352 named "master" (the default).
354 *** Getting Your org Files from the USB Stick.
355 To get your org files from the usb stick on another computer for the
360 #+BEGIN_SRC emacs-shell
361 bzr branch /media/usbdisk/bzr-repo ~/Documents/org
365 #+BEGIN_SRC emacs-shell
366 git clone /media/disk/org.git ~/Documents/org
369 In subsequent sessions, once the local repository has been populated,
370 you should use the "pull" command.
372 *** Getting Your Local Changes onto the USB Stick.
373 When you have finished working on your local org files you need to
374 commit your changes to the local repository:
376 #+BEGIN_SRC emacs-shell
377 bzr commit -m "Commit before push to usb stick."
380 #+BEGIN_SRC emacs-shell
381 git commit -m "Commit before push to usb stick."
384 To update the repo on your USB stick you need to push your changes:
386 #+BEGIN_SRC emacs-shell
390 #+BEGIN_SRC emacs-shell
394 Assuming that you have sucessfully set up a repo on your usb stick and
395 have repos on your work and home computers your work flow would look
400 Commit your changes (=bzr commit=)
401 Push the changes to your usb stick (=bzr push=)
404 - Plug in your usb stick.
405 - Get the changes - =bzr pull=
406 - Work on your files in Emacs.
407 - Commit the changes you made - bzr commit -m "Commit before push to usb stick."
408 - Push your changes to the usb stick - =bzr push=
409 - Unplug the usb stick and go home.
410 ** Update the Local Branch on Your Notebook from the Central Repository.
411 Sometimes you might want to update your local branch from your central
412 repository, rather than from your local server. One reason for wanting
413 to do this is if you are away from home and your local computer's
414 branch is quite out of date. If you automatically update your central
415 repository daily from a cron script, the files on there should never
416 be more than one day old, so if you have an Internet connection you
417 can get a more recent version of your files from the central repository.
419 The pull command will do this, but you need to specify the location on
422 #+BEGIN_SRC emacs-shell
423 bzr pull sftp://myserver.co.uk/my_repo/org
427 I have three different scenarios for using my system:
430 My org files are on my home server in a directory accessible via
431 nfs. I can either load my files via an nfs share, or run Emacs in a
432 terminal on the file server.
435 Update the files on my laptop before I leave:
437 #+BEGIN_SRC emacs-shell
442 Launch Emacs using a different .emacs, which has its org configuration
443 set to point to the files on my local hard disk, rather than the nfs
446 When I get back home I can update the files on my server by doing a
448 #+BEGIN_SRC emacs-shell
453 Note that push updates the repository, but not the working copy of the
454 files. To update the working copy on your server you need to run bzr
455 update. Alternatively, you can use the Push and Update plugin from
456 https://launchpad.net/bzr-push-and-update , which automates this
459 You can set up anacron to update the org files on your laptop when you
460 startup, or shutdown which keeps the files on your local hard drive up
461 to date in most circumstances.
463 ** Away from Home and I Forgot to Update My Files Before Leaving.
464 If the files on my laptop aren't up to date, I can use bzr to pull a
465 copy from my web server via my mobile phone. If I can't get a signal,
466 or find a wifi hotspot, the files on my laptop shouldn't be more than
467 24 hrs out of date. I can just work on my local copy and merge the
468 changes when I get back home.
471 So far my system has proved quite robust. it's also useful having the full version
472 history of my org files on each computer.
473 * Further Information.
474 You can find out more about bzr at:
475 http://doc.bazaar-vcs.org/bzr.dev/en/user-reference/bzr_man.html and
476 http://doc.bazaar-vcs.org/latest/en/mini-tutorial/index.html .
478 Git's home page can be found at: http://git.or.cz/
480 ** Useful bzr Plugins.
481 | rspush | http://bazaar-vcs.org/BzrPushExample | Pushes changes using rsync. Useful if your collection of files is very large. |
482 | fastimport | https://launchpad.net/bzr-fastimport | Import exports streams to bzr repositories. |
483 | automirror | https://launchpad.net/bzr-automirror | Automatically mirror the project's current state to another branch. |
485 ** Moving Data Between bzr and git.
486 While I was writing this tutorial I needed to move my data between my
487 bzr repository and a git repository, so I could test out the various
488 git commands. In the process I learnt quite a bit about moving data
489 between bzr and git, which I thought I would record here in case
490 someone finds it useful.
492 *** Moving Your Data from bzr to git.
493 Like most things this is easy once you know how. You need the bzr
494 fast-import plugin. You can get this from
495 https://launchpad.net/bzr-fastimport . Note that although the plugin
496 is named fastimport it does fast exporting too!
498 First you need to create an empty git repo:
500 #+BEGIN_SRC shell-script
501 mkdir ~/devel/org-git
506 Now import your bzr repo into the empty git repo:
508 #+BEGIN_SRC emacs-shell
509 bzr fast-export --export-marks=.git/bzr.mark ~/Documents/org/.bzr | git-fast-import --export-marks=.git/git.mark
512 If all goes well all your revisions will be imported into the git
513 repo. To start working on your org files you first need to check them
516 #+BEGIN_SRC emacs-shell
520 You should also be able to import new bzr changes incrementally into
523 #+BEGIN_SRC emacs-shell
524 bzr fast-export --import-marks=.git/bzr.mark --export-marks=.git/bzr.mark ~/Documents/org.bzr/trunk | git fast-import --import-marks=.git/git.mark --export-marks=.git/git.mark
527 *** Moving Data from git to bzr.
528 You can also move your data from a git repository to a bzr one. As
529 above you will need to install the bzr fastimport plugin. The
530 procedure is based on the one described in the bzr documentation: http://bazaar-vcs.org/Scenarios/ConvertFromGit
532 Create an empty bzr repository:
534 #+BEGIN_SRC emacs-shell
535 bzr init-repo bzr-org
538 Now use git's fast-export to export all the brnaches and pipe the
539 output to bzr's fast-import.
541 #+BEGIN_SRC emacs-shell
542 $ git fast-export -M --all | (cd bzr-org; bzr fast-import -)
545 Using git fast-export's -M flag embeds git's inferred filenames into
546 the output. If you don't want this, drop the -M flag.
548 I find screencasts a good way of learning things. Unfortunately there
549 don't seem to be any for bzr at the time of writing. However, there
550 are several excellent ones for git:
552 - Linus (author of git) on Git:
553 http://video.google.com/videoplay?docid=-2199332044603874737
555 - Randal Schwartz on Git:
556 http://video.google.com/videoplay?docid=-3999952944619245780
558 Randal's screencast gives an excellent overview of git, without
559 getting too bogged down in the details.
562 http://gitcasts.com/posts/page/1
564 Gitcasts are a series of short screencasts (approximately 5 mins),
565 each covering a particular aspect of git.