From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alan Schmitt Subject: Re: [SYNC] How do you sync your org-mode files between n devices (n > 2) Date: Thu, 05 Sep 2013 14:31:42 +0200 Message-ID: References: <20130904060424.GA679@kuru.dyndns-at-home.com> <499DE163-8785-4997-B6F4-1B4475FAD205@gmail.com> <20130904074317.GC679@kuru.dyndns-at-home.com> <20130905094234.GH19491@kuru.dyndns-at-home.com> <20130905112545.GA2392@kuru.dyndns-at-home.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:34553) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VHYj1-0007UH-Rw for emacs-orgmode@gnu.org; Thu, 05 Sep 2013 08:31:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VHYiw-0001j3-04 for emacs-orgmode@gnu.org; Thu, 05 Sep 2013 08:31:51 -0400 Received: from mail2-relais-roc.national.inria.fr ([192.134.164.83]:5956) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VHYiv-0001ih-Nj for emacs-orgmode@gnu.org; Thu, 05 Sep 2013 08:31:45 -0400 In-reply-to: <20130905112545.GA2392@kuru.dyndns-at-home.com> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Suvayu Ali Cc: emacs-orgmode@gnu.org fatkasuvayu+linux@gmail.com writes: > On Thu, Sep 05, 2013 at 12:00:02PM +0200, Alan Schmitt wrote: >> Hi, >> >> fatkasuvayu+linux@gmail.com writes: >> >> > I think this would be a wonderful addition to Worg. Probably the FAQ is >> > more appropriate (under "Tips and Tricks") since this is one of most >> > commonly asked questions on the list. On the other hand, if you think >> > covering this topic requires more than just a few lines, a longer entry >> > or short article in the config section would be more appropriate. >> >> I can't promise anything, but I can try to write something. What >> external merging tool should I use? > > I think the most appropriate tool would be org-merge-driver. But I'm > not sure how reliable it is. That said, what might be nicer is if you > treat the external tool bits generically. Then people can choose their > own tools in the future; also that will probably be less work for you > since you don't have to figure out the details of the external merging > tool yourself. It makes sense. > What I'm after is having all the Unison config bits on Worg, then people > choose how they want to use it: > 1. plain sync, > 2. sync with merging (with their own choice of tools) > > I or someone else could then add the Dropbox like, and "version control > (Git) way" of syncing. This would then be a fairly complete FAQ on > synchronisation questions. Does that seem feasible to you? I've been playing with the merging using ediff, and it works. I'll explain it here, and depending on the feedback, I'll put it on worg. Alan * Synchronizing org files with Unison This describes how to synchronize org files using the [[http://www.cis.upenn.edu/~bcpierce/unison/][Unison file synchronizer]], as well as how to configure it to use an external tool to merge conflicting edits. ** Prerequisites You should have Unison up and running. Binaries can be found [[http://www.cis.upenn.edu/~bcpierce/unison/download.html][here]] and the documentation is [[http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html][here]]. ** Synchronization Unison is a file synchronizer, thus it may be used to synchronize org files. To configure Unison, on uses a /profile/ which states where the things to synchronize are as well as some options. Assuming I want to synchronize the files in ~/Users/schmitta/dir1~ and ~/Users/schmitta/dir2~, the profile would look like this #+BEGIN_EXAMPLE root = /Users/schmitta/dir1 root = /Users/schmitta/dir2 #+END_EXAMPLE In most cases Unison will be used with a remote machine. The local machine is called the /client/ and the remote one the /server/. For such remote synchronization, the ~unison~ binary must be installed in the server as well. The simplest way to connect to the machine is using ssh. One should check that unison can be found there by doing ~ssh user@remote unison -version~. If ~unison~ cannot be found in the path, one may set the ~servercmd~ option as indicated in the next example. (Please see the [[http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html#roots][manual section on roots]] for further details.) #+BEGIN_EXAMPLE root = /Users/schmitta/dir1 root = ssh://user@remote/relative/path/to/dir2 servercmd = /usr/bin/unison #+END_EXAMPLE ** Merging As Unison works on the level of files, it will trigger a /conflict/ if both files have changed since the last synchronization. In that case one can only choose which file to keep, which is not satisfying. Unison offers the possibility to use external tools to merge the files. There is an [[http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html#merge][extensive manual section]] regarding this, we'll just describe how to use emacs and ediff to do it. For better merging, we will ask unison to keep the last synchronized version of every org file on the client; this way we can use ediff with ancestor. These ~currentbackup~ files may live alongside the synchronized files (with names of the form ~.bak.version.name~, which is configurable) or in a central location. Here is the modified configuration file. #+BEGIN_EXAMPLE root = /Users/schmitta/dir1 root = ssh://user@remote/relative/path/to/dir2 servercmd = /usr/bin/unison backupcurrent = Name *.org backuplocation = local maxbackups = 0 merge = Name *.org -> emacsclient -c --eval '(ediff-merge-files-with-ancestor "CURRENT1" "CURRENT2" "CURRENTARCH" nil "NEW")' #+END_EXAMPLE The ~backupcurrent~ option tells unison to keep a backup of the last synchronized version of ever file with an ~org~ extension. The location of the backup should be local (alongside the file). Finally, no other backup should be created. Next follows the merge command. For every org file in conflict, use the command that launches a new emacs frame calling the ediff with ancestor function. The ~CURRENT1~, ~CURRENT2~, and ~CURRENTARCH~ strings are replaced with the file from the first root, the file from the second root, and the last synchronized version. The ~NEW~ file is where Unison expects the file to be saved (which will be done by the ediff session). Thus, when an org file has been modified on both hosts, an ediff session will be launched in a new frame. Closing the frame will make Unison commit the merge (it waits until the command has finished). If one does not want to use backups, it's possible to use the simpler ediff (without ancestor) command as follows. #+BEGIN_EXAMPLE root = /Users/schmitta/dir1 root = ssh://user@remote/relative/path/to/dir2 servercmd = /usr/bin/unison merge = Name *.org -> emacsclient -c --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")' #+END_EXAMPLE