繁体   English   中英

如何在 git 中保留 png 文件而不跟踪它们?

[英]How do I keep png files in git without tracking them?

我的 bitbucket 存储库中有我的自述文件所需的 png 文件。 但由于这些是二进制文件,当声纳 bitbucket 插件在它们上运行差异时,我会收到错误消息。

如何在不跟踪文件的情况下保留文件?

我运行了git update-index --skip-worktree filename ,然后运行了git status但标志没有反映。 它说 -

Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean

不确定我是否需要从存储库中删除文件,然后添加跳过工作树标志。 有人可以告诉我我做错了什么,或者是否有更好的方法来保存图像文件而不对它们运行差异? 谢谢你。

在主题行中对您的问题的字面回答:

如何在 git 中保留 png 文件而不跟踪它们?

只是“你没有”。 这是因为在 Git 中,被跟踪的文件是存在于 Git 的index中的文件。

Git 的索引是您必须了解的关键数据结构(否则 Git 的行为是莫名其妙的)。 它的名字太笼统,太糟糕了,以至于它还有两个名字:它也被称为staging area ,或者有时——现在很少被称为cache 这些天来,您主要在某些命令的某些标志中看到术语“缓存”,例如git rm --cachedgit diff --cached 但是这三个术语实际上都指的是同一件事。

该索引的功能复杂且众多,但实际上您必须了解的只是少数几个。 主要的——这也是人们称之为暂存区的原因——是它始终保存将 go 进入您的下一次提交的文件的副本。

“副本”一词可能应该在此处用引号引起来,因为索引中的内容实际上go 进入下一次提交的内容。 提交确实存储文件,但它们以冻结、压缩、Git 化和重复内容删除的形式存储它们。 这允许 Git 在每次提交中存储每个文件。 事实上,新的提交主要存储与前一次提交相同的文件,并且 Git 对每个文件的内容进行重复数据删除,这意味着文件的新“副本”不占用空间。 对于索引中的“副本”也是如此:它们是预先去重的,所以只要它们与当前提交匹配,它们就不会占用空间。 1不过,除此之外,它们确实就像每个文件的副本一样。

换句话说,Git 始终拥有您正在处理或使用的每个(已提交)文件的三个副本:

  • 当前提交中有一个冻结的,永久保存。 您无法更改此格式,并且它不是您可以用于任何内容的格式,但 Git 可以读取它。

  • Git 的索引中有一个“副本”,准备 go 进入下一次提交。 这个副本开始匹配提交的副本(好吧,通常无论如何)。

    此索引副本采用冻结格式,但实际上并未冻结。 如果修改工作树副本,则必须运行git add来更新索引副本。 2

  • 最后,当然还有文件的普通读/写副本。 此副本位于您的工作树工作树中。 这是您可以看到和使用和更改的那个,但它实际上根本不在 Git 中 这不是提交中的副本,也不是准备好 go 进入下一次提交的副本 - 这就是为什么如果您更改此工作树副本,您必须git add文件。

当您运行git commit时,Git 从索引中的任何内容创建快照。 Between the time you run git checkout and the time you run git commit , you can control what's in Git's index, using git add and/or git rm . 因此,Git 索引中的文件副本可以更改,甚至完全删除。 这会影响下一次提交,一旦你真正开始运行git commit 在那之前,它只是“暂存”更新的文件。

git status命令通过运行两个比较来工作:

  • 第一个比较告诉您当前提交和索引之间有什么不同 任何不同的东西都是为 commit 上演的
  • 第二个比较告诉你索引和你的工作树有什么不同 无论有什么不同,都不会为 commit 上演

由于存在三个副本,这就是文件可以同时被暂存和未暂存的方式:提交版本、索引版本和工作树版本都是不同的版本。)

无论如何,我们回到跟踪文件的定义:跟踪文件是您的工作树Git 索引中的任何文件。 未跟踪的文件是现在在您的工作树中的文件,但现在不在 Git 的索引中。 它进入 Git 的索引是因为 (a) 它来自一个提交,和/或 (b) 你运行了git add它。 如果要在新提交中,它必须在 Git 的索引中。 如果它现在不在 Git 的索引中,例如,因为你在它上面使用git rm ,它就不会在下一次提交中。 如果您不想在该提交中使用它,那很好; 但如果您确实希望在该提交中使用它,则需要将其放回 Git 的索引中。

我跑了git update-index --skip-worktree filename ...

这个及其相关--assume-unchanged变体,只需在文件的索引条目中设置一个特殊位(必须Git 的索引中,以便有空间设置该位)。 当该位被设置时,Git 将经常(并非总是,但经常)假装文件的工作树副本与文件的索引副本匹配。 然后它将不理会索引副本。 因此,如果索引副本当前与当前提交副本匹配,则设置该位可确保未来的git add使用工作树副本(或缺少工作树副本)来更新索引副本。 索引副本仅保留在索引中,仍与当前提交匹配。

(When you use git checkout or git switch to switch to a new and different commit, so that Git has to update the index copies of various files, Git will not obey the assume-unchanged or skip-worktree bits, and will normally complain and如果更改索引副本会破坏工作树中任何未提交的工作,请停止提交更改。但这至少有点危险,因为在.gitignore中列出文件可以让 Git 有权销毁工作树副本.)


1他们需要一点空间来保存文件、缓存数据以及 Git 发现在使 Git 工作和 go 快速工作方面有用的任何其他内容。 它们还需要一些字节(目前每个文件 20 个字节)来保存内容 hash ID,这与 Git 的内部存储格式有关。 这意味着列出几千个文件的索引需要几千 KiB 来存储。 例如,在 Git 的 Git 存储库中,我们发现:

$ git ls-files | wc -l

表示索引中有 3865 个文件,并且ls -l on .git/index的索引大小为366964 (字节)。 该索引还存储标题和尾声以及其他项目,因此这里不能保证直接相关,但它通常平均起来非常像这样。

2从技术上讲,这个git add会立即压缩和去重文件的内容,然后更新索引中的Blob hash ID 如果内容已经在其他地方的存储库中,则对新的准备提交文件进行重复数据删除。 如果内容是的,它现在是第一次在存储库中,可以提交。

请注意,如果git add在从工作树中删除文件后添加文件,Git 将在此时删除索引副本。 git add命令实际上意味着使索引副本与工作树副本匹配,如果工作树副本消失,则意味着 Git 应该删除索引副本以匹配。

当然,如果根本没有索引副本,Git 将创建一个新的索引条目,像往常一样对工作树内容进行压缩和去重。 索引现在包含文件名、blob hash ID 和缓存数据,并且索引副本现在与工作树副本匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM