Pycharm 与 Git 的行为很奇怪(树条目中的文件名包含反斜杠)

Pycharm behaving strange with Git (Filename in tree entry contains backslash)

我刚买了一台新笔记本电脑,想用 pycharm 克隆我的大学 git 存储库。

每当我尝试使用 Git bash/GUI 或 Pycharm 克隆存储库时,它都会失败并显示错误

Filename in tree entry contains backslash: 'Aufgabe4a.py# coding=utf-8 ...

错误中包含上述文件的完整内容。

由于这是我大学的存储库,我不能直接去重命名不属于我的文件。 奇怪的是,这并没有发生在我的桌面上。我可以在那里很好地克隆回购协议。

我期待您的建议,因为我需要这个 repo 来提交我的练习,但我并不总是可以访问我的桌面。

编辑:存储库中没有一个文件的名称中包含反斜杠。我浏览了网站和“工作副本”,一个 iOS 应用程序来预览 Git 回购。

这些是在笔记本电脑上使用 Git 调试时的结果:

18:28:45.034704 exec-cmd.c:237          trace: resolved executable dir: C:/Program Files/Git/mingw64/bin
18:28:45.036676 git.c:439               trace: built-in: git clone git@*removed*.git
Cloning into 'uebungen'...
18:28:45.093121 run-command.c:663       trace: run_command: unset GIT_DIR; ssh git@*university URL* 'git-upload-pack '\''*university repo*'\'''
18:28:48.140893 run-command.c:663       trace: run_command: git index-pack --stdin -v --fix-thin '--keep=fetch-pack 8492 on DESKTOP-QNIF5QA' --check-self-contained-and-connected
18:28:48.155482 exec-cmd.c:237          trace: resolved executable dir: C:/Program Files/Git/mingw64/libexec/git-core
18:28:48.157663 trace.c:375             setup: git_dir: C:/Users/*removed*/uebungen/.git
18:28:48.157663 trace.c:376             setup: git_common_dir: C:/Users/*removed*/uebungen/.git
18:28:48.157663 trace.c:377             setup: worktree: C:/Users/*removed*
18:28:48.157663 trace.c:378             setup: cwd: C:/Users/*removed*
18:28:48.157663 trace.c:379             setup: prefix: (null)
18:28:48.158012 git.c:439               trace: built-in: git index-pack --stdin -v --fix-thin '--keep=fetch-pack 8492 on DESKTOP-QNIF5QA' --check-self-contained-and-connected
remote:
remote: Enumerating objects: 828, done.
remote:
(...)
remote: Counting objects: 100% (828/828), done.
remote:
(...)
remote:
remote: Compressing objects: 100% (380/380), done.
remote: Total 1184 (delta 490), reused 725 (delta 430)
error: filename in tree entry contains backslash: 'Aufgabe4a.py# coding=utf-8
import random #Liste für die Auswahlmöglichkeiten für den Rechner list = ["Schere", "Stein", "Papier"] #Eingabemöglichkeit für den Benutzer print("Versuchen Sie ihr Glück in Schere, Stein, Papier!") w = (raw_input("Bitte wählen sie Schere, Stein, oder Papier:")) # if w == "Schere":     print("Sie haben Schere gewaehlt!\n") else:     if w == "Stein":         print("Sie haben Stein gewaehlt!\n")     else:         if w == "Papier":             print("Sie haben Papier geweahlt!\n")         else:             print("Sie haben keine zugelassene Eingabe getaetigt!")             exit() #Wahl des Rechners wird, sowie der Ausgang des Spiels entschieden x = list[random.randint(0, 2)] print("Ihr Gegner hat " + x + " gewaehlt!\n")  if w == "Schere":     if x == "Schere":         print("Sie haben unentschieden gespielt!")     else:         if x == "Stein":             print("Stein schleift Schere, Sie haben verloren!")         else:             if x == "Papier":                 print("Schere schneidet Papier, Sie haben gewonnen!") elif w == "Stein":     if x == "Schere":         print("Stein schleift Schere, Sie haben geweonnen!")     elif x == "Stein":         print("Sie haben unentschieden gespielt!")     elif x == "Papier":         print("Papier umfaltet Stein, Sie haben verloren!") elif w == "Papier":     if x == "Schere":         print("Schere schneidet Papier, Sie haben verloren!")     elif x == "Papier":         print("Sie haben unentschieden gespielt!")     elif x == "Stein":         print("Papier umfaltet Stein, Sie haben gewonnen!")'
fatal: Not all child objects of 9(...)c are reachable
fatal: index-pack failed

这是台式机上的调试输出:

21:38:07.768170 exec-cmd.c:237          trace: resolved executable dir:C:/Program Files/Git/mingw64/bin
21:38:07.769170 git.c:440               trace: built-in: git clone git@*uni repo*.git
Cloning into 'uebungen'...
21:38:07.783173 run-command.c:663       trace: run_command: unset GIT_DIR; ssh git@*uni domain* 'git-upload-pack '\''*repo*.git'\'''
21:38:08.587244 run-command.c:663       trace: run_command: git index-pack --stdin -v --fix-thin '--keep=fetch-pack 14672 on Leo-PC' --check-self-contained-and-connected
21:38:08.602247 exec-cmd.c:237          trace: resolved executable dir: C:/Program Files/Git/mingw64/libexec/git-core
21:38:08.604247 trace.c:377             setup: git_dir: C:/Users/*removed*/uebungen/.git
21:38:08.604247 trace.c:378             setup: git_common_dir: C:/Users/*removed*/uebungen/.git
21:38:08.604247 trace.c:379             setup: worktree: C:/Users/*removed*
21:38:08.604247 trace.c:380             setup: cwd: C:/Users/*removed*
21:38:08.604247 trace.c:381             setup: prefix: (null)
21:38:08.604247 git.c:440               trace: built-in: git index-pack --stdin -v --fix-thin '--keep=fetch-pack 14672 on Leo-PC' --check-self-contained-and-connected
remote:
remote: Enumerating objects: 852, done.
(...)                                                                     remote: Counting objects: 100% (852/852), done.
(...)                                                                        remote: Compressing objects: 100% (373/373), done.
remote: Total 1208 (delta 508), reused 792 (delta 461)
Receiving objects: 100% (1208/1208), 6.24 MiB | 36.54 MiB/s, done.
Resolving deltas: 100% (680/680), done.
21:38:09.614724 run-command.c:663       trace: run_command: git rev-list --objects --stdin --not --all --quiet --alternate-refs '--progress=Checking connectivity'
21:38:09.628565 exec-cmd.c:237          trace: resolved executable dir: C:/Program Files/Git/mingw64/libexec/git-core
21:38:09.630566 trace.c:377             setup: git_dir: C:/Users/*removed*/uebungen/.git
21:38:09.630566 trace.c:378             setup: git_common_dir: C:/Users/*removed*/uebungen/.git
21:38:09.630566 trace.c:379             setup: worktree: C:/Users/*removed*
21:38:09.630566 trace.c:380             setup: cwd: C:/Users/*removed*
21:38:09.630566 trace.c:381             setup: prefix: (null)
21:38:09.630566 git.c:440               trace: built-in: git rev-list --objects --stdin --not --all --quiet --alternate-refs '--progress=Checking connectivity'
21:38:09.639568 chdir-notify.c:65       setup: chdir from 'C:/Users/*removed*' to 'C:/Users/*removed*/uebungen'
21:38:09.639568 chdir-notify.c:40       setup: reparent packed-refs to 'C:/Users/*removed*/uebungen/.git/packed-refs'
21:38:09.639568 chdir-notify.c:40       setup: reparent files-backend $GIT_DIR to 'C:/Users/*removed*/uebungen/.git'
21:38:09.639568 chdir-notify.c:40       setup: reparent files-backend $GIT_COMMONDIR to 'C:/Users/*removed*/uebungen/.git'

我已经通过将 Windows 2.23.0 降级到 Git 来解决问题(暂时)。 该问题在最新版本上仍然存在,并且在我的桌面上可重现。

有关此问题的更新,请参阅 VonC's


git-for-windows 存储库(对于 v2.24

有一个未解决的问题

Git 2.24 breaks existing repositories: filename in tree entry contains backslash

用户carlescufi is to disable core.protectNTFS建议的解决方法。

git config --global core.protectNTFS false

此处引用gitdocs

core.protectNTFS

If set to true, do not allow checkout of paths that would cause problems with the NTFS filesystem, e.g. conflict with 8.3 "short" names. Defaults to true on Windows, and false elsewhere.

使用 Git 2.25(2020 年第一季度),该问题应该得到解决。
Windows 的 Git 的较早更新声明,如果树对象中包含带反斜杠的路径组件,则该树对象无效,这过于严格,已得到纠正。

Windows 用户需要的唯一保护是防止此类路径(或他们的文件系统无法检出的任何路径)进入索引。

参见 commit 224c7d7 (31 Dec 2019) by Johannes Schindelin (dscho)
(由 Junio C Hamano -- gitster -- in commit a578ef9 合并,2020 年 1 月 6 日)

mingw: only test index entries for backslashes, not tree entries

Signed-off-by: Johannes Schindelin

During a clone of a repository that contained a file with a backslash in its name in the past, as of v2.24.1(2), Git for Windows prints errors like this:

error: filename in tree entry contains backslash: '\'

The idea is to prevent Git from even trying to write files with backslashes in their file names: while these characters are valid in file names on other platforms, on Windows it is interpreted as directory separator (which would obviously lead to ambiguities, e.g. when there is a file a\b and there is also a file a/b).

Arguably, this is the wrong layer for that error: As long as the user never checks out the files whose names contain backslashes, there should not be any problem in the first place.

So let's loosen the requirements: we now leave tree entries with backslashes in their file names alone, but we do require any entries that are added to the Git index to contain no backslashes on Windows.

Note: just as before, the check is guarded by core.protectNTFS (to allow overriding the check by toggling that config setting), and it is _only_ performed on Windows, as the backslash is not a directory separator elsewhere, even when writing to NTFS-formatted volumes.

An alternative approach would be to try to prevent creating files with backslashes in their file names. However, that comes with its own set of problems.
For example, git config -f C:\ProgramData\Git\config ... is a very valid way to specify a custom config location, and we obviously do _not_ want to prevent that.
Therefore, the approach chosen in this patch would appear to be better.

This addresses git-for-windows/git issue 2435

Saurabh P Bhandari's 中提到的问题)


在 Git 2.32(2021 年第 2 季度)中,cygwin 路径名处理也已修复,ans 对问题的根源进行了更多解释。

参见 commit bccc37f (29 Apr 2021) by Adam Dinwoodie (me-and)
(由 Junio C Hamano -- gitster -- in commit bb2feec 合并,2021 年 5 月 7 日)

cygwin: disallow backslashes in file names

Reported-by: RyotaK
Helped-by: Johannes Schindelin
Signed-off-by: Adam Dinwoodie

The backslash character is not a valid part of a file name on Windows.
If, in Windows, Git attempts to write a file that has a backslash character in the filename, it will be incorrectly interpreted as a directory separator.

This caused CVE-2019-1354 in MinGW, as this behaviour can be manipulated to cause the checkout to write to files it ought not write to, such as adding code to the .git/hooks directory.
This was fixed by e1d911d ("mingw: disallow backslash characters in tree objects' file names", 2019-09-12, Git v2.25.0-rc0 -- merge listed in batch #5).
However, the vulnerability also exists in Cygwin: while Cygwin mostly provides a POSIX-like path system, it will still interpret a backslash as a directory separator.

To avoid this vulnerability, CVE-2021-29468, extend the previous fix to also apply to Cygwin.

As well as checking behaviour in the presence of paths containing backslashes, the existing test also checks behaviour in the presence of paths that differ only by the presence of a trailing ".".
MinGW follows normal Windows application behaviour and treats them as the same path, but Cygwin more closely emulates *nix systems (at the expense of compatibility with native Windows applications) and will create and distinguish between such paths.
Gate the relevant bit of that test accordingly.