Last month, I wrote about how I keep my two main machines in sync using git and how, after doing a git pull, I use a bit of Elisp to automate the reverting of my open buffers. After automating the reversion of buffers, I noticed that pulling all my repositories was also a pain. I had been just pulling the repository that I was going to use but that meant it was easy to forget which repositories were up to date and get things out of sync.
I decided to write a quick script to pull all repositories at once. That way I could just run the script when I began work on one of the computers and be sure that everything was up to date. Here’s the pull-repos script:
#! /bin/bash # -*- mode: sh -*- REPOS="/Users/jcs/org /Users/jcs/medical /Users/jcs/tax /Users/jcs/.emacs.d" for r in $REPOS do cd $r pwd echo "=========================" git pull echo done
There’s nothing exciting here, of course. Most of the script is involved with outputting information as to what repository is being pulled.
The pull-repos script is already a big time saver but to really automate things I made it callable from Emacs and folded in the revert-all-buffers functionality.
(defun sync-repos () "Pull from git repos and then revert all buffers." (interactive) (switch-to-buffer "*SYNC*") (goto-char (point-min)) (shell-command "/Users/jcs/bin/pull-repos" "*SYNC*") (revert-all-buffers) (end-of-buffer) (insert (format-time-string "%Y-%m-%d %T\n")) (insert "Buffers reverted"))
Now I just call sync-repos and all my repositories are updated and all my buffers are reverted. One step when I first start using a machine: perfect.
How do handle pushing to git/git commits? Anything special/automated?
I use
magitfor that. That works out nicely because I can do everything from Emacs.Cheers! That is a great package; for some reason I didn’t know about it.
Inspired by this I wrote the following to open up a new frame, display and sync the repositories (and revert files via magit magic!) that change between my laptop and desktop on a regular basis.
Too many repos will stop the window splitting working. Enjoy.
(setq sync-repos (list "~/.gnupg"
"~/.ssh"
"~/.emacs.d"
;"~/arc"
"~/notes"))
(defun magit-wait ()
(while (and magit-process)
(sleep-for 0.2)))
(defun sync-repos ()
(progn
; Head of list is created first and other windows destroyed
(magit-status (car sync-repos))
(magit-wait)
(delete-other-windows)
(magit-pull) ; update
(magit-wait)
; Process remaining repos
(dolist (r (cdr sync-repos))
(print r)
(magit-status r)
(magit-wait)
(magit-pull)
(magit-wait)
(split-window)
(balance-windows))
(delete-window) ; delete the final unnecessary split
(balance-windows)
))
(defun repo-status ()
(interactive)
(launch-frame "Repo Sync" nil)
(sync-repos))
;; launch frame with name and predicate
(defun launch-frame (name predicate)
"Launch a new frame with name and predicate
or switch to existing frame"
(let* ((frame-names-alist (make-frame-names-alist)) ; get alist of frames
(frame (cdr (assoc name frame-names-alist)))) ; get frame with required name
(if frame
(select-frame-set-input-focus frame) ; frame exists switch to it
(select-frame (new-frame `((name . ,name)))) ; frame doesn't exist create it
(eval predicate))))
Do you know dvcs-autosync?
I do but I didn’t realize that it had move beyond its Linux roots to Mac OS X. If I were starting over, I would definitely think about using this instead of my home-grown solution.
Why not just use this emacs setting:
(global-auto-revert-mode 1)
Use magit to pull and all open buffer will be automatically reverted.