【问题标题】:Error using the :GDiff command of fugitive.vim using gvim for windows and msys git 1.7.0.2使用 fugitive.vim 的 :GDiff 命令时出错,使用 gvim for windows 和 msys git 1.7.0.2
【发布时间】:2011-02-25 07:40:43
【问题描述】:

当我在 Windows 上时,我一直在使用 git 和 fugitive.vim 来管理代码。但是,我遇到了一个问题。根据documentation, :GDiff 命令应该是一个差异窗口,并允许我仅暂存文件的一部分。但是,当我在有更改的文件中发出命令时,我收到以下错误消息:

这是 Windows 的问题吗?维姆?逃犯?系统吉特?文件权限?有人知道吗?

【问题讨论】:

  • 我遇到了 _exact_ 同样的问题 - 如果/如何解决这个问题,请告诉我们!

标签: git vim msysgit vim-fugitive


【解决方案1】:

我没有 Windows 机器,但我能够在 Mac OS X 10.6 系统上重现并隔离此问题。

要么创建C:\TMPC:\TEMP:help 'directory' 表示两者都在 Windows 版本的 Vim 上的 directory 选项的默认值中),或者将 现有 目录添加到directory 选项的值。

我在我的主目录下使用了一个 Vim 特定的临时目录(同样,这里没有 Windows)并添加两个尾部斜杠 (~/tmp/.vim-swaps//)。这种设置集中交换文件,但根据正在编辑的文件的目录为它们提供唯一的名称。请参阅:help :swapname 中的“优点”和“缺点”以及 :help 'directory' 中的“如果目录以两个路径分隔符结尾”位。

使用^= 前置1您的目录(以便始终使用它,如果它存在的话):

set directory^=C:\\some\\existing\\directory//

或者,使用+= 附加您的目录(以便仅在存在且不存在其他适用的directory 条目时使用):

set directory+=C:\\some\\existing\\directory//

Charles’ answer 建议 $TMP(对环境变量的引用)对于 Windows 来说可能是一个不错的值:

set directory+=$TMP//

根本原因与directory选项的默认值结合:Gdiff的索引“伪”文件的路径名有关。

:Gdiff 视图的索引端的缓冲区使用类似于 fugitive:///path/to/repository/.git//0/path/to/file/under/repository 的特殊路径名(逃犯捕获对命名缓冲区的读取和写入,并通过调用 Git “管道”命令将它们重定向到索引)。

directory 中的第一个条目通常是.。这意味着 Vim 将尝试将交换文件放在与编辑文件相同的目录中(即foo/bar.txt 将尝试使用foo/.bar.swp)。如果无法创建此首选交换文件,则将尝试来自 directory 的后续条目。

. 作为第一个directoryfugitive:///path/to/repository/.git//0/path/to/file/under/repository 的首选交换文件将是fugitive:///path/to/repository/.git//0/path/to/file/under/.repository.swp。这个路径名的前导部分(fugitive:pathto 等)可能不存在,所以 Vim 将继续从 directory 开始的下一个条目。如果没有其他 directory 条目可用于创建交换文件(例如,它们不存在),则会出现错误 E302。

通过使用set directory=.,~/no-such-dir,/var/no-such-dir,/no-such-dir(即采用默认的 Unix 值并将 tmp 的出现次数更改为 no-such-dir),我能够在 Unix-y 系统上重现您的问题。实际上不存在任何“no-such-dir”目录。当我使用:Gdiff 时,我遇到了同样的错误。

1:help :set^= 只说“添加”,但代码显示set listopt^=… 的前置类似于set listopt+=… 的添加方式(正如后者所记录的那样)。两者都应该根据需要自动插入逗号(尽管这方面可能存在错误)。

【讨论】:

  • 我想知道为什么逃犯允许对那些fugitive:///path/to/repository/.git//0/path/to/file/under/repository 缓冲区进行读写?为什么它们不是只读的?就我而言,我可以修改这些缓冲区,如果我保存它们然后执行git diff,输出就会受到影响。
  • @HảiPhong:也可以试试git diff --cached。使用这些伪路径名(如fugitive://…/.git//0/…),编辑和保存它们相当于直接更改为下一次提交准备的内容(即Git的“索引”:阶段0)。如果你有信心使用索引来制作你的下一次提交,它可以是一个强大的工具(比如git addgit reset--patch,但更直接)。如果您不喜欢使用索引,您可以使用git reset <pathname>(或相关缓冲区中的:Gread -)“清除”其内容(使其与 HEAD 匹配)。
  • 哇,这就解释了。谢谢
【解决方案2】:

我遇到了同样的问题 - 这是我解决它的方法。

默认情况下,Vim 会尝试将交换文件存储在原始文件旁边。 Fugitive 创建了一个与任何真实文件路径都不对应的缓冲区,因此 Vim 在尝试创建交换文件时会出错。解决方案是确保 Vim 具有它可以写入的路径。

我是这样解决这个问题的:

if has("win32") || has("win64")
   set directory=$TMP
else
   set directory=~/tmp
end

这是 GitHub 上的原始问题: https://github.com/tpope/vim-fugitive/issues/9

编辑:

正如fow 在下面指出的那样,最好使用以下内容:

set directory+=,~/tmp,$TMP

Vim 应该使用它可以使用的第一个路径。

【讨论】:

  • 可能值得注意的是'directory' 选项是一个目录列表,Vim 将使用它可以使用的第一个。最好简单地向列表中添加一个值,而不是像set directory+=$TMP 那样抹掉整个内容。在没有操作系统检查的情况下这样做是安全的,因为在 Unix 中默认添加了 ~/tmp,即使 $TMP 在 Unix 上为空,添加它也不会做任何事情
  • @fow: +1 -- 当我使用set directory+= 时,我确实需要包含,,对吧(因为它是一个评论分隔列表)?
  • 另外,试试set directory^=$TMP(见:help :set^=)。
  • @Chris Johnsen:太棒了;我很好奇我是否可以做这样的事情。
【解决方案3】:

顺便说一句,当我尝试 :gdiff 未保存的文件时遇到同样的错误 - 当我保存它时 (:w) 它可以工作!

【讨论】:

    【解决方案4】:

    这可能与issue 428 of msysgit mentioned in my SO answer有关。

    尝试按照我在上一个答案中的描述修补cmd/git.cmd,看看是否有帮助。

    除此之外,还有 2 个选项:

    • 锁定问题(文件被进程锁定):process monitorprocess explorer 之类的实用程序可能有助于查看是否是这种情况(以及该交换文件上到底有什么句柄)李>
    • 或 Git 问题。一个好技巧是安装 msysgit 的网络安装程序,它将在您的 Windows 上构建最新版本的 Git。然后,您可以尝试查看该更新版本是否仍然存在问题。
      注意:第三个选项,尝试降级 Git,再次排除与该工具的任何链接。

    【讨论】:

    • 我已经修补了 git.cmd,它确实解决了之前的问题(顺便说一句,谢谢。
    • @Paul:我没有意识到你是问上一个问题的人! ;)
    • 我检查了交换文件,看起来 vim 是唯一具有这些文件句柄的应用程序。我现在正在检查不同版本的 msysgit,我还在 github 上提交了一个问题。
    猜你喜欢
    • 1970-01-01
    • 2012-06-06
    • 2017-03-08
    • 1970-01-01
    • 2019-10-14
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多