跟踪多个存储库中的相同文件

KcF*_*nMi 2 git version-control

假设我已repo1被跟踪(它包含 .git)。

然后,在其中,我project1从 github 下载。它有自己的 .git 文件夹(我可能会忽略它?)。

继续,我将添加project1repo1.

此时,我会说project1多个存储库正在跟踪中的文件。

我在这里做了一些测试,没有任何问题,显然这种情况可以继续进行。我可以在两个存储库中提交。显然一切都还算顺利。

我是不是忘记了什么?这有危险吗?

tor*_*rek 6

对于Git来说这不是问题。它可能会让您感到困惑和/或让您做一些您不打算做的事情。

\n\n

关键是跟踪三件事:存储库本身工作树(通常每个存储库一个)和索引(针对该存储库或工作树)。1

\n\n

Git 将忽略任何子目录中的所有文件。2 您有一些顶级目录(和存储库),其中包含另一个目录(即它自己的存储库),因此我们可以确定该目录存在,并且可能也存在;但 Git会自动忽略它们。然而,正如您所见,Git不会自动忽略其他文件。也就是说,从内部来看, \xe2\x80\x94中的文件(例如\xe2\x80\x94)被视为有效的路径名,可以被跟踪(在 repo1 的索引中)或未跟踪(不在该索引中)。 .gitrepo1project1repo1/project1/.git/HEADrepo1/project1/.git/refs/heads/masterrepo1project1repo1/project1/READMEproject1/README

\n\n

如果这些文件显示为未跟踪,并且您尝试使用git status它们来查看它们,您将只能看到整个目录(即project1/),除非您要求-uall(或--untracked-files=all)。通常大多数人都会用 隐藏整个目录,这样.gitignore它的文件既不会显示为未跟踪,也不会意外添加。

\n\n

同时,每当您在嵌套层次结构的某个级别执行操作时,“该级别”的 Git 都会捕获它。例如,如果您将当前工作目录更改为repo1并运行git status,您将检查关于 的状态repo1,但如果您随后将其更改为project1并运行git status,您将检查关于 的状态project1

\n\n

如果project1有自己的子目录 ( repo1/project1/sub/) 而没有目录.git则在该子目录中完成的操作为 "in" project1

\n\n

换句话说,除非你给它额外的指令,否则 Git 会从你现在所在的位置开始检查.git. 如果这里没有,它会爬上一个目录并重试。它会重复,直到用完可能的位置来查找(有一些特殊情况的代码可以避免爬出文件系统,因此“可能的位置”可能不会继续到/;这是依赖于操作系统的)。一旦它找到带有 的“顶层” .git,它就会停止攀爬。要查看它停止的位置,请运行:

\n\n
$ git rev-parse --show-toplevel\n
Run Code Online (Sandbox Code Playgroud)\n\n

无论它停止在哪里,那就是工作树所在的位置。3 这通常(但并非总是)也是存储库本身所在的位置:

\n\n
$ git rev-parse --git-dir\n
Run Code Online (Sandbox Code Playgroud)\n\n

(可能显示相对或绝对路径)。

\n\n

通过这种嵌套,您将需要(痛苦地:-))知道您正在使用哪个存储库,因为每个存储库\xe2\x80\x94,或者更准确地说,存储库关联的一些工作树,加上必要的存储库和索引\xe2\x80\x94将被各种Git命令触及。但这种“接触”不会以任何方式通知任何内部 Git 存储库。例如,如果您运行git checkout otherbranch,Git 将通过切换分支来修改当前工作树中的文件,然后修改当前存储库中的 HEAD 提交。如果此工作树与其他存储库的工作树重叠,并且您将自己移至该其他存储库,则突然所有这些(已更改)文件不再与当前存储库的 HEAD 提交匹配。

\n\n

当工作树像这样重叠时,人们就会犯错误。 Git不会关心;它只是处理存储库、工作树和索引。

\n\n
\n\n

1在旧版本的 Git 中,存储库只有一个工作树。如果您使用 new git worktree add,您可以拥有多个工作树,并且每个工作树都有自己的索引。在没有工作树的特殊情况下(脚注 3),仍然有一个索引。

\n\n

2在折叠大小写的系统上曾经存在一些与安全相关的问题,因为您可能拥有名为.GiT/hooks/pre-commitsomedir/.gIT/hooks/pre-commit例如的文件的存储库,这将覆盖您的顶级或子级存储库的挂钩。现代 Git 也会自动忽略.Git.giT.GIt等。

\n\n

3假设确实存在工作树。如果存储库是“裸”的(core.bare已设置,并且未覆盖),则不存在工作树,所有这些问题基本上都会消失。

\n

  • 给出这样的答案,这个问题可能不值得-1,至少就答案而言。 (2认同)