git rebase -i HEAD~7 -- 仅显示“noop”在编辑器中

发布于 2024-11-30 15:54:51 字数 3362 浏览 0 评论 0原文

我正在尝试将位于 HEAD 的提交压缩为后面的提交。然而,当我运行 git rebase -i HEAD~7 时,编辑器中只显示一个 noop !我完全不知道这是如何运作的。

我正在我创建的一个分支 (cleanup) 中工作(在我在 reflog 中找到的 SHA1 上使用 checkout -b cleanup ...)在我第一次rebase经历之后,我不小心删除了所有这些提交;重点是,我不确定分支的父级是什么(如果这很重要,请在这里)。

我只是想做我已经读过很多次的事情:我想稍微修改一些不是最新提交的已提交代码。我不知道这是“压制”应用程序还是只是在我到达这一点时对其进行修改。

我还在 STDOUT 上看到了这一点,因为编辑器在运行上面所示的 rebase 命令后启动:

$ git rebase -i HEAD~7
usage: git rev-list [OPTION] <commit-id>... [ -- paths... ]
  limiting output:
    --max-count=<n>
    ...

除了 HEAD~7 参考之外,我还尝试指定整个 SHA1,以及本地和远程的不同参考规范分支机构。所有事情的结果都是相同的......

我错过了什么?感谢您的帮助!


编辑:

$ 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

这是我想用 d0fd20e 修改的 bacbeb2 提交,


根据 @MarkLongair 的建议,我将 set -x 添加到 /usr/lib/git-core/git-rebase--interactive 并看到以下奇怪的输出:

$ 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
[...]

我说“奇怪的输出”,因为如果我直接运行 rev-list 命令从我的外壳,它按预期工作:

$ 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

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!


Edit:

$ 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦回旧景 2024-12-07 15:54:51

更新:我的答案末尾有对此行为的解释,但我在这里留下了调试建议,以防它们对任何人有用。


我不确定我在这里有一个真正的答案,但我会尽我所能解释发生了什么。当作为 git rebase -i HEAD~7 调用时,git 应该只输出 noop.git/rebase-merge/git-rebase-todo如果该文件为空或不存在。我们知道这不是权限问题,因为该文件(包含“noop”和注释行)已成功创建。事实上,您在终端上看到 git rev-list 出现错误,这也表明问题实际上是由于 git rev-list 的调用方式造成的。在 git v1.7.4.1 中,使用您引用的命令行,应从以下内容中找到要包含的提交列表:

git rev-list --no-merges --cherry-pick --pretty=oneline --abbrev-commit \
    --abbrev=7 --reverse --left-right --topo-order HEAD~7...HEAD

请注意,这与手册页建议的内容有些不同(git log git log < upper>..HEAD) 因为范围使用 ... 而不是 ..

我猜,因为您看到来自 git rev 的错误-list,这就是有问题的 命令。你能尝试一下,看看输出是什么吗?如果这似乎有效,那么我怀疑有一个较早的错误导致该命令行格式错误。由于交互式变基是作为 shell 脚本实现的,因此您可以通过使用 sudo editor /usr/lib/git-core/git-rebase--interactive 编辑脚本并添加 来相当轻松地调查此问题>set -x 在顶部,类似于:

#!/bin/sh
set -x
#
# Copyright (c) 2006 Johannes E. Schindelin

# SHORT DESCRIPTION
[...]

然后,如果您尝试运行 git rebase -i HEAD~7,您应该看到脚本正在运行的每个命令,并且可能会看到是什么git 错误rev-list 调用。

我希望这有一些帮助。


更新:事实证明这里的问题是提问者将IFS设置为仅包含制表符和换行符,而不是默认的空格、制表符和换行符。

这会导致 git-rebase--interactive 开头的行出现问题:

git rev-list $MERGES_OPTION --pretty=oneline [...]

... 因为 MERGES_OPTION 设置为 --no-merges --cherry-选择。使用默认值IFS(包括空格),在替换变量后,它将分为两个参数。但是,对于不包含空格的 IFS--no-merges --cherry-pick 将被解释为单个,并且显然是未知的参数,导致 git rev-list 用法消息和空输出在脚本中传递。

一个很好的谜题:)

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 :)

濫情▎り 2024-12-07 15:54:51

这个问题是由我的.bashrc设置IFS:引起的,

# remove the space character from IFS
# (http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html#IFS)
IFS="`printf '\n\t'`"

我根本不记得为什么把它放在那里。我确信它与“修复 UNIX/Linux 文件名”有关,正如我包含的该 URL 所示。不知道。

不管怎样,我删除了那句话并且:噗! 没问题了!

非常感谢@MarkLongair 的帮助!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文