跟踪多个存储库中的相同文件 [英] Track the same files in multiple repositories

查看:123
本文介绍了跟踪多个存储库中的相同文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



继续,我将添加 project1 repo1



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



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



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

解决方案

这对于 Git 不是问题。它可能会让你迷惑自己,和/或让你做你不想做的事。



关键是要记住三件事:存储库本身工作树(通常每个存储库一个)和索引(用于该存储库或工作树)。



Git会忽略中的所有文件任何 .git 子目录。 2 您有一些顶级 repo1 目录(和存储库),其中包含另一个目录 project1 (这是它自己的仓库),因此我们可以确定存在 repo1 / project1 / .git / HEAD repo1 / project1 / .git / refs / heads / master 也可能存在;但Git 自动忽略它们。但是,正如你看到的,Git 不会自动忽略其他文件。也就是说,从 repo1 中, project1 - 例如 repo1 / project1 / README中的文件 - 被视为一个有效的路径名称 project1 / README ,可以跟踪(在repo1的索引中)或未跟踪如果这些文件显示为未跟踪,并且您尝试使用 git status 来查看它们,除非你要求 -uall project1 / ) c>(或 - untracked-files = all )。通常大多数人都会用 .gitignore 隐藏整个目录,这样它的文件既不会显示为未跟踪,也不会意外添加。



与此同时,只要您坐在嵌套层次结构的某个层次上进行操作,在该层级上的Git就会抓住它。例如,如果您将当前工作目录更改为 repo1 并运行 git status ,您将检查状态至 repo1 ,但如果您将其更改为 project1 并运行 git status ,您将检查相对于 project1 的状态。



如果 project1 有一个自己的子目录( repo1 / project1 / sub / ), not 有一个 .git 目录中,在该子目录中完成的操作是in project1



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

  $ git rev-parse --show-toplevel 


$ b

无论停在哪里,这都是工作树所在。 3 通常(但不总是)存储库本身也是:

  $ git rev-parse --git-dir 

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

使用这种嵌套,你需要(痛苦地:-))知道你正在使用哪个版本库,因为每个版本库 - 或者更准确地说是与关联的一些工作树 >存储库以及必要时的存储库和索引 - 将会被各种Git命令所触及。但这个感人不会以任何方式通知任何内部Git存储库。例如,如果运行 git checkout otherbranch ,Git将通过切换分支来修改当前工作树中的文件,然后修改当前存储库中的HEAD提交。如果这个工作树与某些其他仓库的工作树重叠,并且您将自己移动到其他仓库中,那么突然间所有这些(更改过的)文件都不再符合您当前的仓库的HEAD提交。



当工作树重叠时,人们会犯错误。 不会在乎;它只是处理一个存储库,一个工作树和一个索引。






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



2 因为您可能拥有名为 .GiT / hooks / pre-commit 或<$ c $的文件的存储库,因此在系统上存在一些与安全相关的问题例如,c> somedir / .gIT / hooks / pre-commit 会覆盖顶级或次级存储库的钩子。现代Git会自动忽略 .Git .giT .GIt ,等等。



3 假设有一个工作树,那就是。如果存储库是裸露的( core.bare 被设置,并且没有被覆盖),那么存在 no 工作树,所有这些问题基本上只是消失。


Let's say I have repo1 being tracked (it contains .git).

Then, inside of it, I download project1 from github. This has it's own .git folder (which I might ignore?).

Proceeding, I'll add project1 to repo1.

At this point, I'll say files in project1 are being tracked by multiple repositories.

I did some tests here without any issues, apparently this situation can be carried on. I can commit in both repositories. Apparently everything is still in order.

Did I forget anything? Is this someway dangerous?

解决方案

It's not a problem for Git. It may let you confuse yourself, and/or let you do things you did not intend.

The key is to keep track of three things: the repository itself, the work-tree (usually one per repository), and the index (for that repository or work-tree).1

Git will ignore all files within any .git sub-directories.2 You have some top level repo1 directory (and repository) that contains another directory project1 (that is its own repository), hence we can be sure that repo1/project1/.git/HEAD exists, and repo1/project1/.git/refs/heads/master probably exists too; but Git automatically ignores them. However, as you saw, Git does not automatically ignore other files. That is, from within repo1, files within project1—such as repo1/project1/README—are seen as a valid path name project1/README, which can be either tracked (in the index for repo1) or untracked (not in that index).

If these files are showing up as untracked, and you try to use git status to view them, you will see only the directory-as-a-whole (i.e., project1/), unless you ask for -uall (or --untracked-files=all). Usually most people hide the entire directory away with a .gitignore so that its files neither show up as untracked, nor accidentally get added.

Meanwhile, any time you do an operation while sitting at some level of this nesting hierarchy, the Git "at that level" will catch it. For instance, if you change your current working directory into repo1 and run git status, you will examine the status with respect to repo1, but if you then change it to project1 and run git status, you will examine the status with respect to project1.

If project1 has a subdirectory of its own (repo1/project1/sub/) that does not have a .git directory, operations done in that sub-directory are "in" project1.

In other words, unless you give it extra instructions, Git starts from where you are now and checks for .git. If there is none here, it climbs up one directory and tries again. It repeats until it runs out of possible places to look (there's some special case code to avoid climbing out of a file system, so "possible places" may not continue up to /; this is OS-dependent). Once it finds thae "top level" with a .git, it stops climbing. To see where it stopped, run:

$ git rev-parse --show-toplevel

Wherever it stopped, that's where the work-tree is.3 That's usually (but not always) where the repository itself is as well:

$ git rev-parse --git-dir

(which may show a relative or absolute path).

With this kind of nesting, you will need to be (painfully :-) ) aware of which repository you're working with, because each repository—or, more precisely, some work-tree associated with the repository, plus the repository and index as necessary—will get touched by various Git commands. But this "touching" won't inform any inner Git repositories in any way. For instance, if you run git checkout otherbranch, Git will modify files in your current work-tree by switching branches, and then modify the HEAD commit in your current repository. If this work-tree overlaps the work-tree of some other repository, and you move yourself into that other repository, suddenly all those (changed) files no longer match your current repository's HEAD commit.

When work-trees overlap like this, people make mistakes. Git won't care; it's just dealing with a repository, a work-tree, and an index.


1In older versions of Git there is only one work-tree for a repository. If you use the new git worktree add, you can have more than one work-tree, and each will have its own index. In the special case of having no work-tree (footnote 3), there's still one index.

2There used to be some security-related issues on systems that folded case, because you could have repositories that had files named .GiT/hooks/pre-commit or somedir/.gIT/hooks/pre-commit for instance, which would overwrite your top or sub-level repositories' hooks. Modern Git automatically ignores .Git, .giT, .GIt, and so on as well.

3Assuming there is a work-tree at all, that is. If the repository is "bare" (core.bare is set, and not overridden), then there is no work-tree and all these questions basically just vanish.

这篇关于跟踪多个存储库中的相同文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆