Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
    
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

6 Answers 6

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

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

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 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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.