如何让COMMIT_EDITMSG从正确的位置打开?

7

我刚接触GIT。几天前,我从GitHub的链接下载了Windows版本的GIT。我正在使用命令行工具MinGW32。默认编辑器让我感到不舒服,所以我一直在尝试设置我的最爱编辑器。

我按照这里的说明来设置EditPad Pro作为我的编辑器。但是我一直收到以下消息:

由于提交信息为空,提交中止。

EditPad Pro会打开一个新实例。因为只有在关闭EditPad Pro后才会收到中止消息,所以MinGW32一直在等待。当编辑器打开时,它会打开一个名为COMMIT_EDITMSG的空文件。当我关闭编辑器时,该文件将保存到存储库的主目录中。

这个回答中,我找到了线索,特别是这句话:

[Vim]默认将文件保存到.git/COMMIT_EDITMSG。

如果我在关闭编辑器之前使用另存为将文件保存到.git目录中,那么它就可以正常工作。然而,这样做存在两个问题:

  1. 我必须记得另存为
  2. 我无法获得Git默认添加到COMMIT_EDITMSG中的有用注释

core.editor的当前配置设置为:

"'D:\Program Files\JGsoft\EditPadPro5\EditPad Pro.exe' //newinstance"

我不确定指南中提到的$*是用来做什么的,但我尝试了带或不带它以及带或不带单/双引号等各种组合。我还尝试在shell脚本中设置值。最坏的情况下,它根本不起作用(例如,甚至无法打开编辑器),而最好的情况下它会打开一个空文件。

如何让我的编辑器打开Git在.git目录中创建的文件?

编辑:无论我是否使用$*,结果都完全相同,而此答案表示它不需要。 这个 Git Pro 页面在解释如何设置外部合并和差异工具时提到了它,但在解释core.editor配置设置时没有提到它。注意:我还尝试了%*

如果需要$*变量(并且缺失),我认为EditPad Pro会打开一个空的Untitled文件而不是当前目录中的空COMMIT_EDITMSG文件。问题似乎是路径。

编辑:我进行了更多实验。我文件路径中有空格,我认为这可能会导致问题。我将我的存储库克隆到没有空格的新目录中,并修复了我的配置变量。它没有解决问题。但我注意到另一个问题。在一些测试中,加载到编辑器中的空文件名为$@


记录一下,/newinstance命令行参数,用于启动一个新的EditPad实例,应用程序可以等待。不同的编辑器有不同的指定方式。换句话说,这个参数是特定于编辑器而不是Git的。 - toxalot
请注意:在这种情况下需要使用双斜杠(//newinstance)。如果没有它,EditPad Pro会在现有实例中打开一个名为newinstance的空文件。 - toxalot
5个回答

6
有几个问题可能会导致混淆和问题。
  1. The Shell Special Variable

    If core.editor is set to the editor path and filename, then the $* variable is redundant and not needed. However, if the core.editor is set to a shell script, then the $* variable must be passed along to the editor.

    This is valid:

    $ git config --global core.editor "'D:/Path To/EditPadPro.exe' //newinstance"
    

    This is also valid:

    $ git config --global core.editor "'E:/Path To/editor.sh'"
    

    when editor.sh contains:

    #!/bin/sh
    "D:/Path To/EditPadPro.exe" //newinstance "$*"
    
  2. Spaces in File Names

    Filenames with spaces can be a pain. If the path/filename is quoted, then it isn't usually a problem. But when setting the value of core.editor you have to either

    escape the spaces like this:

    "E:/Path\ To/editor.sh"
    

    or quote it twice like this:

    "'E:/Path To/editor.sh'"
    

    Without the extra quotes (or backslash escapes), you will have no problem setting the value, but it will fail when it's used because the outer quotes are not part of the value.

    EDIT: Latter method (quoting twice) seems safer. See the edit at the bottom for more explanation.

  3. Windows Path Separator

    The filename that is being passed to the editor can be a relative path (i.e. .git/COMMIT_EDITMSG) or absolute path (i.e. e:/path to/.git/rebase-merge/git-rebase-todo), but in both cases it is using forward slashes as a path separator. Windows can usually accept forward slashes as a path separator, especially if the path is quoted. Perhaps the older version of EditPad Pro is unable to accept the forward slashes in combination with the hidden directory. A little bit of preprocessing can fix this.

    Note: Hardcoded paths with forward slashes and no hidden directory seem to work fine. Hardcoded paths with hidden directories and backslashes seem to work fine.

最终解决方案

我对shell脚本并不是很有经验,但以下内容对我目前来说是可行的。

editor.sh文件包含:

#!/bin/sh
fullpath=`echo "$*" | tr '/' '\\\'`
"D:/Program Files/JGsoft/EditPadPro5/EditPadPro.exe" //newinstance "$fullpath"

配置如下:

$ git config --global core.editor "'E:/Path To/editor.sh'"

我的EditPad Pro 5.3.2现在可以正确打开已加载的文件,无论哪个git命令启动编辑器。

编辑:我不得不更改core.editor的值。我曾使用反斜杠来转义路径中的空格,并成功地打开了编辑器。但是,当Git命令将相对路径(以点开头)的文件名传递给我的shell脚本时,$*的值是$@而不是文件名,导致编辑器打开一个名为$@的空文件。我以为我测试过这种组合,但显然没有。使用双引号的方法可以解决这个问题。


非常好的反馈,比我的答案更完整。+1 - VonC
谢谢。我花了很多时间和精力来解决并写出这个程序。自己搞定让我感到满意,但得到认可更让人开心。更重要的是,你的投票为我赢得了一个帽子。 :) - toxalot
“Git R done” 帽子……作为一名 Git 专家,我只能欣赏:那顶帽子适合你和这个问题。向您致敬,先生。 - VonC

2

$* 是指“所有其他参数”:参见“shell脚本中的$*代表什么”。

如果你在使用中忘记了 $*

 "C:/Program Files/JGsoft/EditPadPro6/EditPadPro.exe" //newinstance "$*"

你不会使用最后一个参数打开编辑器,这个参数是.git/COMMIT_EDITMSG
这意味着你不会默认保存提交信息到它应该保存的地方(供Git使用)。


1

我不确定问题是出在EditPad Pro还是MinGW32上,但我找到了一个解决方法。如果我传入路径和文件名,它就可以工作。

例如:

$ git config --global core.editor "'D:/Program Files/JGsoft/EditPadPro5/EditPadPro.exe' //newinstance '.git\COMMIT_EDITMSG'"

EditPad Pro将打开两个文件:当前目录中的一个空白COMMIT_EDITMSG和.git目录中的COMMIT_EDITMSG。我可以编辑.git文件并保存它。当我关闭编辑器时,.git文件将用作提交消息。空白文件不会被保存在任何地方,完全被忽略。

'.git\COMMIT_EDITMSG'中的反斜杠和单引号很重要。其他方式都行不通。起初我以为我的旧版EditPad Pro不喜欢正斜杠,但我可以传递其他使用正斜杠路径的文件名(带或不带引号),对它们也有效。我只能推测,任何其他变体的COMMIT_EDITMSG都会与MinGW32已经传入的内容发生冲突。

由于路径是相对于当前目录的,所以无论我提交哪个repo,它都应该工作。

编辑:上述解决方案仅适用于提交。

当编辑器用于其他目的,如交互式变基时,它并没有帮助。请参见我的其他答案以获取最终解决方案。


0

到目前为止,以下方法对我来说在提交方面是有效的:

$ git config --global core.editor "'C:/Program Files/Just Great Software/EditPad Pro 7/EditPadPro7.exe' '//wait'" --replace-all

这将打开一个指向正确文件的新标签页,并在该标签页关闭后继续执行。添加--replace-all是为了清除之前尝试设置它时卡住的内容。


0

所选答案中的解决方案非常有帮助。

我想分享一个基于它的一行代码版本:

git config --global core.editor "callEditor(){ filepath=\`echo \"\$*\" | tr '/' '\\' 2> /dev/null\`; '**PathToYourEditorHere**' \"\$filepath\"; }; callEditor"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接