Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I set up emacs to automatically git commit every time I save an open file or periodically?

share|improve this question
6  
Doesn't that kinda defeat the point of version control? – Phoshi May 7 '10 at 15:25
1  
If you are a programmer, probably. But for those of using emacs to write rather then code, I think this is quite useful. – Brian Z Sep 8 '13 at 14:36
up vote 3 down vote accepted

If you wanted to commit upon every save, you'd do:

(add-hook 'after-save-hook 'my-commit-on-save)
(defun my-commit-on-save ()
   "commit the buffer"
   ...your-code-goes-here...)

Likely you could just use

(defun my-commit-on-save ()
   "commit the buffer"
   (call-interactively 'vc-next-action))

But, you'll want to add some checks to make sure it's a part of the set of files you want to commit, otherwise every buffer you save will be added to a repository.

share|improve this answer
    
This is exactly what I came here looking for! – Ryan Fox Sep 15 '10 at 20:25

I use git-wip for that (see my answer on SO).

share|improve this answer

Here is a bit of lisp that I found. Does not do commit/push on every save, but schedules it for the near future so if you save a bunch of small edits you don't get a bunch of small commits.

https://gist.github.com/defunkt/449668

;; Automatically add, commit, and push when files change.

(defvar autocommit-dir-set '()
  "Set of directories for which there is a pending timer job")

(defun autocommit-schedule-commit (dn)
  "Schedule an autocommit (and push) if one is not already scheduled for the given dir."
  (if (null (member dn autocommit-dir-set))
      (progn
        (run-with-idle-timer
         10 nil
         (lambda (dn)
           (setq autocommit-dir-set (remove dn autocommit-dir-set))
           (message (concat "Committing org files in " dn))
           (shell-command (concat "cd " dn " && git commit -m 'Updated org files.'"))
           (shell-command (concat "cd " dn " && git push & /usr/bin/true")))
         dn)
        (setq autocommit-dir-set (cons dn autocommit-dir-set)))))

(defun autocommit-after-save-hook ()
  "After-save-hook to 'git add' the modified file and schedule a commit and push in the idle loop."
  (let ((fn (buffer-file-name)))
    (message "git adding %s" fn)
    (shell-command (concat "git add " fn))
    (autocommit-schedule-commit (file-name-directory fn))))

(defun autocommit-setup-save-hook ()
  "Set up the autocommit save hook for the current file."
  (interactive)
  (message "Set up autocommit save hook for this buffer.")
  (add-hook 'after-save-hook 'autocommit-after-save-hook nil t))
share|improve this answer
    
It's better to copy and paste the relevant info from the linked page rather than just linking to it in case the page content changes or moves. – Tog Jul 23 '13 at 18:02

You don't need emacs for that at all. You can write a shell script that uses inotify. It could look like this:

while true; do
    inotifywait -e modify FILES...
    git commit ....
done

inotifywait is part of inoftify-tools.

share|improve this answer
    
or some other periodic thing: 'cron', 'sched from zsh', whatever – akira May 7 '10 at 15:28
    
what i suggested isn't periodic – Kim May 7 '10 at 21:08

You can also use my git-monitor utility, if especially if you are a Haskell user.

share|improve this answer

Try something like this:

(defadvice save-buffer (after commit-buffer-now activate)
  (when buffer-file-name (your commit code goes here)))

This is the emacs way to do it.

share|improve this answer
    
You shouldn't be using advice when save-buffer already provides the perfectly good variable after-save-hook. – Ryan Thompson Dec 1 '10 at 2:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .