How to use shelf1?

Vincent Ladeuil v.ladeuil+lp at
Wed Dec 9 08:07:30 GMT 2009

>>>>> "Óscar" == Óscar Fuentes <ofv at> writes:


    Óscar> bzr shelve -F file-with-hunk-headers

    Óscar> which proceeds to shelve those hunks. If some listed
    Óscar> hunk is unknown to bazaar, it bails out.

So, while this will open a totally different can of worms, I'd
like to say that, in the long term, a better integration between
emacs and bzr will certainly use a more direct approach and
interface directly with bzrlib instead of bzr at the command-line

But since I don't have the time to work on that, the above is
certainly the way to go in the short term :-/

    >> I'll also note that Vincent uses Emacs as his primary
    >> editor, and he says that emacs diff-mode is his preferred
    >> method of handling this sort of thing. I don't know if
    >> that means he wishes diff-mode could call out to shelve,
    >> or if he just likes how it handles going between
    >> "unified-diff" and full-text editing. I'm CCing him, so he
    >> can give his experience w/ shelve and emacs.

    Óscar> Great.

So, indeed I use mainly 'bzr shelve --all' as (AIUI) an
equivalent to 'git stash': save the work in progress for later

BUT you can use shelve interactively under emacs, you just need
to use an eshell buffer not a shell regular one. The later use
buffered input but the former is perfectly happy to provide
unbuffered input.

AND: adding a --buffered option to shelve to that it can be used
even in regular emacs shell buffers is possible (patches
welcome), but as I will explain, I've never been motivated enough
to do it myself.

So, for anything more involved than 'bzr shelve --, I just save
the diff-mode buffer into a '.patch' file and use C-c C-c (goto
that hunk in the file) and C-c C-a (apply/un-apply that
hunk). With that and some editing when needed, I have a far
better emacs-integrated experience than shelve can provide.

Finally I use DVC to build the right buffers in diff-mode:

;; Most often used diff
(defun bzr-diff-against-submit ()
  (bzr-dvc-diff '(bzr (tag "submit:"))))

(defun bzr-diff-against-thread ()
  (bzr-dvc-diff '(bzr (tag "thread:"))))

(defun bzr-diff-against-rev-whatever (rev)
  (interactive "sbzr diff -r ")
  (bzr-dvc-diff (list 'bzr (list 'tag rev))))

;; my bindings
(defvar mydvc-map
  (let ((map (make-sparse-keymap)))
    (define-key map [?d] 'dvc-diff)
    (define-key map [?s] 'dvc-status)
    (define-key map [?m] 'bzr-diff-against-submit)
    (define-key map [?t] 'bzr-diff-against-thread)
    (define-key map [?r] 'bzr-diff-against-rev-whatever)
  "Keymap used dvc shortcuts.")

(if (eq system-type 'darwin)
    ;; super-z doesn't exist here
    (global-set-key [?\C-\M-z] mydvc-map)
  ;; super-z should be available everywhere else
  (global-set-key [?\s-z] mydvc-map)

And I mostly (95%) use 'dvc-diff and 'bzr-diff-against-submit to
respectively access to:
- the uncommitted changes,
- a preview of the patch I'm working on: including both the
  uncommitted changes and the previous commits up to where I
  branched from the trunk I intend to merge my patch into.

And I use that kind of file (and some M-x cd RET ../other-branch
RET) when I want to apply uncommitted changes from one branch to
an other.

I even sometimes abuse that to do some cherry-picking.


P.S.: I also have the following lines in my .bashrc but I don't
remember clearly if that's still needed with recent versions of

# If we are inside an emacs shell, tell bzr it can use a text UI
# an a tty progress bar
emacs_shell=`echo $INSIDE_EMACS | grep comint`
if [ "$emacs_shell" != "" ] ; then
    export BZR_USE_TEXT_UI=1
    export BZR_PROGRESS_BAR=text

More information about the bazaar mailing list