Change a heading in the FAQ
[Worg/babel-doc.git] / org-tutorials / org-vcs.org
blob4d79ee092b582cf078db0162272194551ae6deee
1 #+TITLE: Putting Your org Files Under Version Control.
2 #+AUTHOR: Ian Barton.
3 #+EMAIL: ian@manor-farm.org
4 #+SEQ_TODO:  TODO DONE
5 #+LANGUAGE: en
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
7 #+STARTUP:    hidestars 
10 * Introduction.
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
28 server each night.
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.
40 * Requirements.
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
43 of:
45 #+BEGIN_SRC emacs-shell
46 apt-get install bzr bzrtools
47 apt-get git-core  
48 #+END_SRC
50 If you want to push changes to a remote server, you might also want to
51 install the ncftp client.
53 * Getting Started.
54 ** Creating a Repository.
55   The first step is to create a repository in the directory where you
56   keep your org files:
57 #+BEGIN_SRC emacs-shell
58 cd ~/Documents/org
59 bzr init
60   
61 #+END_SRC
63 If you are using git:
65 #+BEGIN_SRC emacs-shell
66 git init  
67 #+END_SRC
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
73 directory:
75 In my .bzrignore I simply have:
77 #+BEGIN_SRC emacs-shell
78 *~  
79 #+END_SRC
81 With git you  can create a .gitignore file, which has a very similar
82 syntax to .bzrignore.
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
89 bzr add *.org  
90 #+END_SRC
92 For git users:
94 #+BEGIN_SRC emacs-shell
95 git add *.org  
96 #+END_SRC
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."  
104 #+END_SRC
106 For git users:
108 #+BEGIN_SRC emacs-shell
109 git commit -a -m "Imported sources."  
110 #+END_SRC
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
119 #!/bin/sh
120 cd ~/Documents/org
121 bzr commit -m "automatic commit via cron."  
122 #+END_SRC
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  
129 #+END_SRC
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
141 described below.
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  
155 #+END_SRC
157 For git users:
158 #+BEGIN_SRC emacs-shell
159   git clone ~nfs/firewall/Documents/org ~/Documents/org
160 #+END_SRC
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
195 the commit command:
197 #+BEGIN_SRC emacs-shell
198   bzr commit -m "Committing changes made on my notebook."
199 #+END_SRC
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
211   bzr push  
212 #+END_SRC
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."  
227 #+END_SRC
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
235 git push 
236 #+END_SRC
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
240 bzr.
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
247 bzr pull  
248 #+END_SRC
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
257 git pull   
258 #+END_SRC
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
264 karma.
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
268 no-trees option:
270 #+BEGIN_SRC emacs-shell
271 bzr init-repo --no-trees sftp://myserver.com/bzr/myrepo  
272 #+END_SRC
274 You can now use bzr to push your local branch to the central
275 repository:
277 #+BEGIN_SRC emacs-shell
278 cd ~/Documents/org
279 bzr push sftp://myserver.com/bzr/myrepo/org-files  
280 #+END_SRC
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
285 the remote server:
287 #+BEGIN_SRC emacs-shell
288   git clone --bare . ssh://myserver.com/git-repo/org.git
289 #+END_SRC
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
296 #+END_SRC
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
301 firewall in the way.
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
314 Intrepid.
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    
321 #+END_SRC
323 Now populate the repository with your org files:
325 #+BEGIN_SRC emacs-shell
326   bzr push file:///media/disk/bzr-repo
327 #+END_SRC
329 Using git the comand is:
331 #+BEGIN_SRC emacs-shell
332   git clone --bare ~/Documents/org /media/disk/org.git
333 #+END_SRC
335 Once you have made the initial push you can sync your changes to the
336 usb stick like this:
338 #+BEGIN_SRC shell-script
339   cd ~/Documents/org
341   # bzr will default to using the saved initial location,
342   # so you don't need to specify a location. 
343   bzr-push
344 #+END_SRC
346 #+BEGIN_SRC emacs-shell
347   git push origin master
348 #+END_SRC
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
356 first time.
358 With bzr:
360 #+BEGIN_SRC emacs-shell
361   bzr branch /media/usbdisk/bzr-repo ~/Documents/org
362 #+END_SRC
363 With git:
365 #+BEGIN_SRC emacs-shell
366   git clone /media/disk/org.git ~/Documents/org
367 #+END_SRC
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."
378 #+END_SRC
380 #+BEGIN_SRC emacs-shell
381   git commit -m "Commit before push to usb stick."
382 #+END_SRC
384 To update the repo on your USB stick you need to push your changes:
386 #+BEGIN_SRC emacs-shell
387   bzr push
388 #+END_SRC
390 #+BEGIN_SRC emacs-shell
391   git push
392 #+END_SRC
393 *** Day to Day Use.
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
396 something like:
398 Home.
399 Edit your org files
400 Commit your changes (=bzr commit=)
401 Push the changes to your usb stick (=bzr push=)
403 Work.
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
420 the command line:
422 #+BEGIN_SRC emacs-shell
423 bzr pull sftp://myserver.co.uk/my_repo/org  
424 #+END_SRC
425    
426 * Day to Day Usage.
427 I have three different scenarios for using my system:
429 ** Working at Home.
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.
434 ** Away from Home.
435 Update the files on my laptop before I leave:
437 #+BEGIN_SRC emacs-shell
438   cd ~/Documents/org
439   bzr pull
440 #+END_SRC
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
444 share.
446 When I get back home I can update the files on my server by doing a
448 #+BEGIN_SRC emacs-shell
449 cd ~/Documents/org
450 bzr push  
451 #+END_SRC
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
457 process for you.
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.
470 * Conclusion.
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
502   cd ~/devel/org-git
503   git init
504 #+END_SRC
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
510 #+END_SRC
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
514 out:
516 #+BEGIN_SRC emacs-shell
517   git checkout master
518 #+END_SRC
520 You should also be able to import new bzr changes incrementally into
521 git:
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
525 #+END_SRC
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
536 #+END_SRC
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 -)
543 #+END_SRC
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.
547 ** Git Screencasts.
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.
561 - Gitcasts:
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.