@matheusbsbs / matheus-bagliano / commits / c375e9d04c
Fork 0

git.el: Add a checkout command.

Prompts for a branch name and checks it out. Bound to C-c C-o by default. Based on a patch by Rémi Vanicat <vanicat@debian.org>. Signed-off-by: Alexandre Julliard <julliard@winehq.org>

Alexandre Julliard committed Nov 23, 2008 at 14:16 UTC c375e9d04cbcaaca7ae459437d185eda0a4472b4
1 file changed +31 -2
contrib/emacs/git.el
+31 -2
@@ -39,10 +39,8 @@
39 ;; - renaming files from the status buffer
40 ;; - creating tags
41 ;; - fetch/pull
42 -;; - switching branches
42 ;; - revlist browser
43 ;; - git-show-branch browser
45 -;; - menus
44 ;;
45
46 (eval-when-compile (require 'cl))
@@ -397,6 +395,17 @@ the process output as a string, or nil if the git command failed."
395 (unless newval (push "-d" args))
396 (apply 'git-call-process-display-error "update-ref" args)))
397
398 +(defun git-for-each-ref (&rest specs)
399 + "Return a list of refs using git-for-each-ref.
400 +Each entry is a cons of (SHORT-NAME . FULL-NAME)."
401 + (let (refs)
402 + (with-temp-buffer
403 + (apply #'git-call-process t "for-each-ref" "--format=%(refname)" specs)
404 + (goto-char (point-min))
405 + (while (re-search-forward "^[^/\n]+/[^/\n]+/\\(.+\\)$" nil t)
406 + (push (cons (match-string 1) (match-string 0)) refs)))
407 + (nreverse refs)))
408 +
409 (defun git-read-tree (tree &optional index-file)
410 "Read a tree into the index file."
411 (let ((process-environment
@@ -1356,6 +1365,24 @@ Return the list of files that haven't been handled."
1365 (push (match-string 1) files)))
1366 files))
1367
1368 +(defun git-read-commit-name (prompt &optional default)
1369 + "Ask for a commit name, with completion for local branch, remote branch and tag."
1370 + (completing-read prompt
1371 + (list* "HEAD" "ORIG_HEAD" "FETCH_HEAD" (mapcar #'car (git-for-each-ref)))
1372 + nil nil nil nil default))
1373 +
1374 +(defun git-checkout (branch &optional merge)
1375 + "Checkout a branch, tag, or any commit.
1376 +Use a prefix arg if git should merge while checking out."
1377 + (interactive
1378 + (list (git-read-commit-name "Checkout: ")
1379 + current-prefix-arg))
1380 + (unless git-status (error "Not in git-status buffer."))
1381 + (let ((args (list branch "--")))
1382 + (when merge (push "-m" args))
1383 + (when (apply #'git-call-process-display-error "checkout" args)
1384 + (git-update-status-files))))
1385 +
1386 (defun git-amend-commit ()
1387 "Undo the last commit on HEAD, and set things up to commit an
1388 amended version of it."
@@ -1471,6 +1498,7 @@ amended version of it."
1498 (define-key map "\M-\C-?" 'git-unmark-all)
1499 ; the commit submap
1500 (define-key commit-map "\C-a" 'git-amend-commit)
1501 + (define-key commit-map "\C-o" 'git-checkout)
1502 ; the diff submap
1503 (define-key diff-map "b" 'git-diff-file-base)
1504 (define-key diff-map "c" 'git-diff-file-combined)
@@ -1491,6 +1519,7 @@ amended version of it."
1519 `("Git"
1520 ["Refresh" git-refresh-status t]
1521 ["Commit" git-commit-file t]
1522 + ["Checkout..." git-checkout t]
1523 ("Merge"
1524 ["Next Unmerged File" git-next-unmerged-file t]
1525 ["Prev Unmerged File" git-prev-unmerged-file t]