Re: Ability to edit message from git rebase --interactive.
- From
- Marcel M. Cary <marcel@earth.care2.com>
- Date
- Mar 18, 2009, 21:02 UTC
- Message-ID
- <49C16150.6070001@earth.care2.com>
- In-Reply-To
- <49C10A97.6060201@oak.homeunix.org>
Marcel M. Cary wrote:
Show 48 quoted lines
> Michael J Gruber wrote: >> Sverre Rabbelier venit, vidit, dixit 18.03.2009 06:42: >>> Heya, >>> >>> On Wed, Mar 18, 2009 at 02:06, Junio C Hamano <gitster@pobox.com> wrote: >>>> Jeff King <peff@peff.net> writes: >>>> I am not quite sure what rephrase is buying us. Do we also want to >>>> introduce retree that allows you to muck with the tree object recorded >>>> without giving you a chance to clobber the commit log message? >>> Is that a common operation? Rephrase is, at least to me... >>> >> Rephrase for sure is common, and for sure can be done currently... It's >> only that "commit --amend, save&quit, continue" could be shortened. >> >> OTOH: Most commonly one would want to rephrase a commit message or two >> without actually rebasing anything. And the proposed change doesn't help >> as much as it could, in two respects: >> >> 1) I want to be able to say "rephrase HEAD~2" without having to edit a >> rebase action script. (That would be useful for rewriting a single >> commit as well, and could be added easily.) >> >> 2) Currently, all rebasing operations have trouble with merges. But if >> all I want to do is rephrasing a log message then no diff/apply is >> necessary, no rewriting of trees, no change in the DAG structure (i.e. >> connectivity; sha1s change, of course). So there should be a special >> mode for DAG-preserving rewrites, where one can be sure that merges are >> fully preserved. >> >> 2) seems to be the most important point to make rephrasing safe and >> convenient. > > Interesting points about skipping the action script and preserving > structure. I just tried to do something like that with filter-branch: > > git filter-branch --msg-filter 'cat > tmp; $EDITOR tmp < '$(tty)' > > '$(tty)' 2>&1; cat tmp' ^HEAD^ HEAD > > And discovered that it will neither accept "HEAD^^..HEAD^" nor "HEAD^" > as a shortcut for a rev-list containing a single commit. But if you're > content to save and quit each message through the branch tip and specify > the range, it seems to work. > > I have no idea what it would take to make filter-branch support the > additional kinds of rev and rev list specifications, or if that would be > undesirable. > > I'm assuming it accomplishes (2) because of the nature of filter-branch.
Ok, so I guess you have to explicity tell filter-branch all the commits that reach the ones you want to rewrite so it will know to fixup their parents. Below is a rough way of doing that, but sometimes it will find too many commits, and it's rather slow, even on a git.git.
git-rephrase: #!/bin/sh
if [ -z "$EDITOR" ]; then
export EDITOR=vim
fi
# Does change tags
refs=$(git for-each-ref --format='%(refname)' 'refs/heads/*' |
while read ref; do
# This is the slow part
if git rev-list $ref | grep -q $(git rev-parse --verify $1); then
echo $ref
else
echo ^$ref
fi;
done
)
parents=$(git rev-list --max-count=1 --parents $1 | {
read hash parents
for hash in $parents; do
echo ^$hash
done
})
git filter-branch --msg-filter "
if [ \$GIT_COMMIT = $(git rev-parse $1) ]; then
cat > tmp
\$EDITOR tmp < $(tty) > $(tty) 2>&1
cat tmp
else
cat
fi
" $refs $parents