I am trying to squash a commit which is at HEAD into one that is a few back. When I run git rebase -i HEAD~7
, however, I am presented with just a noop
in the editor! I am totally confused about how this is supposed to work.
I am working in a branch (cleanup
) that I created (using checkout -b cleanup ...
on the SHA1 I found in reflog
) after I had my first rebase
experience and I accidentally deleted all of those commits; point is, I am not sure what the branch's parent is (if that matters, here).
I am simply trying to do what I have read about many times: I want to modify slightly some commited code that isn't the most recent commit. Whether that's an application for "squashing" or just amending it when I get to that point, I don't know.
I am also seeing this on STDOUT as the editor starts after running the rebase command shown above:
$ git rebase -i HEAD~7
usage: git rev-list [OPTION] <commit-id>... [ -- paths... ]
limiting output:
--max-count=<n>
...
In addition to the HEAD~7
reference, I have tried specifying the entire SHA1, and different refspecs to local and remote branches. Same result for everything...
What am I missing? Thanks for your help!
$ git log --oneline HEAD~7..HEAD
d0fd20e temp Fix resume_cities table
ea2ffdf Fix db/seeds.rb to reflect recent database structure modifications
dbd2b8b Add several models/scaffolds that go along with the Geonames tables
9759091 Fix name of the ResumeSkill model file.
3fc3134 Added the SHA1 for the previous commit to the comments on the migration, to help link back to that.
bacbeb2 Consolidate database migrations! READ ME!
0c49a57 Moved back to gem versions of linkedin, omniauth, and twitter
It's the bacbeb2
commit I want to amend with the d0fd20e
Per the recommendation of @MarkLongair, I added set -x
to /usr/lib/git-core/git-rebase--interactive
and saw the following strange output:
$ git rebase -i HEAD~7
[... output muted for brevity, see the full output, here: http://gist.github.com/1163118]
+ read -r shortsha1 rest
+ sed -n s/^>//p
+ git rev-list --no-merges --cherry-pick --pretty=oneline --abbrev-commit --abbrev=7 --reverse --left-right --topo-order 2c51946812a198ca908ebcad2308e4b8274624b3...d0e9ff6d9c1f8bc374856ca2a84ad52d6013b5bf
usage: git rev-list [OPTION] <commit-id>... [ -- paths... ]
limiting output:
--max-count=<n>
--max-age=<epoch>
--min-age=<epoch>
--sparse
--no-merges
--remove-empty
--all
--branches
--tags
--remotes
--stdin
--quiet
ordering output:
--topo-order
--date-order
--reverse
formatting output:
--parents
--children
--objects | --objects-edge
--unpacked
--header | --pretty
--abbrev=<n> | --no-abbrev
--abbrev-commit
--left-right
special purpose:
--bisect
--bisect-vars
--bisect-all
+ test t =
+ test -s /home/ryan/Projects/social-jobs/.git/rebase-merge/git-rebase-todo
+ echo noop
[...]
I say, 'strange output' because if I run the rev-list
command directly from my shell, it works as expected:
$ git rev-list --no-merges --cherry-pick --pretty=oneline --abbrev-commit --abbrev=7 --reverse --left-right --topo-order 2c51946812a198ca908ebcad2308e4b8274624b3...d0e9ff6d9c1f8bc374856ca2a84ad52d6013b5bf
>0c49a57 Moved back to gem versions of linkedin, omniauth, and twitter
>bacbeb2 Consolidate database migrations! READ ME!
>3fc3134 Added the SHA1 for the previous commit to the comments on the migration, to help link back to that.
>9759091 Fix name of the ResumeSkill model file.
>dbd2b8b Add several models/scaffolds that go along with the Geonames tables
>ea2ffdf Fix db/seeds.rb to reflect recent database structure modifications
>d0e9ff6 !temp Fix resume_cities table !temp
Update: There's an explanation for this behaviour at the end of my answer, but I've left the debugging suggestions here in case they are of use to anyone.
I'm not sure I have a real answer here, but I'll explain what's happening to the best of my understanding. When invoked as git rebase -i HEAD~7
, git should only output noop
to .git/rebase-merge/git-rebase-todo
if that file is empty or does not exist. We know that this isn't a permissions problem, since that file (containing "noop" and the commented lines) is successfully created as a result. The fact that you see an error from git rev-list
on the terminal also suggests that the problem is really due to how git rev-list
is invoked. In git v1.7.4.1, with the command line you quote, the list of commits to include should be found from the following:
git rev-list --no-merges --cherry-pick --pretty=oneline --abbrev-commit \
--abbrev=7 --reverse --left-right --topo-order HEAD~7...HEAD
Note that this is somewhat different from what is suggested by the man page (git log <upstream>..HEAD
) since the range uses ...
instead of ..
I would guess, since you see an error from git rev-list
, that this is the problematic command. Could you try that, and see what the output is? If that seems to work, then I suspect that there is an earlier error that causes this command line to be malformed. Since the interactive rebase is implemented as a shell script, you can fairly easily investigate this by editing the script with sudo editor /usr/lib/git-core/git-rebase--interactive
and adding set -x
at the top, something like:
#!/bin/sh
set -x
#
# Copyright (c) 2006 Johannes E. Schindelin
# SHORT DESCRIPTION
[...]
Then if you try running git rebase -i HEAD~7
, you should see every command that the script is running, and possibly see what's wrong with the git rev-list
invocation.
I hope that's of some help.
Update: It turns out that the problem here was the the questioner had IFS
set to only include tab and newline, rather than the default of space, tab and newline.
This causes a problem in the line in git-rebase--interactive
beginning:
git rev-list $MERGES_OPTION --pretty=oneline [...]
... since MERGES_OPTION
is set to --no-merges --cherry-pick
. With the default value of IFS
(which includes space) this will be split into two parameters after the variable is substituted. However, with an IFS
that doesn't include space, --no-merges --cherry-pick
will be interpreted as a single, and obviously unknown, argument, causing the git rev-list
usage message and empty output being passed on in the script.
A good puzzle :)
This issue was caused by my .bashrc setting IFS:
# remove the space character from IFS
# (http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html#IFS)
IFS="`printf '\n\t'`"
I cannot remember at all why I put that in there. I'm sure it had something to do with 'fixing UNIX/Linux filenames' as indicated by my inclusion of that URL. Dunno.
Regardless, though, I removed that statement and: POOF! No more problem!
Thanks so much to @MarkLongair for his help!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With