ssh-deploy is a way to do coding on local machine and deploy on remote machine. Essentially, it keeps a local directory and a remote directory in sync by doing rsync on file save.
magit probably needs no introduction.
While I find ssh-deploy really really useful, I observed that making changes using magit, such as deleting a hunk in a file or changing a branch (thereby changing files or file contents), the changes are understandably not propagated to remote dir.
I am no lisp expert, but took up the challenge to get something working with my setup for these usecases:
(defun advice-for-magit-branch-checkout (BRANCH &optional START-POINT)
"advice for magit-branch-checkout:
only executes body when there is a ssh-deploy setup in place
do a remote branch switch on remote before branch switch on local
also stash away any changes on local and remote before doing the branch switch
"
;; Local - just stash changes (if any), because we will be checking out some branch after this advice
(unless (string= default-directory ssh-deploy-root-remote) ;; to stop recursion of magit-branch-checkout called for remote directory
(when ssh-deploy-root-remote
(when (magit-anything-modified-p)
(fuh-safe-wrap
(magit-stash-both
(concat (magit-get-current-branch) ": "))))
;; Remote - stash and checkout BRANCH on remote
(let ((default-directory ssh-deploy-root-remote))
(magit-branch-checkout BRANCH)))))
(advice-add 'magit-branch-checkout :before 'advice-for-magit-branch-checkout)
(defun advice-for-magit-stash-both (MESSAGE &optional INCLUDE-UNTRACKED)
"advice for magit-stash-both
if applicable, do a stash on remote before doing a stash on local
"
;; Local - just stash changes (if any), because we will be checking out some branch
(unless (string= default-directory ssh-deploy-root-remote) ;; to stop recursion of magit-stash-both called for remote dir
(when ssh-deploy-root-remote
(let ((default-directory ssh-deploy-root-remote))
(when (magit-anything-modified-p)
(fuh-safe-wrap (magit-stash-both MESSAGE)))))))
(advice-add 'magit-stash-both :before 'advice-for-magit-stash-both)
(defun advice-for-magit-stash-pop (STASH)
"advice for magit-stash-pop:
if applicable, do magit-stash-pop on remote after magit-stash-pop on local
"
(unless (string= default-directory ssh-deploy-root-remote) ;; to stop recursion of magit-stash-pop
(when ssh-deploy-root-remote
(let ((default-directory ssh-deploy-root-remote))
(fuh-safe-wrap (magit-stash-pop STASH))))))
(advice-add 'magit-stash-pop :before 'advice-for-magit-stash-pop)
(defun advice-for-magit-discard ()
"advice for magit-discard:
magit-discard works with (point) to determine context what to do
My current hacky approach basically assumes that both local and remote magit-status buffers will look identical
I open magit-status buffer on remote, then goto (point) same as from magit-status buffer on local,
then invoke magit-discard.
I have a feeling this can go horribly wrong ...
"
(unless (string= default-directory ssh-deploy-root-remote) ;; to stop recursion of magit-discard
(when ssh-deploy-root-remote
(let ((point (point)) (default-directory ssh-deploy-root-remote))
(progn
(magit-status-setup-buffer ssh-deploy-root-remote)
(goto-char point)
(fuh-safe-wrap (magit-discard)))))))
(advice-add 'magit-discard :after 'advice-for-magit-discard)
(defmacro fuh-safe-wrap (fn &rest clean-up)
"Taken from https://curiousprogrammer.wordpress.com/2009/06/08/error-handling-in-emacs-lisp/
error handling via try/catch
"
`(unwind-protect
(let (retval)
(condition-case ex
(setq retval (progn ,fn))
('error
(message (format "Caught exception: [%s]" ex))
(setq retval (cons 'exception (list ex)))))
retval)
,@clean-up))
There are no issues so far as functionality goes... (yet)
But I wanted to ask the community in general if there is some better way to do what I want to do. Or if you guys have any suggestions, or maybe someone finds this useful for their workflow.