Syncing With Git Repositories

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.

This entry was posted in General and tagged . Bookmark the permalink.

7 Responses to Syncing With Git Repositories

  1. beslayed says:

    How do handle pushing to git/git commits? Anything special/automated?

  2. Matt Ford says:

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

  3. semente says:

    Do you know dvcs-autosync?

    • jcs jcs says:

      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.

  4. kasim says:

    Why not just use this emacs setting:
    (global-auto-revert-mode 1)

    Use magit to pull and all open buffer will be automatically reverted.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>