How to create a backup of .emacs every time Emacs starts - version-control

What is a good way to take a backup of my .emacs file each time Emacs starts? I want to keep multiple copies for when I need to get back to a previous version.
My first thought is to issue a shell command from within the .emacs file:
cp ~/.emacs ~/Backups/.emacs-yyyymmdd:hhmmss
... appending the current timestamp to get a unique filename. But as far as I know you can't issue shell commands from the .emacs file.
I've read about BackupEachSave and ForceBackups. Does anyone have experience with these? Do they work well?
EDIT:
Event_jr's answer about version control is a possible solution. I prefer using a shell command, though, because version control applies to all files and I don't need multiple backups of every single file.
I looked at the 'version control' variable. It's described in the Emacs manual:
Emacs can also make numbered backup files. Numbered backup file names contain ‘.~’, the >number, and another ‘~’ after the original file name. Thus, the backup files of eval.c >would
be called eval.c.~1~, eval.c.~2~, and so on, all the way through names like eval.c.~259~ >and beyond.
The variable version-control determines whether to make single backup files or multiple >numbered backup files.
So, I added this to my .emacs:
; Version control and backups:
(setq version-control t)
Works as advertised.
This section tells how to control backups on a per-file basis. I haven't explored it.

The question you should really be asking is how do I never lose a revision of any file I edit in Emacs, including ~/.emacs?
The answer is versioned backups. The variable that controls this feature is called version-control, which is kind of confusing, as it relates completely to backups, not VCS.
This is also a feature of Emacs; there is no additional package to install. Almost everything I work on is in VCS, but I still find it extremely useful to have all revisions of my work easily accessible. Storage is so cheap, so why not?
EDIT: describe the save-buffer aspect of backup every file.
You should read the documentation (C-h k C-x C-s) of save-buffer to understand the nuances, but basically passing it C-u C-u will force it to backup after every save. I actaully remap it to my own function
(defun le::save-buffer-force-backup (arg)
"save buffer, always with a 2 \\[universal-argument]'s
see `save-buffer'
With ARG, don't force backup.
"
(interactive "P")
(if (consp arg)
(save-buffer)
(save-buffer 16)))
(global-set-key [remap save-buffer] 'le::save-buffer-force-backup)

as far as I know you can't issue shell commands from the .emacs file.
Sure you can:
(shell-command "cp ~/.emacs ~/.emacs-`date +%Y%m%d:%H%M`")

A better solution is to use a version control system like git. It will be easier if you create an ~/.emacs.d directory and put your elisp files in there:
mkdir ~/.emacs.d
mv .emacs ~/.emacs.d/init.el
git init
git add init.el
git commit -m 'initial checkin'
Now each time you modify the init.el file you can use the following to save the changes:
git commit -a -m 'descriptive commit message here'
You can then add a function to after-save-hook, such as something like this gist to automatically add, commit, and push when files change. After the push you then have a local copy and a remote copy (e.g. on github).
Emacs also has integration with git via a package called magit.
You'll be greatly rewarded in the long run if you spend the time now to learn how to use a DVCS (Distributed Version Control System) and you'll find that magit makes it very convenient to use git.

You set backup properties as configuration; you can refer here.

Related

Projectile - use .projectile instead of .gitignore for excluding file from projectile-find-file

I'm using projectile on emacs for managing project files. There are some files
which I've put in my .gitignore as they contain my local configuration settings
dev/resources/local.edn
.dir-locals.el etc.
The problem with this is when I use projectile-find-file, these files are not listed since
they are in .gitignore file. I do not want projectile to get the list of files to ignore from .gitignore and instead only rely on .projectile for that.
Keeping files out of git repository should not be confused with listing project files using projectile. They serve different purpose - .gitignore for git and .projectile to exclude from listing files using projectile.
Is there a way to do this ? I couldn't find any variables to tweak.
Thanks
I've found a possible solution - setting indexing method to native
(setq projectile-indexing-method 'native)
Based on Projectile Documentation you can change projectile-git-command variable.
I am using project detection based on git repository with no .projectile file.
For me to show also ignored files, this change works fine:
(setq projectile-git-command "git ls-files -zco")
It's possible to use little bit faster 'hybrid' method

I use Emacs with Prelude and want to re/write git-autocommit-mode

Where inside .emacs.d should I put the source code? How should I publish my changes? This is my first attempt at writing an Emacs mode. What are the current commendations?
proggress
I'm not sure if I did it properly but I have added following to my
~/.emacs.d/personal/personal.el
(add-to-list 'load-path "~/emacs.d/vendor")
(require 'git-auto-commit-mode)
then I did 'git clone myrepo' in the vendor directory.
I haven't used Prelude myself, but it's got an
init.el,
which is probably where you should put a statement to load your code.
But if you're really at the point where you want to write your own
code, I'd recommend to either dump Prelude in favor of rolling your
own config, or completely understand how Prelude works and build on
top of that. Anything in the middle will result in much confusion.
Here's how I'd go about changing git-autocommit-mode:
visit melpa.org to lookup the source: https://github.com/ryuslash/git-auto-commit-mode
fork the source on github
clone the repo I just forked:
git clone https://github.com/abo-abo/git-auto-commit-mode.git
uninstall git-auto-commit-mode via package.el
install use-package
use this code to load your own git-auto-commit-mode:
(use-package git-auto-commit-mode
:load-path "~/git/git-auto-commit-mode")
if you make changes that you think are useful, open a pull request
on github to merge in your changes into the source repo

Org-mode from git, problems with tables

Recently I downloaded the git version of org-mode in order to use markdown export. It seems to be working, unless I have a table. When I have a table in the file I always got the next message:
Symbol's function definition is void: org-table-begin
I also get that message when I want to use the table, like the tab key to navigate or whatsoever.
My configuration is pretty simple:
;; put in the load-path the org-mode directory
(add-to-list 'load-path "~/.emacs.d/elisp/org-mode/lisp")
;; Activating the markdown export mode
(eval-after-load "org"
'(require 'ox-md nil t)
)
Do you have any idea? I have the latest version of the git repository master.
Silly answer for a silly question. I was using the org-mode repositories. I git pull the sources but I forgot to run make in order to generate the files. I just did make and that solved my problem.

Mercurial: How to ignore changes to a tracked file

I have a file with database settings in my project which I have set to some defaults. The file is tracked by Mercurial and checked in. Since this file will be edited with different values various developer machines, is there a way I can tell Mercurial to ignore new changes to this file?
I tried adding the file to the .hgignore file, but since the file is tracked it isn't ignored. This is alright and good in other situations, but I am wondering if there is something I can do here?
Using a file template is definitely the best solution.
For example, if you have a database.ini file, commit a database.ini.template file and ignore database.ini in .hgignore
If you always want to ignore the file, you can add the -X option as a default for commit to your .hg/hgrc configuration file:
[defaults]
commit = -X program.conf
We wrote an extension for this called exclude. It will automatically add the -X options on the commands that support them -- so hg status and hg commit wont see the modified file. It works by reading a .hgexclude file from the root of your repository, just like the .hgignore file. You add the files that you want to exclude there:
syntax: glob
db.conf
The extension works quite well, but there is a known situation where it fails: merges and the commit that follows a merge (this is documented on the wiki). It would need to be improved so that it would save the modifications away to a temporary file and then restore them afterwards. Please get in contact if you need this feature.
There is no truly automated process, but you can try (as in this SO question) the -X option on hg commit:
% hg stat
M myfile
% hg commit -X 'myfile'
(other solutions might involve shelve or hq)
However, this is not the "right" solution. I would rather recommend versioning:
a file template
a script able to generate the final file (that you modify but can ignore altogether)
If you are using TortoiseHG, open the Settings for the repo, go to the Commit section (2nd icon down on the left) & add the file name(s) to the Auto Exclude list on the right (~ 3rd from the bottom in the list).
From https://tortoisehg.readthedocs.io/en/latest/settings.html#commit
Typically you would check in a reference copy of the file and track it then have the developers make a copy of that for local development, you wouldn't really want developers editing the source controlled file for their own environments.
If your configuration system supports it, it's even easier if you can use an override file that simply override values in the reference copy (e.g. the database connection string). That way devs only have to keep a very minimal local set of override values.
If the file is already being tracked, you can issue the Forget command to the file. If you're using TortoiseHg just right click the file during commit and select Forget. The file must also be already in the ignore list.
I had the same problem as yours, I file keeps on appearing on every commit even-though its already in the ignore list. I tried the Forget command and it did the trick.
You can try hg forget.
For more details, see the official manual about the same command.
It worked for me.
I think, something like this is closer to a correct answer to the original question Mercurial: How to ignore changes to a tracked file, rather than the others suggesting a template, etc.

Bazaar: how put files from different locations in one repository?

I'm new to bazaar and would like to give it a try by storing my Emacs configuration files in one repository.
These files consist of a .emacs file in my home directory (on unixish systems) and a couple of Emacs Lisp source files in /usr/local/share/emacs/site-lisp
I'd really like to have one repo because some changes in my .emacs file go together with changes in other files.
What I couldn't work out from the manual is how to get these files together. The "bzr init" takes recursively all files from the current directory; for my situation this would mean to create the repo in the root directory...
What do you recommend? Try working with symbolic links? Is there a way to associate a revision from one repo to one from another repo, so that easier solution of having two separate repos could be a way to go?
There is an additional challenge: on a Windows machine, these Emacs files sit on completely different locations. How to treat that?
I have some perforce experience: there the solution is easy: you can just define a view that maps repo files to an arbitrary location on your hard disk.
This is more of a bzr question, but I can give you an Emacs answer.
The "new" way to structure your Emacs setup is to have a directory ~/.emacs.d and put everything under there. Rename your .emacs file to ~/.emacs.d/init.el and it will be found automatically. Next, create a ~/.emacs.d/lisp directory (actually you can name the dir whatever you want, but lisp is pretty standard), and move or copy the files the /usr/local/share/emacs/site-lisp files to that dir (and byte-compile them if you want to). Finally, put (add-to-list 'load-path "~/.emacs.d/lisp") at the top of your ~/.emacs/init.el file.
Now everything is under one tree, so bzr init it as usual. This setup will work on Windows also since Emacs understands ~ on there as well.