Backups Mode README
The inspiration for this came after reading John Siracusa’s review of the Document Model new to Mac OS X Lion. This new framework on the Mac allows for the following:
- All documents are automatically saved. This includes when the user closes the document or quits the application.
- Old versions of the document are automatically stored and accessible.
- The user has the ability to manually save a verion of the document.
- Old versions can be viewed, diffed, and reverted.
- Reverting an old version saves the current file as a version and copies the selected version to become the current file.
So I set out to emulate these features in Emacs. Emacs already has its own rudimentary version control system that can be turned on simply by configuring emacs. It can also be configured to keep those backup files tucked away in a central directory. It can also be configured to automatically save (without prompting) your files when you kill the buffer or quit emacs. In the event that Emacs crashes, you can also restore your file from an autosave file emacs creates for you. So it has all of that out of the box.
What this mode adds is the ability to easily find, view, diff, and revert those versioned backup files. While editing any file-based buffer in Emacs, you can now do two extra things. You can list all backups of that file, you can explicily save a version, and you can kill the buffer without saving (since the default is to save as soon as a buffer is killed).
Using the Emacs version control functionality is really an implementation of a backup system, and doesn’t replace a proper version control system such as CVS, SVN, Git, Mercurial, and the like. So if you are developing a project or typing a manuscript, you’ll want to consider using one of those systems. Version control systems and backup systems serve different purposes. Use the right tool for the job.
- Clone the git repost
git clone email@example.com:rpdillon/backups-mode.git cd backups-mode
- Copy to your emacs load-path
cp backups-mode.el ~/.emacs.d/
This assumes ~/.emacs.d/ is in your emacs load-path.
- Add the following to .emacs
4 Additional configuration
Putting this in your .emacs will allow you to change version control settings. These are the default settings found in backups-mode.el.
(setq backup-by-copying t delete-old-versions t kept-new-versions 6 kept-old-versions 2 version-control t)
The Emacs documentation will explain these options.
By default, backups are saved to “~/.emacs.d/backups” and tramp file backups are saved to “~/.emacs.d/backups/tramp-backups”. These defaults can be changed by customizing the variables:
You can also tune how many new and old versions are kept in the backup directory with the variables:
You can view and customize all these variables with:
passing in the variable you want to view or change.
If you choose to use the default keybindings (which you can enable by adding
(backups-mode-default-keybindings) to your config), then you can access backups mode while editing any file-based emacs buffer. Here are three additional commands:
- This will version the previous saved copy of the file.
- By default, this command can be done with control-c v (“\C-cv”)
- This will open a new buffer in backups-mode which will list all backups of the file.
- By default, this command can be done with control-c b (“\C-cb”)
- This will allow the user to close a buffer without saving any changes
- By default, this command can be done with control-c k (“\C-ck”)
While in the backups-mode buffer, you can:
- View Backup
- This is done by aligning the cursor to a file’s line, and hitting \[enter\].
- Backup files will be opened read-only.
- You can move up and down with ‘n’ and ‘p’, and quit back to the backups buffer with ‘q’
- Revert Backup
- This is done by aligning the cursor to a file’s line, and typing “R”.
- Reverting will save the current file as a version, then replace the current file with the chosen backup.
- Diff Two Files
- This is done by aligning the cursor to a file’s line, and typing “d”. This will mark that line as first file to diff.
- Then, you align the cursor to another file’s line and type “d”. This will run ediff on the two selected files.
The problem with creating N backup files per file is that over time you’ll have generated a lot of backup files. Some of these backup files may even be orphaned if the original file is moved or deleted. I’ve taken two approaches for this problem:
6.1 For local files
For local files, I’ve created the script “show-orphaned.sh” (found in the scripts directory). It goes through my backups directory and displays all orphaned backups. I’ve created a @daily crontab job to remove all of the orphaned backups.
@daily home/chadbraunduin.emacs.d/backups/show-orphaned.sh | xargs -r /bin/rm -f
6.2 For tramp files
For tramp files, we cannot assume to be able to access the original file. Therefore, I’ve taken a more crude approach with tramp backups. I’ve scheduled a @daily crontab job that removes any tramp backups that have not be accessed in the past 180 days (roughly 6 months).
@daily find home/chadbraunduin.emacs.d/tramp-backups/ -type f -name “*.*~” -atime +180 | xargs -r /bin/rm -f
7 rsnapshot configuration
I use rsnapshot for rsync backups to an external drive. I’ve decided I do not care to backup these emacs generated backup files. Therefore, I’ve added these two lines to /etc/rsnapshot.conf:
exclude home/chadbraunduin.emacs.d/backups/*.*~ exclude home/chadbraunduin.emacs.d/tramp-backups/*.*~
8 Bugs and TODOs
As with most projects, this is still a work in progress. The known issues are:
- This has not been tested on Windows, yet. There is nothing inherently Linux or OS X-specific in the Emacs code, but YMMV