gpt4 book ai didi

git - “git ls-files”的作用是什么,以及如何从中删除文件?

转载 作者:行者123 更新时间:2023-12-04 20:46:44 25 4
gpt4 key购买 nike

它显示本地存储库,登台存储库,远程存储库还是其他位置的文件?

我经常看到“ git ls-files”中存在一个文件。该文件已从远程存储库中删除。之后,我尝试进行git pull。但是,该文件仍显示在此命令列表中。它不应在此处显示,因为它也不在远程存储库中。

最佳答案

摘要

您需要全神贯注,Git会为每个文件至少存储三个,有时最多多达五个活动副本:一个在当前提交中,一个(或两个或三个!)在索引中,以及一个(唯一的)您可以在工作树中看到并使用它。 git ls-files命令查看这些副本,然后根据提供给git ls-files的标志告诉您一些副本。

如果没有每个文件三到五个副本的想法,Git中的许多事情将永远毫无意义。 (嗯,尽管有些事情仍然棘手,但这完全是另一个问题。)



我认为这里有两个问题。一种需要一些术语,然后另一种应该适用:


[git ls-files]是否显示本地存储库中的文件,


有点,但是:


登台存储库,


Git没有暂存库。每个存储库都有一个在不同的Git文档中称为索引或暂存区的东西。 (有一个过时的第三个名称,缓存,它也显示在the Git glossary中。)


远程仓库


绝对不是:根本不需要任何远程存储库(即,其他具有自己的存储库的Git),如果存在,只有git fetchgit push可以让您的Git调用其Git并与它们交换数据。 (好吧,git ls-remotegit fetch的头几位,而git pull运行git fetch,所以这两个也与远程交换数据。但是git ls-files却不。)


还是其他地方?


是的,有点。这使我们回到了第一部分。因此,让我们采用the Git glossary中定义的这三个术语。下面的斜体(包括粗斜体)文本直接来自链接的文档:


资料库

refs的集合以及包含来自引用的object database的所有对象的reachable,可能还包含来自一个或多个porcelains的元数据。存储库可以通过alternates mechanism与其他存储库共享对象数据库。 (所有链接都是他们的)

当然,这充满了更多的术语。为了使它神秘化,他们在这里所说的是,适当的存储库不包括索引和工作树:它主要由提交(及其内容)组成。当然,这要求我们定义“索引”和“工作树”,因此让我们继续:
指数

具有统计信息的文件的集合,其内容存储为对象。索引是您的working tree的存储版本。说实话,它还可以包含工作树的第二个甚至第三个版本,在merging时使用。
工作树(我通常将此工作树称为):

实际检出文件的树。工作树通常包含HEAD提交树的内容,以及您已进行但尚未提交的所有本地更改。


提交被永久冻结

当您运行git commit时,Git会为您所有文件(无论如何,所有被跟踪文件)创建快照,并将其以及一些元数据(例如您的姓名和电子邮件地址)存储在提交中。该提交基本上是永久性的-您可以摆脱提交,通常会遇到很多困难,但是为了方便起见,将它们视为永久性的-完全是完全100%只读的。像这样故意是只读的,因为它允许其他提交共享相同的文件副本,因此,如果一次,十次甚至一百万次提交同一文件,则实际上只有一个副本。资料库。只有当您将文件更改为新版本时,Git才能提交新的单独副本。

提交编号,但不是通过简单易用的顺序编号系统编号。也就是说,我们可以将它们绘制为一系列简单的带数字或字母的东西:

... <-C4 <-C5 <-C6 ...


在此以后的每个提交都指向其前身。但是它们的实际名称是丑陋的哈希ID。每个人都保证是唯一的,这就是为什么它们必须如此大,丑陋且外观随意的原因。每个哈希ID实际上是根据提交内容计算的加密校验和,因此,宇宙中每个地方的每个Git都会同意该提交,并且只有该提交才能获得该校验和。这是您(甚至是Git)无法更改的另一个原因:如果您从存储库数据库中取出一个提交,进行修改,甚至只更改一点,然后再将其放回数据库,您得到的就是具有新的和不同的哈希ID的新提交。

因此,提交将永远被冻结。其中的文件也将永久冻结并压缩,并且采用特殊的仅Git格式。我喜欢将这些文件称为“冻干”。这就意味着,嘿,它们非常适合存档,但是对于完成任何新工作却毫无用处……这意味着Git必须提供某种方式来将这些冻干的文件重新水化为文件。有用的形式。

工作树提供有用的表格副本

事情实际上并没有比这简单得多:工作树具有有用的形式,重新水合的文件副本。由于它们只是计算机上的普通日常文件,因此您可以查看,使用它们,随意更改它们,或者以其他方式使用它们。从技术上讲,它们根本不在存储库中,它们只是紧邻存储库。在典型的设置中,存储库本身位于工作树顶层的 .git目录/文件夹中。

显然,如果提取了一个提交来制作工作树,则每个文件现在必须有两个副本:冻干的提交一个,再加上常规工作的一个。 Git可能会在这里停止。 Mercurial确实会在这里停止:如果您使用Mercurial而不是Git,则无需担心第三份副本,因为没有第三份副本。但是Git继续存储文件的更多副本。

索引/暂存区位于提交和工作树之间

Git在这里所做的是在冻干的提交副本和工作树副本之间插入每个文件的第三副本。第三份副本采用提交文件格式(即预先脱水),但是由于不在提交状态,因此实际上并未完全冻结:可以随时替换。这就是 git add的作用: git add从工作树中获取文件的普通副本,将其压缩为冻结干燥的格式,然后替换索引中的副本。或者,如果文件根本不在索引中,则将副本放入索引中。

这就是为什么您必须始终 git add归档文件的原因。在Mercurial中,您只需 hg add一个文件。之后,您只需运行 hg commit,Mercurial就会查看它知道的所有文件,并将其冻结为新的提交。在大型存储库中,这可能需要很长时间。相比之下,Git已经在索引中拥有了它应该知道的所有文件,并且已经脱水,因此 git commit可以将这些脱水的文件打包成一个新的冻结提交。这种速度的代价是 git add,但是如果您对索引副本进行巧妙的欺骗(例如,使用 git add -p),则不仅会获得提速的好处。

正如 the Git glossary在其对索引的描述中所提到的,索引在冲突合并期间承担着扩展角色。当您执行合并操作时(无论是来自 git merge还是来自 git revertgit cherry-pick或使用合并引擎的任何其他Git命令),并且操作都不顺利,Git会把所有三个输入每个文件都放入索引中,因此得到的不仅仅是三个 file.ext副本。但是只要您不在合并的中间,索引中就只有一个副本。

通常,索引副本与 HEAD冻结副本匹配,或与工作树副本匹配,或两者都匹配。例如,在新的 git checkout之后,所有三个副本都匹配。然后,您在工作树中修改 file.ext:现在,提交和索引已匹配,但是它们与工作树副本不同。然后您 git add file.ext,现在索引和工作树匹配,但是它们与冻结副本不同。然后,您 git commit进行一个新提交,该提交成为当前提交,并且所有三个副本再次匹配。

请注意,您可以修改工作树副本:

vim file.ext


然后将更新的副本复制到索引中:

git add file.ext


然后再次编辑它:

vim file.ext


这样,您就可以使所有三个副本都不同。如果这样做, git status会说您已暂存提交的更改,因为索引副本不同于当前提交的副本,并说您未暂存更改的提交,因为工作树副本不同从索引副本。

工作树可以包含根本不在索引中的文件

索引最初只是当前提交的副本。然后,Git还将这些文件复制到工作树中,以便您可以使用它们。但是您可以在工作树中创建文件,而不能在它们上运行 git add。这些文件现在不在索引中,并且如果您运行 git commit,它们也将不在新的提交中,因为Git从索引中构建了新的提交。

您也可以从索引中删除文件,而无需从工作树中删除它们:

git rm --cached file.ext


删除索引副本。当然,它不能触摸当前的提交冻结副本,但是如果您现在进行新提交,则新提交中根本没有 file.ext。 (当然,以前的提交仍然可以。)

当前在您的工作树中且当前不在索引中的任何文件都是未跟踪的文件。它无法跟踪的原因是它不在您的索引中。将该文件放入索引并进行跟踪,无论您如何将其放入索引。不管您如何从索引中删除它,它都不会被跟踪。所以这就是索引的最后一个角色:确定要跟踪的文件,因此将在下一次提交中进行。

现在我们可以清楚地看到 git ls-files的作用

git ls-files的作用是读取所有内容:提交,索引和工作树。根据您为 git ls-files提供的参数,它随后显示索引和/或工作树中某些或所有文件的名称:

git ls-files --stage


列出索引/暂存区中的文件,以及暂存槽号。 (它没有提及 HEAD提交和工作树中的副本。)或者:

git ls-files --others


列出工作树中但不在索引中的(文件名)。 (它没有对 HEAD提交中的副本进行任何说明。)或者:

git ls-files --modified


列出索引中与 HEAD提交中的副本(或根本不在 HEAD提交中的副本)不同的文件(的名称)。没有选择:

git ls-files


列出索引中的文件(的名称),而不考虑 HEAD提交或工作树中的文件。

关于git - “git ls-files”的作用是什么,以及如何从中删除文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56235287/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com