【问题标题】:Is it possible to reconnect a detached and modified folder to a Git repository?是否可以将分离和修改的文件夹重新连接到 Git 存储库?
【发布时间】:2019-12-04 07:27:30
【问题描述】:

我有一个源代码文件夹,该文件夹被错误地文件复制,不包括任何内部 .git 目录,随后被修改。运行 git status 说“致命:不是 git 存储库......”

是否可以将此复制的目录(及其内容)重新连接回原始 Git 存储库或该存储库中的新分支? (并使用 git diff 检查任何源代码更改、提交/推送任何值得保留的内容等)如果是,如何?

【问题讨论】:

    标签: git version-control repository


    【解决方案1】:

    TL;DR:只需将文件放置到位并在其上运行 git add


    首先,让我们先解决一些问题,否则会引起混乱。

    文件夹 是操作系统级别的概念:文件夹包含子文件夹和/或文件。 Git 不存储文件夹。 Git 存储提交,并且提交存储文件(仅——不是文件夹)。

    Git 以一种特殊的、压缩的、只读的、仅限 Git 的格式存储文件。这些文件有全名——例如,a/b/c.ext。它们不存在于文件夹中,它们只是以您的操作系统可能坚持需要将其分解为个文件夹的方式命名。这些存储的文件都不能更改!他们一直被冻结。这对于存档非常有用——例如,用于查看旧版本的文件——但对于完成任何工作完全无用。另外,当然,这些冻结的文件是仅 Git 格式。您计算机上的其余程序根本无法使用它们。冻结的文件深埋在您的操作系统坚持 Git 必须使用的 .git 目录/文件夹中;在这里他们有奇怪的名字,比如11ccea40716d9bbcef731f093e530a9b1aee0013。它们甚至可能根本没有明显的名称(当“打包”时),但在这种情况下,它们仍然可以通过使用 11ccea40716d9bbcef731f093e530a9b1aee0013 作为键的数据库访问。

    为了让您使用、更改和存储新版本的文件,Git必须为您提供一个单独的工作区。 Git 将此工作区(Git 允许您查看和处理文件的地方)称为 work-treeworking tree,或此名称的任何数量的类似变体.

    这个工作树中的文件实际上并没有被 Git使用!它们只是被提取出来的,通常是从一些提交中提取的。提交包含 Git 应该使用的名称,例如 Makefilebuiltin/rebase.c,以及 Git 可以用来检索文件数据的内部怪异名称。如果操作系统要求 Git 这样做,Git 将提取文件,创建任何文件夹。例如,为了使文件具有像 builtin/rebase.c 这样的名称,操作系统要求 Git 首先创建一个 builtin 文件夹,如果它尚不存在,那么 Git 会这样做。

    如果您以任何方式更改其中一个文件,则必须告诉 Git:Makefilebuiltin/rebase.c 的工作树版本复制回临时存储您将在其中进行新提交的区域。您可以使用 git add 执行此操作。

    运行 git add <em>path</em> 告诉 Git:嗨!如果您有一个具有此名称的文件的现有副本,准备进入下一次提交,请将其替换为工作树中的版本。如果没有,请将文件的副本放入我们正在构建下一个提交的存储区域。这个存储区域,您在其中组装新提交,称为 - 各种 - 索引 em>,或 暂存区,或(现在很少)缓存

    您可以随时在您的工作树中拥有索引中的文件。工作树中但不在索引中的文件称为未跟踪文件。一个充满未跟踪文件的整个文件夹通常通过打印文件夹名称而不是所有单个文件名来总结,但实际上,它是该文件夹中的文件 - 使用它们的全名,而不是切片的文件夹化名称您的操作系统要求 - 不在您的索引中,因此不会在您的下一次提交中。

    您可以使用简单的git add <em>folder</em> 添加整个文件夹,其中包含文件。 Git 将通读该文件夹以查找其所有文件,从中组合全名,并将这些全名git add 每个全名添加到索引中,从而创建该文件的随时可冻结的副本。 (但请参阅下面对.gitignore 的描述。)您最终的下一个git commit 将进行一个新的全时间冻结提交。将成为您当前提交的新提交将包含您运行 git commit 时索引中的每个文件,以此时索引中的形式。。 p>

    Git 使用每个文件的索引副本,而不是工作树副本,这就是为什么您在更改文件时必须经常重新git add 的原因。 (有一些快捷方式,例如 git add -ugit commit -a,它让 Git 扫描您的整个工作树以查找自索引副本以来您更改的文件,并自动更新它们,但这仍然只是真正的意思 先更新索引,再提交)

    要获取索引中的所有文件的列表——请注意,这个列表可能很长,而且几乎没有任何用处——你可以运行git ls-files。但与其这样做,通常最好运行git statusgit status 命令将:

    • 首先,列出您所在分支的名称,有时还可以提供更多信息。

    • 然后,对于索引中的每个文件,比较该文件的内容与当前(永久冻结)提交中的对应文件。对于匹配的文件,什么也不说。对于匹配的文件,说这个文件为提交暂存。如果有 10,000 个文件,但其中只有 2 个不匹配,您会得到一个很好的简短列表,告诉您如果您现在提交,new 快照有两个文件与 旧快照。

      对于当前提交中而不是索引中的文件,将它们称为暂存删除。

    • 单独:对于索引和/或工作树中的每个文件,将准备冻结的索引副本与工作树副本进行比较。如果两者匹配,则什么也不说。如果他们匹配,说点什么:说这个文件没有为提交暂存

      如果索引中有文件,但工作树中没有,git status 会将它们标记为“已删除”。

      如果有文件在工作树中,但不在索引中......好吧,这就是.gitignore 的来源。git status 命令通常会抱怨这些文件,说它们是 未追踪。也就是说,毕竟,未跟踪文件的定义:它是工作树中的文件,但不在索引中。

    不过,对于许多软件开发来说,拥有数千个未跟踪的文件是完全正常的。我们需要一种方法让 Git 不再抱怨它们。列出这些文件,或命名模式,如 *.o*.pyc__pycache__/,告诉 Git:闭嘴这些未跟踪的文件。它还具有告诉 Git 的重要且有用的副作用:如果我对整个文件夹中的文件进行整体添加,如果它们尚未在索引中,请不要将它们添加到索引中. 这意味着您通常只需git add . 即可添加所有内容:已跟踪的文件会在需要时更新,以及任何未明确忽略的文件 被跟踪。

    您只需将一个包含文件的整个文件夹移动(或复制)到您的工作树中。这些文件当前不在索引中,因此它们都不会被跟踪。您只需git add 他们将当前 版本放入索引中。它们不会有以前的版本——现有的提交无法更改,因为它们一直被冻结——但它们将在你所做的下一个提交中,并继续从那时起,在每次提交中,直到您明确地将它们从索引中删除

    在您的情况下,如果您的充满新文件的文件夹中有一些不应被跟踪的文件,您可能需要使用 git status 来查看哪些文件现在被列为未跟踪。如果其中一些不应该被跟踪,您可以在.gitignore 文件中列出它们。 然后您可以执行git add <em>folder</em> 操作。如果git status 通过显示来总结它们:

    Untracked files:
        ...
        folder/
    

    您可以运行 git status -uall 让 Git 向您显示所有文件名,而不是将它们汇总为文件夹名称。

    【讨论】:

    • 你是什么意思“把文件到位”?回到 git 跟踪的工作目录树?否则,当前副本目录中的所有 git 命令都会出错。或者我应该在这个未跟踪的文件夹中执行 git init。
    • 你在某个地方有一个 Git 存储库,例如,在 /home/me/src/foo/ 中,其中有一个 .git/。只需将其他文件复制到那里:cp -r /path/to/files /home/me/src/foo/new。这将创建一个 new/ 文件夹,其中包含所有文件的副本。这是在该 Git 存储库中的工作树中。所有这些文件现在都未跟踪。
    • 这个怎么样?我将所有文件从断开连接的工作文件夹 (xyz/) 移到 foo/.然后我将一个新的(旧的)集克隆到该文件夹​​(xyz/)中。然后我从 foo/ 复制所有内容,用 .git 破坏当前存在的同名文件(在 xyz/ 中)。复制的文件现在会被 git 跟踪吗?
    • 复制的文件现在将位于 Git 让您使用的 work-tree 中。文件是否在 Git 的 index 中(在 .git/index 文件中)取决于 Git 之前签出 into 工作树的提交是否包含这些文件它。同样,模型是:Git 的文件在 .git 中,采用 Git-ish 格式,您无法控制。 Git 让您可以随意处理您的工作树,它是您的普通计算机格式。您可以在此工作树中随时做任何您想做的事情。然后,您可以告诉 Git:请查看我的工作树,使用 git status 和/或 git add
    • 您可以随时对工作树中的任何文件进行任何操作。吉特不在乎。然后你告诉 Git:将你存储的东西与我的工作树比较git status),或者:从你存储的东西覆盖我的工作树中的东西(@987654368 @),或者:将工作树中的内容复制回您存储的内容中 (git add)。还有一些这样的命令,但总的来说,其想法是:您的工作树是您的,可以随意折叠、旋转或破坏。只需将 .git/* 操作留给 Git 本身。
    猜你喜欢
    • 1970-01-01
    • 2013-03-03
    • 2020-12-11
    • 2012-03-09
    • 2021-03-11
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多