Subject: bug#13069: 24.3.50; vc-dir: Unify git stashing and bzr shelving

From: Jambunathan K <[email-masked]>
Date: Mon, 03 Dec 2012 20:31:56 +0530

"Works-for-me" changes in my .emacs to uniformly shelf/unshelve changes
in git and bzr backends.

You can install the following changes and in a *vc-dir* (git/bzr) buffer
you can do

f s => stash
f S => snapshot
f p => pop

The patch uses `vc-call-backend' for each of the above operations.
There is also a `vc-stash-name' function to get the latest stash name.

The changes for "works-for-me".  It would be good to have
"works-for-all" equivalent of this functionality in vanilla Emacs.

----------------------------------------------------------------------

;; Unify git stashing and bzr shelving

;; Put stash related operations on a `f' prefix.
(defvar vc-dir-stash-map
  (let ((map (make-sparse-keymap)))
    (define-key map "s" 'vc-stash)
    (define-key map "S" 'vc-stash-snapshot)
    (define-key map "p" 'vc-stash-pop)
    map))

(fset 'vc-dir-stash-map vc-dir-stash-map)

(add-hook 'vc-dir-mode-hook
	  (lambda ()
	    (define-key vc-dir-mode-map "f" 'vc-dir-stash-map)))

;; Generic vc-stash callbacks.
(require 'vc)
(defun vc-stash (name)
  "Stash current working tree."
  (interactive "sName: ")
  (let* ((vc-fileset (vc-deduce-fileset t)) ;FIXME: Why t? --Stef
	 (backend (car vc-fileset))
	 (files (cadr vc-fileset)))
    (vc-call-backend backend 'stash name)))

(defun vc-stash-snapshot ()
  "Take a snapshot of working tree."
  (interactive)
  (let* ((vc-fileset (vc-deduce-fileset t)) ;FIXME: Why t? --Stef
	 (backend (car vc-fileset))
	 (files (cadr vc-fileset)))
    (vc-call-backend backend 'stash-snapshot)))

(defun vc-stash-pop ()
  "Pop newest stash."
  (interactive)
  (let* ((vc-fileset (vc-deduce-fileset t)) ;FIXME: Why t? --Stef
	 (backend (car vc-fileset))
	 (files (cadr vc-fileset))
	 (name (vc-stash-name)))
    (when name
      (vc-call-backend backend 'stash-pop name))))

(defun vc-stash-name ()
  "Name of the stash on top."
  (let* ((vc-fileset (vc-deduce-fileset t)) ;FIXME: Why t? --Stef
	 (backend (car vc-fileset))
	 (files (cadr vc-fileset)))
    (vc-call-backend backend 'stash-name)))

;; Bzr vc-stash callbacks.
(defalias 'vc-bzr-stash 'vc-bzr-shelve)
(defalias 'vc-bzr-stash-snapshot 'vc-bzr-shelve-snapshot)
(defalias 'vc-bzr-stash-apply 'vc-bzr-shelve-apply)

(defun vc-bzr-stash-name ()
  (let* ((name (car (vc-bzr-shelve-list)))
	 (id (when (and name (string-match "^ +\\([0-9]+\\):" name))
	       (match-string 1 name))))
    id))

(defun vc-bzr-stash-pop (name)
  (interactive)
  (vc-bzr-shelve-apply name))

;; Git vc-stash callbacks.
(defun vc-git-stash-name ()
  (let* ((name (car (vc-git-stash-list)))
	 (id (when (and name (string-match "^ +\\({[0-9]+}\\):" name))
	       (match-string 1 name))))
    (format "stash@%s" id)))

In GNU Emacs 24.3.50.8 (i686-pc-linux-gnu, X toolkit, Xaw3d scroll bars)
 of 2012-12-03 on debian-6.05
Bzr revision: 111072 [email-masked]
Windowing system distributor `The X.Org Foundation', version 11.0.10707000
Important settings:
  value of $LANG: en_IN
  locale-coding-system: iso-latin-1-unix
  default enable-multibyte-characters: t