From: Michal Sojka <sojka@os.inf.tu-dresden.de>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org, paulus@samba.org
Subject: [PATCH v4] gitk: Allow commit editing
Date: Sat, 27 Aug 2011 14:31:02 +0200 [thread overview]
Message-ID: <87fwknaveh.fsf@steelpick.2x.cz> (raw)
In-Reply-To: <20110825173018.GA519@sigill.intra.peff.net>
On Thu, 25 Aug 2011, Jeff King wrote:
> On Thu, Aug 25, 2011 at 03:15:42PM +0200, Michal Sojka wrote:
> > + # Check whether some other refs contain the commit to be edited
> > + if {[exec git rev-list --stdin $id << $otherrefsneg] eq {}} {
> > + if { [confirm_popup [mc "The commit you are going to edit is contained in another, possibly non-local, ref (e.g. branch or tag).\
> > + It is a bad idea to change a ref that is possibly used by other people. See git-rebase(1) for details.\n\n\
> > + Do you want to continue?"]]} {
> > + return 1
>
> Minor micro-optimization: this can be "git rev-list -1". You only care
> if it produces the one commit, so that's sufficient. Without "-1", git
> will keep reporting commits all the way down to the merge base with some
> other ref.
Here is a new version with the micro-optimization.
Another minor change is that this patch now applies to gitk repo
(http://git.kernel.org/pub/scm/gitk/gitk.git) instead of the main git
repo.
-Michal
--8<---------------cut here---------------start------------->8---
I often use gitk to review patches before pushing them out and I would
like to have an easy way to edit commits. The current approach with
copying the commitid, switching to terminal, invoking git rebase -i,
editing the commit and switching back to gitk is a way too complicated
just for changing a single letter in the commit message or removing a
debug printf().
This patch adds "Edit this commit" item to gitk's context menu which
invokes interactive rebase in a non-interactive way :-). git gui is
used to actually edit the commit.
Besides editing the commit message, splitting of commits, as described
in git-rebase(1), is also supported.
The user is warned if the commit to be edited is contained in another
ref besides the current branch and the stash (e.g. in a remote
branch). Additionally, error box is displayed if the user attempts to
edit a commit not contained in the current branch.
Signed-off-by: Michal Sojka <sojka@os.inf.tu-dresden.de>
---
gitk | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/gitk b/gitk
index a701e0d..1ca2d00 100755
--- a/gitk
+++ b/gitk
@@ -2481,6 +2481,7 @@ proc makewindow {} {
makemenu $rowctxmenu {
{mc "Diff this -> selected" command {diffvssel 0}}
{mc "Diff selected -> this" command {diffvssel 1}}
+ {mc "Edit this commit" command edit_commit}
{mc "Make patch" command mkpatch}
{mc "Create tag" command mktag}
{mc "Write commit to file" command writecommit}
@@ -8445,18 +8446,18 @@ proc rowmenu {x y id} {
if {$id ne $nullid && $id ne $nullid2} {
set menu $rowctxmenu
if {$mainhead ne {}} {
- $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] -state normal
+ $menu entryconfigure 8 -label [mc "Reset %s branch to here" $mainhead] -state normal
} else {
- $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled
+ $menu entryconfigure 8 -label [mc "Detached head: can't reset" $mainhead] -state disabled
}
if {[info exists markedid] && $markedid ne $id} {
- $menu entryconfigure 9 -state normal
$menu entryconfigure 10 -state normal
$menu entryconfigure 11 -state normal
+ $menu entryconfigure 12 -state normal
} else {
- $menu entryconfigure 9 -state disabled
$menu entryconfigure 10 -state disabled
$menu entryconfigure 11 -state disabled
+ $menu entryconfigure 12 -state disabled
}
} else {
set menu $fakerowmenu
@@ -9120,6 +9121,68 @@ proc cherrypick {} {
notbusy cherrypick
}
+proc rebase_ok {id} {
+ if {[exec git merge-base $id HEAD] ne $id} {
+ error_popup [mc "You cannot edit commits outside of the current branch."]
+ return 0
+ }
+ set headref [exec git symbolic-ref HEAD]
+ set allrefs [split [exec git for-each-ref --format=%(refname)] "\n"]
+ set otherrefs {}
+ set otherrefsneg ""
+ foreach ref $allrefs {
+ if {$ref eq "refs/stash" || $ref eq $headref} continue
+ set otherrefsneg "$otherrefsneg^$ref\n"
+ }
+
+ # Check whether some other refs contain the commit to be edited
+ if {[exec git rev-list --stdin $id --max-count=1 << $otherrefsneg] eq {}} {
+ if { [confirm_popup [mc "The commit you are going to edit is contained in another, possibly non-local, ref (e.g. branch or tag).\
+ It is a bad idea to change a ref that is possibly used by other people. See git-rebase(1) for details.\n\n\
+ Do you want to continue?"]]} {
+ return 1
+ } else {
+ return 0
+ }
+ }
+ return 1
+}
+
+proc edit_commit {} {
+ global rowmenuid selectedline
+
+ if {![rebase_ok $rowmenuid]} return
+
+ nowbusy edit [mc "Editing commit"]
+ if {[catch {exec sh -c "(GIT_EDITOR='sed -ie 1s/^pick/edit/' git rebase -p -i --no-autosquash $rowmenuid^ && git gui citool --amend) 2>&1"} err]} {
+ notbusy edit
+ error_popup $err
+ exec git rebase --abort
+ return
+ }
+ set newcommit [exec git rev-parse HEAD]
+ while {[catch {exec sh -c "git diff-index --quiet --cached HEAD && git diff-files --quiet"} err]} {
+ if {[confirm_popup [mc "There are uncommited changes in the working tree or in the index.\
+ Do you want to create a new commit (OK) or discard them (Cancel)?"]]} {
+ catch {exec git gui citool} err;
+ # In case of error (i.e. the user did not commit anything), we just ask him again
+ } else {
+ exec git reset --hard
+ }
+ }
+ if {[catch {exec sh -c "git rebase --continue 2>&1"} err]} {
+ notbusy edit
+ error_popup $err
+ exec git rebase --abort
+ return
+ }
+ updatecommits
+ # XXX How to select the edited commit? This doesn't work.
+ selbyid $newcommit
+ notbusy edit
+}
+
+
proc resethead {} {
global mainhead rowmenuid confirm_ok resettype NS
--
1.7.5.4
--8<---------------cut here---------------end--------------->8---
next prev parent reply other threads:[~2011-08-27 12:31 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-17 19:56 [PATCH RFC] gitk: Allow commit editing Michal Sojka
2011-08-18 22:33 ` Jeff King
2011-08-19 11:44 ` Chris Packham
2011-08-19 13:34 ` Michal Sojka
2011-08-19 14:40 ` Michal Sojka
2011-08-19 12:23 ` Michal Sojka
2011-08-19 12:25 ` [PATCH] " Michal Sojka
2011-08-25 3:14 ` Jeff King
2011-08-25 13:15 ` [PATCH v3] " Michal Sojka
2011-08-25 17:30 ` Jeff King
2011-08-27 12:31 ` Michal Sojka [this message]
2011-09-07 20:10 ` [PATCH v4] " Jeff King
2011-09-08 20:59 ` Paul Mackerras
2011-09-13 23:11 ` Michal Sojka
2011-08-25 3:07 ` [PATCH RFC] " Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87fwknaveh.fsf@steelpick.2x.cz \
--to=sojka@os.inf.tu-dresden.de \
--cc=git@vger.kernel.org \
--cc=paulus@samba.org \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.