我需要一个用于跟踪更改的本地存储库和一个仅包含其中一些文件的远程存储库。
我在项目中添加了一个父目录以初始化本地存储库,并在项目目录中将另一个git初始化为另一个远程存储库,并将其发布到GitHub。
父回购的.gitignore文件为空,但子代中的.gitignore排除了所有父项,除了某些特定的子项。 父存储库不应使用子存储库的.gitignore文件。
我需要本地存储库来跟踪所有文件,而需要远程存储库来跟踪其中的一些文件。问题是父存储库在项目内部不包含任何内容。
我尝试了this submodule solution,但是它为新存储库创建了一个新文件夹,而不是使用现有文件夹。
这是父存储库的git add -A的输出:
# Getting all the values of key in d:
values = recursively_find_dict_values(d, key)
# Checking if key has value v in d:
if v in recursively_find_dict_values(d):
print('Success!')
答案 0 :(得分:0)
您可以嵌套存储库。这是一个示例(我的Git版本与您的Git版本略有不同),在这台特定的计算机上,当前版本为2.14.1,但是我收到了同样的新git add
抱怨和行为,这需要一点技巧。
$ mkdir trepo
$ cd trepo
$ git init
Initialized empty Git repository in ...
$ echo testing nested dirs > README
$ git add README
$ git commit -m initial
[master (root-commit) 1eb37c9] initial
1 file changed, 1 insertion(+)
create mode 100644 README
顶层存储库(path/trepo
)现在存在,其中只有一个提交。单独的提交包含一个文件README
。
$ mkdir sub
$ cd sub
$ git init
Initialized empty Git repository in .../trepo/sub/.git
$ echo this is a nested subdirectory > README
$ git add README
$ git commit -m initial-sub
[master (root-commit) 943378a] initial-sub
1 file changed, 1 insertion(+)
create mode 100644 README
该子存储库现在存在,并且一次提交包含一个名为README
的文件。如果现在返回上一级,我们可以 说服Git将文件添加到sub
中。但是,正如您所发现的,如果我们使用git add sub
,则将一个足够现代的Git(我不确定何时会出现这种新行为),将sub
添加为子模块,好吧,将其添加为破碎的子模块-而不是添加内部 sub
中包含的文件。因此,我们将在每个git add sub
中显式添加文件,而不是sub
(对于每个这样的文件,这很容易,因为现在只有一个,请记住,我们想< em>跳过 .git
目录及其所有内容):
$ cd ..
$ git add sub/README
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: sub/README
让我们继续进行此操作,然后在sub
中创建另一个文件以查看会发生什么:
$ git commit -m 'add sub/README'
[master a7fb248] add sub/README
1 file changed, 1 insertion(+)
create mode 100644 sub/README
$ echo another test > sub/newfile
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
sub/newfile
nothing added to commit but untracked files present (use "git add" to track)
$ (cd sub; git status)
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
newfile
nothing added to commit but untracked files present (use "git add" to track)
因此,既然我们的trepo/.git
存储库正在跟踪sub
中的文件,事情就会按照我们期望的方式运行。
正如我在评论中指出的那样,您可以完成所有这一切。我见过人们尝试这种方法。他们通常不满意。不过,如果它对您有用,那么Git是一种工具,而不是解决方案。随便使用它!
(请注意,在使用子模块时,“顶层”存储库(Git将其称为 superproject )将不包含与子存储库相同的内容。) ,超级项目中的每个提交将在每个提交中包含一个称为 gitlink 的特殊Git条目,该条目记录Git应该git checkout
在其中的正确的哈希ID 。子模块是一个完全独立的Git存储库,可以单独使用,可以作为独立项目使用。要与超级项目一起使用,请克隆超级项目,然后让Git使用超级项目的.gitmodules
文件来了解如何克隆子模块,然后,您从超级项目中提取的每个现有提交都知道在子项目中提取的子提交,并且每个子提交都知道您在超级项目中的 make 新提交将记录正确的子项目提交,这取决于您确保那些新的超级项目提交 do 记录正确的子项目commi t。)
这不会按照您想要的方式工作。信息库不保存文件-好吧,不是直接保存文件。存储库保存 commits 。如果连接两个存储库,它们将共享的是一组 commits 。
任何给定的提交都拥有(文件的)快照,因此从特定的意义上讲,存储库确实拥有文件。但是它一次只能让他们一次提交。通常,您git checkout
进行整个提交。我们将此提交称为C1
。这将填充您的工作树,并且非常重要的是,还将填充您的索引/临时区域。 1 您的工作树现在具有C1
中的所有文件。 / p>
如果您随后从该提交切换到其他提交C2
,则Git 会删除所有与C1
一起且不在C2
中的文件。您的索引和工作树现在匹配提交C2
,而不是提交C1
。
在这一点上,请不要关注.gitignore
,因为它基本上无关紧要。在Git工作树中的 tracked 文件集就是索引中的那些文件。它们存在于索引 中,因为您从提交C1
或C2
中提取了它们,无论您签出的是哪个。因此,这些文件将被跟踪,而工作树中的任何其他文件(无论它们可能到达那里)都将被跟踪。
.gitignore
的作用是防止Git对未跟踪的文件进行投诉。通常,Git会对您发牢骚,建议您将它们添加到要执行的 next 提交中。因此,例如,如果您有一堆构建工件,则可以在.gitignore
中列出它们,并防止Git抱怨。作为令人愉快的副作用,这还意味着git add .
或git add --all
不会添加未跟踪的文件,但是它们的“未跟踪状态”是它们的结果目前不在索引中。
如果您git checkout
进行了其他提交C3
,并且其中还有其他文件集,则Git将从工作树中删除任何 C3
中不是,并且将C3
中的任何文件添加到索引和工作树中。 (当然,它会将两次提交中的文件的内容更改为C3
的内容。)根据定义,C3
中的文件现在是,跟踪。
注意:提交由其哈希ID唯一标识。存储库具有完整的提交,或者没有任何提交。当您连接两个存储库时,Git的一般过程是将发送存储库所具有的 all 提交全部拉入自身,而接收存储库所缺少的 all 提交。 2 这是整个提交< / em>,而不是文件。然后,您git checkout
这些提交之一来填充索引和工作树。诸如master
和develop
之类的分支名称主要用于标识一个 specific 提交,即Git用作该分支的尖端的提交。
您可以通过对多个索引文件进行花哨的技巧来获得所需的内容。但是,您将需要具有单个共享工作树的单独(未连接)存储库,这很棘手,并且您需要分别 将所有内容分别提交给两个单独的存储库,这也很棘手。您也将无法有效地使用.gitignore
文件(您将需要使用每个仓库$GIT_DIR/info/exclude
)。我不建议尝试此操作:我不认为自己想尝试这样做,而且我知道Git的大多数黑暗角落。 :-)
1 此索引事物实际上具有三个名称,反映了其三个目的:(1)索引工作树; (2)充当暂存区,在其中构建您将要进行的 next 提交; (3)作为缓存来使git commit
变得非常快。
2 这是一个故意夸大的事实-事实与图论和reachability有关-但对于初始视图来说已经足够了。