了解git如何处理特定文件?

问题描述 投票:0回答:1

我正在一个我不熟悉的存储库中工作,我需要更好地了解git如何处理各种文件。任何给定的文件可以是以下一个或多个:

  • 已跟踪和最新
  • 已跟踪,正在更改工作树
  • 已跟踪,有阶段性更改
  • 分段添加
  • 未追踪
  • 被.gitignore或其他机制忽略
  • 标记为假定不变
  • 缺少

是否存在某种git info <fileName>命令,它将告诉我git有关该文件的所有信息?

git file status
1个回答
0
投票

在Git中,tracked仅表示存在于索引中。同时,仅untracked文件可以忽略。根据定义,untracked文件是在索引中为not但在工作树(您从事日常工作的区域)中为[[is的文件。

索引也可能最好地描述为

下一次提交的内容

。 (这比这更复杂-因为索引还有一些其他的作用-但这只是简短的版本。)新的git commit只是打包索引中的文件以为新提交创建快照。其他一切都源于此。请记住,实际上始终存在跟踪文件的

3

个活动副本,尽管其中两个可能会丢失:
  • HEAD(当前提交)副本,这是文件最初来自的位置。如果没有HEAD副本,则该文件是新文件:与当前提交相比,它将是下一次提交中的已添加文件。

    HEAD文件的副本,就像任何文件的任何已提交副本一样,都是只读的。您无法做任何改变。它采用特殊的仅Git格式,很难找到:您必须将Git

    extract

转换为可用形式。
  • 有索引副本。从技术上讲,这实际上是对其他地方的副本的引用。它也采用特殊的内部Git格式存储文件(用Git术语表示为“ blob对象”),但是出于您自己的目的,您可以将其视为完整的单独物理副本,因为您可以随时<< [用

    new

  • 副本覆盖,或将其删除。最后,有工作树副本。这是您可以使用普通计算机工具看到的文件的唯一版本。它采用您计算机的普通格式,因此您可以使用此副本进行任何操作。
  • [如果缺少跟踪文件的工作树副本,则与(未删除的)索引副本相比,它看起来已删除。
  • [第一次执行git checkout时,某些提交-每个提交都由其丑陋的哈希ID唯一地指定,以便您可以根据需要签出旧的提交-Git将提交的文件读入索引,以便所有提交的文件

    1现在是HEAD,这是您刚刚检出的提交,索引为[[match

    。同时,该相同的git checkout还从您的工作树中删除了您之前刚刚提交的所有

    tracked

    文件,并将它们替换为来自新HEAD提交的索引文件。 。因此,现在所有索引副本都与所有工作树副本匹配。您的任何[[untracked文件都没有被触摸,只有被跟踪的文件被触摸。效果是在git checkout之后,每个跟踪文件的所有三个副本都匹配HEAD提交中有一个不可更改的副本,该副本已复制到索引中,该副本已复制到您的工作树中。从这里开始,您可以:

    随意修改(或创建或删除)工作树文件;使用git add复制工作树文件

    进入

    索引:现在这两个匹配,并且如果文件以前根本不在索引中,那么现在它在索引中;

      使用git rm
    • both
    索引
  • 工作树删除中的文件:现在,两者都消失了]]]
  • 使用git reset(的一种形式)将文件从HEAD复制到索引,而无需触摸工作树;和/或
  • 使用其他各种Git命令,例如git rm --cached或特殊形式的git checkout,现在在Git 2.23+中通过新的git restore变得更加容易,实现索引和/或工作树的其他操作。无论您做什么,文件的HEAD副本都不会更改。索引副本位于此处,以便跟踪文件,或者不存在,从而取消跟踪文件。工作树副本是否存在:Git并不在乎,因为Git将使用index副本进行下一次提交。
  • 要查看什么[[不同,您必须具有Git比较:
  • HEAD vs index:任何

    the same

    都很无聊; git status对此没有说什么。 different的任何内容都很有趣:git status告诉您
      stage for commit
    ,因为如果您现在运行git commit,则您将进行的新提交将不同于当前的提交。

  • 索引与工作树:相同

  • 的任何内容都很无聊,git status什么也没说。 different的任何内容都很有趣:git status告诉您notstaged for commit,因为您可以更新文件的索引副本(或删除它)以匹配工作树,之后可能不再与当前提交匹配。
  • 最后一次,

    几乎最后-给定任何untracked文件-根据定义它不在索引中-git status会抱怨该文件未被跟踪,除非您使用“忽略”文件以使其关闭。关闭Git的文件就是您忽略的文件。请注意,

    全部三个

    副本中的跟踪文件可以不同。在这种情况下,HEAD运行的两个比较-git status -vs-index和index-vs-work-tree都会产生“有趣”的结果。您将看到文件为暂存为提交未暂存为提交。有时,git status --short的结果将这两个结果都放入多行每文件输出一行的输出的前两列,在这里很有用。

    1

    这有点过分简化。关于何时可以在Checkout another branch when there are uncommitted changes on the current branch中的结帐中携带未提交的更改

  • 的细节很多。
    假定不变且跳过工作树

    您提到--assume-unchanged标志。还有一个--skip-worktree标志。这些标志在内部略有不同,但是在大多数情况下,实现相同的结果。它们只能在索引中

    的文件上设置,因此它们仅适用于跟踪的文件。它们的作用是告诉Git,尤其是git status,它正在进行文件的[[lot比较”,它应该
    不必费心看文件的工作树副本。相反,当Git检查工作树副本时,Git可以

    假定工作树副本与索引副本匹配。

    这些标志有点难以查看,因为它们存储在索引中,索引本身很难查看。 git ls-files命令可以显示它们以及索引中的所有条目-在许多项目中往往是数千行,因此在实践中并没有那么有用。我写了一点Python script that I call git-flagged,以便可以运行git-flagged来查看哪些文件设置了这些标志,并且/或者重置了这些标志,而没有看到很多其他不相关的东西。2

    请注意,git flaggedgit checkout之类的操作将越过这些标志,并警告您是否会覆盖工作树文件。也就是说,您可能会在某些文件上进行本地更改,标记索引副本,以便Git通常停止向您显示未暂存为提交的更改,并进行一段时间的工作,包括进行新的提交,当然可以使用index

    文件的副本,以便它们与先前的提交保持匹配。但是,经过一段时间后,您忘记故意隐藏了这些本地更改。

    有时,在其他定期从中获取提交的其他Git存储库中,其他人更改文件。如果您git merge他们的提交,或git checkout他们的提交,则Git必须将文件的

    their

    版本写入您的工作树。幸运的是,Git不会在没有警告的情况下这样做。不幸的是,您可能忘记了标记了某些文件,并且可能想要获取所有标记文件的完整列表。2您也可以使用git merge或类似的名称,但是当我经常使用这些标志时,可以更方便地使用它们。]

    © www.soinside.com 2019 - 2024. All rights reserved.