{"thread":{"id":"12073","subject":"[PATCH] Add function to checkout a branch in git.el","startedAt":"2008-02-13T15:53:12Z","lastAt":"2008-02-17T18:30:34Z","messageCount":14,"participants":["=?utf-8?q?R=C3=A9mi=20Vanicat?=","Karl Hasselström","Remi Vanicat","Sergei Organov","Rémi Vanicat","Alexandre Julliard"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"68656","messageId":"87wsp8u9m7.dlv@maison.homelinux.org","threadId":"12073","inReplyTo":null,"subject":"[PATCH] Add function to checkout a branch in git.el","fromName":"=?utf-8?q?R=C3=A9mi=20Vanicat?=","fromEmail":"vanicat@debian.org","sentAt":"2008-02-13T15:53:12Z","receivedAt":"2008-02-13T15:53:12Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"One can now:\n- checkout an existing branch with M-x git-change-branch\n- create and checkout a new branch with C-u M-x git-change-branch\n- do all this from the Git menu\n---\nIt could also be interesting to add some  key biding for those\n\nAlso one might want to update the *git-status* buffer after checkout,\nbut this is not done by this patch\n contrib/emacs/git.el |   45 +++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 45 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex a8bf0ef..404c8e6 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1138,6 +1138,50 @@ 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-branch ()\n+  \"Return a list of available branch\"\n+  ;; should I check if I'm in a git repository ?\n+  (let ((branchs ()))\n+    (with-temp-buffer\n+      (git-run-command-buffer (current-buffer) \"branch\")\n+      (goto-char (point-min))\n+      (while (re-search-forward \"^\\\\([ *]\\\\) \\\\([^\\n]*\\\\)$\" () t)\n+\t(push (list (match-string 2)\n+\t\t    (string= (match-string 1) \"*\"))\n+\t      branchs)))\n+    (nreverse branchs)))\n+\n+(defun git-change-branch (branch &optional new)\n+  \"Switch to another branch\n+\n+With a prefix argument, switch to a new branch, ortherwise use\n+an existing one\"\n+  (interactive\n+   (if current-prefix-arg\n+       (list (read-from-minibuffer \"Branch: \")\n+\t     current-prefix-arg)\n+       (list (completing-read \"Branch: \" (git-list-branch) () t)\n+\t     current-prefix-arg)))\n+  (with-temp-buffer\n+    (if new\n+\t(git-call-process-display-error \"checkout\" \"-b\" branch)\n+\t(git-call-process-display-error \"checkout\" branch))\n+    (goto-char (point-min))))\n+\n+(defun git-change-new-branch-menu (branch)\n+  \"Switch to new branch\"\n+  (interactive \"MBranch: \")\n+  (git-change-branch branch 't))\n+\n+(defun git-change-branch-menu-filter (rest)\n+  \"define the change branch menu\"\n+  (append\n+   (mapcar\n+    (lambda (branch)\n+      `[,(car branch) (git-change-branch ,(car branch)) t])\n+    (git-list-branch))\n+   (list [\"change to new\" git-change-new-branch-menu t])))\n+\n (defun git-diff-file ()\n   \"Diff the marked file(s) against HEAD.\"\n   (interactive)\n@@ -1486,6 +1530,7 @@ amended version of it.\"\n \t[\"Diff Against Merge Head\" git-diff-file-merge-head t]\n \t[\"Diff Against Mine\" git-diff-file-mine t]\n \t[\"Diff Against Other\" git-diff-file-other t])\n+      (\"Change branch\" :filter git-change-branch-menu-filter)\n       \"--------\"\n       [\"Add File\" git-add-file t]\n       [\"Revert File\" git-revert-file t]\n-- \n1.5.4.1.101.gacba\n"},{"id":"68658","messageId":"20080213163002.GA5670@diana.vm.bytemark.co.uk","threadId":"12073","inReplyTo":"87wsp8u9m7.dlv@maison.homelinux.org","subject":"Re: [PATCH] Add function to checkout a branch in git.el","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-02-13T16:30:02Z","receivedAt":"2008-02-13T16:30:02Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-02-13 16:53:12 +0100, =?utf-8?q?R=C3=A9mi=20Vanicat?= wrote:\n\n> - checkout an existing branch with M-x git-change-branch\n> - create and checkout a new branch with C-u M-x git-change-branch\n\nWhy the prefix? Wouldn't it be easier to just have one \"switch branch\"\nprompt that would tab complete existing branch names, and\n\n  * if the user enters the name of an existing branch, just switch to\n    it;\n\n  * if the user enters a name that's not the name of an existing\n    branch, ask for confirmation, and then create the new branch and\n    switch to it.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"68659","messageId":"20080213164356.GA5828@diana.vm.bytemark.co.uk","threadId":"12073","inReplyTo":"20080213163002.GA5670@diana.vm.bytemark.co.uk","subject":"Re: [PATCH] Add function to checkout a branch in git.el","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-02-13T16:43:56Z","receivedAt":"2008-02-13T16:43:56Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-02-13 17:30:02 +0100, Karl Hasselström wrote:\n\n> Why the prefix? Wouldn't it be easier to just have one \"switch\n> branch\" prompt that would tab complete existing branch names, and\n>\n>   * if the user enters the name of an existing branch, just switch to\n>     it;\n>\n>   * if the user enters a name that's not the name of an existing\n>     branch, ask for confirmation, and then create the new branch and\n>     switch to it.\n\nReading your code a bit more carefully, I realize that my suggestion\ndoesn't give you the opportunity to base the new branch on anything\nbut HEAD. So change the second bullet to\n\n  * if the user enters a name that's not the name of an existing\n    branch, display a prompt like this\n\n      Creating new branch \"foo\". Where should it start?\n\n    Tab complete on existing tags and branches, but accept any\n    committish. Create the new branch and switch to it.\n\nThis bit of UI could obviously be reused to make create-branch and\ncreate-tag commands that don't switch the current branch.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"68663","messageId":"87hcgcu3rl.dlv@maison.homelinux.org","threadId":"12073","inReplyTo":"20080213164356.GA5828@diana.vm.bytemark.co.uk","subject":"Re: [PATCH] Add function to checkout a branch in git.el","fromName":"Remi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-13T18:09:50Z","receivedAt":"2008-02-13T18:09:50Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"M-x git-change-branch checkout branch, and ask for confirmation\nif a new one is to be created\nOne could also use a new submenu in the Git menu for this.\n---\nKarl Hasselström <kha@treskal.com> writes:\n\n> On 2008-02-13 17:30:02 +0100, Karl Hasselström wrote:\n>\n>> Why the prefix? Wouldn't it be easier to just have one \"switch\n>> branch\" prompt that would tab complete existing branch names, and\n\nI didn't think of the other way, that seem simpler. Here is a\ncorrected patch\n\n>   * if the user enters a name that's not the name of an existing\n>     branch, display a prompt like this\n>\n>       Creating new branch \"foo\". Where should it start?\n>\n>     Tab complete on existing tags and branches, but accept any\n>     committish. Create the new branch and switch to it.\nMmm seem cool, but I have no time for now. Patch are welcome,\notherwise I might look at it this weekend or next week.\n\nAlso one might want to do detached head checkout, it wont work for\nnow, but should not be very hard to do.\n-- \nRémi Vanicat\n contrib/emacs/git.el |   45 +++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 45 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex a8bf0ef..bf0601d 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1138,6 +1138,50 @@ 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-branch ()\n+  \"Return a list of available branch\"\n+  ;; should I check if I'm in a git repository ?\n+  (let ((branchs ()))\n+    (with-temp-buffer\n+      (git-run-command-buffer (current-buffer) \"branch\")\n+      (goto-char (point-min))\n+      (while (re-search-forward \"^\\\\([ *]\\\\) \\\\([^\\n]*\\\\)$\" () t)\n+\t(push (list (match-string 2)\n+\t\t    (string= (match-string 1) \"*\"))\n+\t      branchs)))\n+    (nreverse branchs)))\n+\n+(defun git-change-branch (branch &optional new)\n+  \"Switch to another branch\n+\n+if new is non-nil, creating it if needed\n+otherwise just checkout it\"\n+  (interactive\n+   (let ((branch (completing-read \"Branch: \" (git-list-branch))))\n+     (list branch\n+\t   (and (not (assoc branch (git-list-branch)))\n+\t\t(or (y-or-n-p \"create a new branch? \")\n+\t\t    (error \"branch does not exist\"))))))\n+  (with-temp-buffer\n+    (if new\n+\t(git-call-process-display-error \"checkout\" \"-b\" branch)\n+\t(git-call-process-display-error \"checkout\" branch \"--\"))\n+    (goto-char (point-min))))\n+\n+(defun git-change-new-branch-menu (branch)\n+  \"Switch to new branch\"\n+  (interactive \"MBranch: \")\n+  (git-change-branch branch 't))\n+\n+(defun git-change-branch-menu-filter (rest)\n+  \"define the change branch menu\"\n+  (append\n+   (mapcar\n+    (lambda (branch)\n+      `[,(car branch) (git-change-branch ,(car branch)) t])\n+    (git-list-branch))\n+   (list [\"change to new\" git-change-new-branch-menu t])))\n+\n (defun git-diff-file ()\n   \"Diff the marked file(s) against HEAD.\"\n   (interactive)\n@@ -1486,6 +1530,7 @@ amended version of it.\"\n \t[\"Diff Against Merge Head\" git-diff-file-merge-head t]\n \t[\"Diff Against Mine\" git-diff-file-mine t]\n \t[\"Diff Against Other\" git-diff-file-other t])\n+      (\"Change branch\" :filter git-change-branch-menu-filter)\n       \"--------\"\n       [\"Add File\" git-add-file t]\n       [\"Revert File\" git-revert-file t]\n-- \n1.5.4.1.101.gacba\n"},{"id":"68664","messageId":"87zlu4vhon.fsf@osv.gnss.ru","threadId":"12073","inReplyTo":"20080213164356.GA5828@diana.vm.bytemark.co.uk","subject":"Re: [PATCH] Add function to checkout a branch in git.el","fromName":"Sergei Organov","fromEmail":"osv@javad.com","sentAt":"2008-02-13T18:23:52Z","receivedAt":"2008-02-13T18:23:52Z","isPatch":true,"sender":{"key":"osv@javad.com","avatar":null},"body":"Karl Hasselström <kha@treskal.com> writes:\n\n> On 2008-02-13 17:30:02 +0100, Karl Hasselström wrote:\n>\n>> Why the prefix? Wouldn't it be easier to just have one \"switch\n>> branch\" prompt that would tab complete existing branch names, and\n>>\n>>   * if the user enters the name of an existing branch, just switch to\n>>     it;\n>>\n>>   * if the user enters a name that's not the name of an existing\n>>     branch, ask for confirmation, and then create the new branch and\n>>     switch to it.\n>\n> Reading your code a bit more carefully, I realize that my suggestion\n> doesn't give you the opportunity to base the new branch on anything\n> but HEAD. So change the second bullet to\n>\n>   * if the user enters a name that's not the name of an existing\n>     branch, display a prompt like this\n>\n>       Creating new branch \"foo\". Where should it start?\n>\n>     Tab complete on existing tags and branches, but accept any\n>     committish. Create the new branch and switch to it.\n\nIt still doesn't allow to detach HEAD at arbitrary tag/committish, as\nfar as I can see.\n\nI believe the interface should be designed more carefully. Here are some\nthoughts/suggestions:\n\n1. Let `git-checkout' switch HEAD. It will never create new branches but\n   will be able to detach HEAD. Use tab-completion on branch names and\n   maybe tags (maybe by inserting tags/ into completion list, and\n   switching completion list to tags after tags/ is enterd by user), but\n   allow any commitish. Ideally, it will also revert Emacs buffers for\n   which working copy files are changed during checkout.\n\n2. Let `git-create-branch' create new branches. It will prompt for a branch\n   name, then prompt for starting point with default set to HEAD, and\n   create the branch. As it doesn't switch HEAD, it won't touch working\n   files.\n\n3. Let `git-branch' create new branch at HEAD and switch to it. This\n   will be just a short-cut for common and simple case. Note that this\n   will never change working files as newly created branch will match\n   HEAD.\n\n4. Reserve C-u prefix for ability to provide arbitrary options to\n   underlying GIT commands. For example, it's useful to be able to give\n   -m or -f option to \"git checkout\"; or --track or -f to \"git branch\".\n\nThe \"create new branch at arbitrary point and then switch to it\" will\nthen be a two-step operation: either \"\n\n((git-create-branch <name> <point>) (git-checkout <name>)\n\nor\n\n((git-checkout <point>) (git-branch <name>))\n\nbut that is IMHO reasonable trade-off for interface simplicity, though\nyet another function could be defined to do it in one step.\n\n-- Sergei.\n"},{"id":"68666","messageId":"87y79ovhfi.fsf@osv.gnss.ru","threadId":"12073","inReplyTo":"87wsp8u9m7.dlv@maison.homelinux.org","subject":"Re: [PATCH] Add function to checkout a branch in git.el","fromName":"Sergei Organov","fromEmail":"osv@javad.com","sentAt":"2008-02-13T18:29:21Z","receivedAt":"2008-02-13T18:29:21Z","isPatch":true,"sender":{"key":"osv@javad.com","avatar":null},"body":"<vanicat@debian.org> writes:\n> One can now:\n> - checkout an existing branch with M-x git-change-branch\n> - create and checkout a new branch with C-u M-x git-change-branch\n\ns/git-change-branch/git-checkout/? I mean is there any reason it is\ncalled differently from GIT's \"git checkout\"?\n\nBesides, I also think that prefix is not a good idea for this kind of\nstuff (see my other reply in this thread).\n\n> - do all this from the Git menu\n> ---\n> It could also be interesting to add some  key biding for those\n>\n> Also one might want to update the *git-status* buffer after checkout,\n> but this is not done by this patch\n\nWhy? Isn't it as simple as calling (git-refresh-status) at the end of\ngit-change-branch?\n\n>  contrib/emacs/git.el |   45 +++++++++++++++++++++++++++++++++++++++++++++\n>  1 files changed, 45 insertions(+), 0 deletions(-)\n>\n> diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\n> index a8bf0ef..404c8e6 100644\n> --- a/contrib/emacs/git.el\n> +++ b/contrib/emacs/git.el\n> @@ -1138,6 +1138,50 @@ 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-branch ()\n> +  \"Return a list of available branch\"\n\ns/branch/branches/\n\n> +  ;; should I check if I'm in a git repository ?\n> +  (let ((branchs ()))\n\ns/branchs/branches/\n\n\n-- Sergei.\n"},{"id":"68675","messageId":"20080213210420.GA9316@diana.vm.bytemark.co.uk","threadId":"12073","inReplyTo":"87zlu4vhon.fsf@osv.gnss.ru","subject":"Re: [PATCH] Add function to checkout a branch in git.el","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-02-13T21:04:20Z","receivedAt":"2008-02-13T21:04:20Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-02-13 21:23:52 +0300, Sergei Organov wrote:\n\n> Karl Hasselström <kha@treskal.com> writes:\n>\n> >   * if the user enters a name that's not the name of an existing\n> >     branch, display a prompt like this\n> >\n> >       Creating new branch \"foo\". Where should it start?\n> >\n> >     Tab complete on existing tags and branches, but accept any\n> >     committish. Create the new branch and switch to it.\n>\n> It still doesn't allow to detach HEAD at arbitrary tag/committish,\n> as far as I can see.\n\nIt wouldn't be hard. Just try to interpret the string supplied by the\nuser as a committish: if successful, check it out; if not, create a\nnew branch by that name. Of course, this makes it impossible to create\na branch with the same name as an existing committish, but that's\nprobably OK.\n\n> I believe the interface should be designed more carefully. Here are\n> some thoughts/suggestions:\n\nYes, having different commands that do one job each and do it well\nisn't a bad idea either. I like my idea more, but obviously whoever\nwrites the code gets to decide ...\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"68729","messageId":"87myq3vjx4.fsf@osv.gnss.ru","threadId":"12073","inReplyTo":"20080213210420.GA9316@diana.vm.bytemark.co.uk","subject":"Re: [PATCH] Add function to checkout a branch in git.el","fromName":"Sergei Organov","fromEmail":"osv@javad.com","sentAt":"2008-02-14T11:47:51Z","receivedAt":"2008-02-14T11:47:51Z","isPatch":true,"sender":{"key":"osv@javad.com","avatar":null},"body":"Karl Hasselström <kha@treskal.com> writes:\n\n> On 2008-02-13 21:23:52 +0300, Sergei Organov wrote:\n>\n>> Karl Hasselström <kha@treskal.com> writes:\n>>\n>> >   * if the user enters a name that's not the name of an existing\n>> >     branch, display a prompt like this\n>> >\n>> >       Creating new branch \"foo\". Where should it start?\n>> >\n>> >     Tab complete on existing tags and branches, but accept any\n>> >     committish. Create the new branch and switch to it.\n>>\n>> It still doesn't allow to detach HEAD at arbitrary tag/committish,\n>> as far as I can see.\n>\n> It wouldn't be hard. Just try to interpret the string supplied by the\n> user as a committish: if successful, check it out; if not, create a\n> new branch by that name.\n\nToo much AI for a function, at least to my taste.\n\n> Of course, this makes it impossible to create a branch with the same\n> name as an existing committish, but that's probably OK.\n\nI'd say it's probably even desirable. Whatever implementation, I'd at\nleast check for such a collision and ask for confirmation, provided it's\nnot very time-consuming.\n\n>\n>> I believe the interface should be designed more carefully. Here are\n>> some thoughts/suggestions:\n>\n> Yes, having different commands that do one job each and do it well\n> isn't a bad idea either. I like my idea more, but obviously whoever\n> writes the code gets to decide ...\n\nYes, sure. I just wanted to point to alternative approach. Or maybe I'll\nget the time to implement it myself, though I'm more interested in\ngit-merge and git-[fetch|pull]-[merge|rebase] implementation, so that\ngit.el support at least some of real workflows without resorting to\nplain GIT commands.\n\n-- Sergei.\n"},{"id":"68922","messageId":"87lk5ku2wn.dlv_-_@maison.homelinux.org","threadId":"12073","inReplyTo":"87zlu4vhon.fsf@osv.gnss.ru","subject":"[patch v2] switching and creating branch, merging and rebasing with Emacs","fromName":"=?utf-8?q?R=C3=A9mi=20Vanicat?=","fromEmail":"vanicat@debian.org","sentAt":"2008-02-16T19:17:28Z","receivedAt":"2008-02-16T19:17:28Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"I've a new version, in the form of a patch series that follow:\nfirst I add some function for asking user commitish\nthen some code for checkouting commitish and branching, mostly\nfollowing the idea of Sergei,\nthen some code for merging.\n\nI've look to add rebase, but when thinking about how to do about\nconflict and continued rebasing, I feel lazy, and didn't try. As\nsomeone a good idea for the interface?\n-- \nRémi Vanicat\n"},{"id":"68924","messageId":"87ejbcu2gb.dlv_-_@maison.homelinux.org","threadId":"12073","inReplyTo":"87lk5ku2wn.dlv_-_@maison.homelinux.org","subject":"[PATCH 01/03] Add helper function for branch tag and commitish to git.el","fromName":"Rémi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-16T19:27:16Z","receivedAt":"2008-02-16T19:27:16Z","isPatch":true,"sender":{"key":"vanicat@debian.org","avatar":"https://gravatar.com/avatar/cd491a7f4c221349809a60f88fc21326b97cce2a705e318898aa74851db92409?d=mp&s=160"},"body":"\n---\n contrib/emacs/git.el |   37 +++++++++++++++++++++++++++++++++++++\n 1 files changed, 37 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex a8bf0ef..16d9771 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1138,6 +1138,43 @@ 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-branches (&optional all)\n+  \"Return an alist of available branches\n+if all is non-nil, return all branch, otherwise only local one\n+cdr of assoc is non-nil for the current branch\n+nil otherwise\"\n+  (let ((branches ()))\n+    (with-temp-buffer\n+      (if all\n+\t  (git-run-command-buffer (current-buffer) \"branch\" \"-a\")\n+\t  (git-run-command-buffer (current-buffer) \"branch\"))\n+      (goto-char (point-min))\n+      (while (re-search-forward \"^\\\\([ *]\\\\) \\\\([^\\n]*\\\\)$\" () t)\n+\t(push (cons (match-string 2)\n+\t\t    (string= (match-string 1) \"*\"))\n+\t      branches)))\n+    (nreverse branches)))\n+\n+(defun git-list-tags ()\n+  \"Return an list of available tags\"\n+  (let ((tags ()))\n+    (with-temp-buffer\n+      (git-run-command-buffer (current-buffer) \"tag\")\n+      (goto-char (point-min))\n+      (while (re-search-forward \"^\\\\([^\\n]+\\\\)$\" () t)\n+\t(push (match-string 1)\n+\t      tags)))\n+    (nreverse tags)))\n+\n+(defun git-read-commitish (prompt &optional default)\n+  \"ask user, with commpletion for a commit, branch, tag or any commitish\"\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 (append (git-list-branches t)\n+\t\t\t\t\t (git-list-tags)))\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":"68925","messageId":"87abm0u2ao.dlv_-_@maison.homelinux.org","threadId":"12073","inReplyTo":"87lk5ku2wn.dlv_-_@maison.homelinux.org","subject":"[PATCH 02/03] Adding checkout function for commitish in git.el","fromName":"Rémi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-16T19:30:39Z","receivedAt":"2008-02-16T19:30:39Z","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\"\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: \"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\"\nA menu is also available for just switching branch\n---\nThe main problem that I still see, is the error message when one try\nto checkout a branch/tag... that doesn't exist: it is a cryptic error\nmessage... \n\n contrib/emacs/git.el |   42 ++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 42 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex 16d9771..f180421 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1175,6 +1175,44 @@ nil otherwise\"\n \t\t\t\t\t (git-list-tags)))\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+  (append\n+   (mapcar\n+    (lambda (branch)\n+      `[,(car branch)\n+\t (git-checkout ,(car branch))\n+\t :style radio\n+\t :selected ,(cdr branch)])\n+    (git-list-branches))\n+   (list [\"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@@ -1466,6 +1504,9 @@ amended version of it.\"\n     (define-key map \"a\"   'git-add-file)\n     (define-key map \"c\"   'git-commit-file)\n     (define-key map \"\\C-c\" commit-map)\n+    (define-key map \"C\"   'git-checkout)\n+    (define-key map \"b\"   'git-branch)\n+    (define-key map \"B\"   'git-create-branch)\n     (define-key map \"d\"    diff-map)\n     (define-key map \"=\"   'git-diff-file)\n     (define-key map \"f\"   'git-find-file)\n@@ -1513,6 +1554,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\n\n-- \nRémi Vanicat\n"},{"id":"68926","messageId":"8763wou23f.dlv_-_@maison.homelinux.org","threadId":"12073","inReplyTo":"87lk5ku2wn.dlv_-_@maison.homelinux.org","subject":"[PATCH 03/03] Adding command for merging in git.el","fromName":"Rémi Vanicat","fromEmail":"vanicat@debian.org","sentAt":"2008-02-16T19:35:00Z","receivedAt":"2008-02-16T19:35:00Z","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.\nA new submenu is also available for merging with local and remote\nbranch.\n---\nThe problem here, which is similar to the one that exist now when one\nmerge from outside Emacs, is that in case of conflict, Emacs doesn't\nlook to the index, and so, when one commit the resolved conflict,\none might forget to select all file that should be selected for the\ncommit to be what is needed.\n\nThis problem could be even worse with rebasing, as rebasing is a more\ndestructive action than merging.\n\n\n contrib/emacs/git.el |   22 +++++++++++++++++++++-\n 1 files changed, 21 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/emacs/git.el b/contrib/emacs/git.el\nindex f180421..60553d3 100644\n--- a/contrib/emacs/git.el\n+++ b/contrib/emacs/git.el\n@@ -1213,6 +1213,25 @@ use a prefix arg if git should merge while checking out\"\n    (list [\"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 merge branch menu\"\n+  (append\n+   (mapcar\n+    (lambda (branch)\n+      `[,(car branch)\n+\t (git-merge ,(car branch)) :visible ,(not (cdr branch))])\n+    (git-list-branches :all))\n+   (list [\"merge with any commitish\" git-merge t])))\n+\n (defun git-diff-file ()\n   \"Diff the marked file(s) against HEAD.\"\n   (interactive)\n@@ -1555,7 +1574,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"},{"id":"69012","messageId":"871w7b5th1.fsf@wine.dyndns.org","threadId":"12073","inReplyTo":"87abm0u2ao.dlv_-_@maison.homelinux.org","subject":"Re: [PATCH 02/03] Adding checkout function for commitish in git.el","fromName":"Alexandre Julliard","fromEmail":"julliard@winehq.org","sentAt":"2008-02-17T18:27:22Z","receivedAt":"2008-02-17T18:27:22Z","isPatch":true,"sender":{"key":"julliard@winehq.org","avatar":null},"body":"Rémi Vanicat <vanicat@debian.org> writes:\n\n> M-x git-checkout ask for a commitish, and checkout it as in\n>   git checkout commitish --\n>   key binding: \"C\"\n> M-x git-branch ask for the name of a new branch, create it and\n> checkout it as in\n>   git checkout -b name\n>   key binding: \"b\"\n> M-x git-create-branch ask for a new branchname, a startpoint (a\n> commitish) and create a new branch as in\n>   git branch branchname startpoint\n>   key binding \"B\"\n> A menu is also available for just switching branch\n\nMy idea was to put commands that act on commits instead of files on the\nC-c prefix, for instance amend-commit is on C-c C-a, I have a\npreliminary cherry-pick implementation that I put on C-C C-p, then we\ncould have git-checkout on C-c C-o, git-branch on C-c C-b, git-merge on\nC-c C-m. Otherwise we'll soon run out of single letter bindings.\n\nAlso for more complex operations like git-create-branch we may want\nanother prefix, as there would probably be more branch manipulations\ncommands.  For instance something like \"B C\" for create-branch, \"B D\"\nfor delete-branch, \"B M\" for move-branch etc.\n\n-- \nAlexandre Julliard\njulliard@winehq.org\n"},{"id":"69013","messageId":"87wsp34er9.fsf@wine.dyndns.org","threadId":"12073","inReplyTo":"87ejbcu2gb.dlv_-_@maison.homelinux.org","subject":"Re: [PATCH 01/03] Add helper function for branch tag and commitish to git.el","fromName":"Alexandre Julliard","fromEmail":"julliard@winehq.org","sentAt":"2008-02-17T18:30:34Z","receivedAt":"2008-02-17T18:30:34Z","isPatch":true,"sender":{"key":"julliard@winehq.org","avatar":null},"body":"Rémi Vanicat <vanicat@debian.org> writes:\n\n> +(defun git-list-branches (&optional all)\n> +  \"Return an alist of available branches\n> +if all is non-nil, return all branch, otherwise only local one\n> +cdr of assoc is non-nil for the current branch\n> +nil otherwise\"\n> +  (let ((branches ()))\n> +    (with-temp-buffer\n> +      (if all\n> +\t  (git-run-command-buffer (current-buffer) \"branch\" \"-a\")\n> +\t  (git-run-command-buffer (current-buffer) \"branch\"))\n> +      (goto-char (point-min))\n> +      (while (re-search-forward \"^\\\\([ *]\\\\) \\\\([^\\n]*\\\\)$\" () t)\n> +\t(push (cons (match-string 2)\n> +\t\t    (string= (match-string 1) \"*\"))\n> +\t      branches)))\n> +    (nreverse branches)))\n\ngit-run-command-buffer isn't really what you want to use here, look at\nhow other functions that use a temp-buffer do it. Also that alist thing\nis ugly, there are better ways of finding the current branch if we need\nit. Besides, you probably want to use git-for-each-ref instead of\ngit-branch, git-branch is a bit too porcelainish IMO.\n\n-- \nAlexandre Julliard\njulliard@winehq.org\n"}]}