{"thread":{"id":"12181","subject":"[PATCH v3 00/03] switching, branch creating branch and merging within Emacs","startedAt":"2008-02-18T16:24:04Z","lastAt":"2008-02-18T16:35:55Z","messageCount":4,"participants":["Rémi Vanicat","Remi Vanicat"],"isPatch":true,"patchVersion":3,"patchTotal":3},"messages":[{"id":"69163","messageId":"87zltyp717.dlv@maison.homelinux.org","threadId":"12181","inReplyTo":null,"subject":"[PATCH v3 00/03] switching, branch creating branch and merging within Emacs","fromName":"Rémi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-18T16:24:04Z","receivedAt":"2008-02-18T16:24:04Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"So, I resend my patch series, with better keys binding, reworked refs\nreading (using git-for-each-ref), and a common framework for building\nmenu for merge/checkout/rebase/branching (even if it is for now only\nuse for checkout and merge).\n\n-- \nRémi Vanicat\n"},{"id":"69165","messageId":"87r6fap6mi.dlv@maison.homelinux.org","threadId":"12181","inReplyTo":"87zltyp717.dlv@maison.homelinux.org","subject":"[PATCH v3 01/03] Add helpers functions for refs and commitish to git.el","fromName":"Remi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-18T16:32:53Z","receivedAt":"2008-02-18T16:32:53Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"git-list-refs list refs\ngit-refs-build-menu is a function to build menu for refs\ngit-read-commitish ask the user a commitish, with completion for\nbranch, local and remote, and tags.\n---\n contrib/emacs/git.el |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 71 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex a8bf0ef..5166fca 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1138,6 +1138,77 @@ Return the list of files that haven't been handled.\"\n   (when (eq (window-buffer) (current-buffer))\n     (shrink-window-if-larger-than-buffer)))\n \n+(defun git-list-refs (&optional spec)\n+  \"return a list of refs using git-for-each-refs\n+\n+if type is nil or :all return all refs\n+if it is :branches return local branches\n+if it is :remotes return remote branches\n+if it is :tags return tags\"\n+  (let ((ref-spec (cond\n+\t\t    ((or (eq spec :all) (eq spec ()))\n+\t\t     \"*/*/*\")\n+\t\t    ((eq spec :branches)\n+\t\t     \"refs/heads\")\n+\t\t    ((eq spec :remotes)\n+\t\t     \"refs/remotes\")\n+\t\t    ((eq spec :tags)\n+\t\t     \"refs/tags\")\n+\t\t    (t (error \"don't know what to do with %s\" spec))))\n+\trefs)\n+    (with-temp-buffer\n+      (git-call-process-env t nil \"for-each-ref\" ref-spec \"--format=%(refname)\")\n+      (goto-char (point-min))\n+      (while (re-search-forward \"^[^/]+/[^/]+/\\\\([^\\n]*\\\\)$\" () t)\n+\t(push (cons (match-string 1)\n+\t\t    (match-string 0))\n+\t      refs)))\n+    (nreverse refs)))\n+\n+(defun git-refs-build-menu-helper (refs fcts)\n+  (let ((menu ()))\n+    (dolist (branch (git-list-refs refs))\n+      (push (funcall fcts (car branch) (cdr branch))\n+\t    menu))\n+     (nreverse menu)))\n+\n+(defun git-refs-build-menu (&rest rest)\n+  (let (before branch tag remote after)\n+    (while (and rest\n+\t\t(cdr rest)\n+\t\t(keywordp (car rest)))\n+      (cond\n+\t((eq :before (car rest))\n+\t (setq before (cadr rest)))\n+\t((eq :branch (car rest))\n+\t (setq branch (cadr rest)))\n+\t((eq :tag (car rest))\n+\t (setq tag (cadr rest)))\n+\t((eq :remote (car rest))\n+\t (setq remote (cadr rest)))\n+\t((eq :after (car rest))\n+\t (setq after (cadr rest)))\n+\t((error \"git-refs-build-menu: I don't know this keyword\")))\n+      (setq rest (cddr rest)))\n+    (unless (and (not rest)\n+\t\t remote tag branch)\n+      (error \"bad argument list\"))\n+    `(,@before\n+      ,@(git-refs-build-menu-helper :branches branch)\n+      \"------\"\n+      (\"Remotes\" ,@(git-refs-build-menu-helper :remotes remote))\n+      (\"Tags\" ,@(git-refs-build-menu-helper :tags remote))\n+      \"------\"\n+      ,@after)))\n+\n+(defun git-read-commitish (prompt &optional default)\n+  \"ask user a commitish, with commpletion for local branch, remote branch and tag\"\n+  (completing-read prompt (list* \"HEAD\"\n+\t\t\t\t \"ORIG_HEAD\"\n+\t\t\t\t \"FETCH_HEAD\"\n+\t\t\t\t (git-list-refs :all))\n+\t\t   () () () () default))\n+\n (defun git-diff-file ()\n   \"Diff the marked file(s) against HEAD.\"\n   (interactive)\n-- \n1.5.4.1.123.gcb68-dirty\n"},{"id":"69167","messageId":"87mypyp6jt.dlv@maison.homelinux.org","threadId":"12181","inReplyTo":"87zltyp717.dlv@maison.homelinux.org","subject":"[PATCH v3 02/03] Adding checkout function for commitish in git.el","fromName":"Rémi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-18T16:34:30Z","receivedAt":"2008-02-18T16:34:30Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"M-x git-checkout ask for a commitish, and checkout it as in\n  git checkout commitish --\n  key binding: \"C-cC-o\"\nM-x git-branch ask for the name of a new branch, create it and\ncheckout it as in\n  git checkout -b name\n  key binding: \"C-cC-b\"\nM-x git-create-branch ask for a new branchname, a startpoint (a\ncommitish) and create a new branch as in\n  git branch branchname startpoint\n  key binding \"B C\"\nA menu is also available for just switching branch\n---\n contrib/emacs/git.el |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 52 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex 5166fca..d35f837 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1209,6 +1209,51 @@ if it is :tags return tags\"\n \t\t\t\t (git-list-refs :all))\n \t\t   () () () () default))\n \n+(defun git-checkout (branch &optional merge)\n+  \"checkout a branch, tag, or any commitish\n+\n+use a prefix arg if git should merge while checking out\"\n+  (interactive\n+   (list (git-read-commitish \"Branch: \")\n+\t current-prefix-arg))\n+  (let ((args (list branch \"--\")))\n+    (if merge (push \"-m\" args))\n+    (if (apply #'git-call-process-display-error \"checkout\" args)\n+\t(git-refresh-status))))\n+\n+(defun git-branch (branch)\n+  \"branch from current commit and checkout the new branch\"\n+  (interactive \"MBranch: \")\n+  (if (git-call-process-display-error \"checkout\" \"-b\" branch)\n+      (git-refresh-status)))\n+\n+(defun git-create-branch (branch start-point)\n+  \"create a new branch named [branch] from the [start-point]\"\n+  (interactive\n+   (list (read-string \"New branch: \")\n+\t (git-read-commitish \"Start point(HEAD): \" \"HEAD\")))\n+  (git-call-process-display-error \"branch\" branch start-point))\n+\n+(defun git-checkout-menu-filter (rest)\n+  \"define the change branch menu\"\n+  (let ((head (git-symbolic-ref \"HEAD\")))\n+    (git-refs-build-menu\n+     :before `([\"detached head\" ignore\n+\t\t\t\t:visible ,(not head)\n+\t\t\t\t:selected ,(not head)\n+\t\t\t\t:style radio\n+\t\t\t\t:key-sequence nil])\n+     :branch (lambda (short-name ref-name)\n+\t       `[,short-name (git-checkout ,short-name)\n+\t\t\t      :style radio\n+\t\t\t      :selected ,(string= head ref-name)])\n+     :remote (lambda (short-name ref-name)\n+\t       `[,short-name (git-checkout ,ref-name)])\n+     :tag (lambda (short-name ref-name)\n+\t    `[,short-name (git-checkout ,ref-name)])\n+     :after `([\"checkout any commitish\" git-checkout t]\n+\t      [\"change to new\" git-branch t]))))\n+\n (defun git-diff-file ()\n   \"Diff the marked file(s) against HEAD.\"\n   (interactive)\n@@ -1491,6 +1536,7 @@ amended version of it.\"\n (unless git-status-mode-map\n   (let ((map (make-keymap))\n         (commit-map (make-sparse-keymap))\n+        (branch-map (make-sparse-keymap))\n         (diff-map (make-sparse-keymap))\n         (toggle-map (make-sparse-keymap)))\n     (suppress-keymap map)\n@@ -1498,6 +1544,7 @@ amended version of it.\"\n     (define-key map \"h\"   'git-help)\n     (define-key map \" \"   'git-next-file)\n     (define-key map \"a\"   'git-add-file)\n+    (define-key map \"B\"    branch-map)\n     (define-key map \"c\"   'git-commit-file)\n     (define-key map \"\\C-c\" commit-map)\n     (define-key map \"d\"    diff-map)\n@@ -1525,8 +1572,12 @@ amended version of it.\"\n     (define-key map \"x\"   'git-remove-handled)\n     (define-key map \"\\C-?\" 'git-unmark-file-up)\n     (define-key map \"\\M-\\C-?\" 'git-unmark-all)\n+    ; the branch map\n+    (define-key branch-map \"C\" 'git-create-branch)\n     ; the commit submap\n     (define-key commit-map \"\\C-a\" 'git-amend-commit)\n+    (define-key commit-map \"\\C-o\" 'git-checkout)\n+    (define-key commit-map \"\\C-b\" 'git-branch)\n     ; the diff submap\n     (define-key diff-map \"b\" 'git-diff-file-base)\n     (define-key diff-map \"c\" 'git-diff-file-combined)\n@@ -1547,6 +1598,7 @@ amended version of it.\"\n     `(\"Git\"\n       [\"Refresh\" git-refresh-status t]\n       [\"Commit\" git-commit-file t]\n+      (\"Checkout Branch\" :filter git-checkout-menu-filter)\n       (\"Merge\"\n \t[\"Next Unmerged File\" git-next-unmerged-file t]\n \t[\"Prev Unmerged File\" git-prev-unmerged-file t]\n-- \n1.5.4.1.123.gcb68-dirty\n"},{"id":"69168","messageId":"87ir0mp6hg.dlv@maison.homelinux.org","threadId":"12181","inReplyTo":"87zltyp717.dlv@maison.homelinux.org","subject":"[PATCH v3 03/03] Adding command for merging in git.el","fromName":"Rémi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-18T16:35:55Z","receivedAt":"2008-02-18T16:35:55Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"M-x git-merge will ask for an commitish, and merge with it.\n    key binding \"C-cC-m\"\nA new submenu is also available for merging with local and remote\nbranch.\n---\n contrib/emacs/git.el |   24 +++++++++++++++++++++++-\n 1 files changed, 23 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex d35f837..5c3fc01 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1254,6 +1254,26 @@ use a prefix arg if git should merge while checking out\"\n      :after `([\"checkout any commitish\" git-checkout t]\n \t      [\"change to new\" git-branch t]))))\n \n+(defun git-merge (commitish)\n+  \"merge with commitish\n+\n+Note that in case of conflict, after resolving everty conflict,\n+one have to select every concerned file before commiting\"\n+  (interactive (list (git-read-commitish \"Merge with: \")))\n+  (git-call-process-display-error \"merge\" commitish)\n+  (git-refresh-status))\n+\n+(defun git-merge-menu-filter (rest)\n+  \"define the change branch menu\"\n+  (git-refs-build-menu\n+   :branch (lambda (short-name ref-name)\n+\t     `[,short-name (git-merge ,short-name)])\n+   :remote (lambda (short-name ref-name)\n+\t     `[,short-name (git-merge ,short-name)])\n+   :tag (lambda (short-name ref-name)\n+\t  `[,short-name (git-merge ,short-name)])\n+   :after `([\"merge with any commitish\" git-merge t])))\n+\n (defun git-diff-file ()\n   \"Diff the marked file(s) against HEAD.\"\n   (interactive)\n@@ -1578,6 +1598,7 @@ amended version of it.\"\n     (define-key commit-map \"\\C-a\" 'git-amend-commit)\n     (define-key commit-map \"\\C-o\" 'git-checkout)\n     (define-key commit-map \"\\C-b\" 'git-branch)\n+    (define-key commit-map \"\\C-m\" 'git-merge)\n     ; the diff submap\n     (define-key diff-map \"b\" 'git-diff-file-base)\n     (define-key diff-map \"c\" 'git-diff-file-combined)\n@@ -1599,7 +1620,8 @@ amended version of it.\"\n       [\"Refresh\" git-refresh-status t]\n       [\"Commit\" git-commit-file t]\n       (\"Checkout Branch\" :filter git-checkout-menu-filter)\n-      (\"Merge\"\n+      (\"Merge\" :filter git-merge-menu-filter)\n+      (\"Resolve Merge\"\n \t[\"Next Unmerged File\" git-next-unmerged-file t]\n \t[\"Prev Unmerged File\" git-prev-unmerged-file t]\n \t[\"Mark as Resolved\" git-resolve-file t]\n-- \n1.5.4.1.123.gcb68-dirty\n"}]}