简体   繁体   English

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

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

I have png files in my bitbucket repo that I need for my readme file.我的 bitbucket 存储库中有我的自述文件所需的 png 文件。 But since these are binary files, I'm getting an error when the sonar bitbucket plugin runs diff on them.但由于这些是二进制文件,当声纳 bitbucket 插件在它们上运行差异时,我会收到错误消息。

How can I keep the files without it getting tracked?如何在不跟踪文件的情况下保留文件?

I ran git update-index --skip-worktree filename and then git status but the flag is not reflecting.我运行了git update-index --skip-worktree filename ,然后运行了git status但标志没有反映。 It said -它说 -

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

Not sure if I need to remove the file from the repo and then add the skip worktree flag.不确定我是否需要从存储库中删除文件,然后添加跳过工作树标志。 Can someone please tell me what I'm doing wrong or if there's a better way of saving image files without running diff on them?有人可以告诉我我做错了什么,或者是否有更好的方法来保存图像文件而不对它们运行差异? Thank you.谢谢你。

The literal answer to your question in the subject line:在主题行中对您的问题的字面回答:

How do I keep png files in git without tracking them?如何在 git 中保留 png 文件而不跟踪它们?

is simply "you don't".只是“你没有”。 That's because in Git, a tracked file is a file that exists in Git's index .这是因为在 Git 中,被跟踪的文件是存在于 Git 的index中的文件。

Git's index is a crucial data structure that you must know about (Git's behavior is inexplicable otherwise). Git 的索引是您必须了解的关键数据结构(否则 Git 的行为是莫名其妙的)。 Its name is so generic, and so bad, that it has two other names: it's also called the staging area , or sometimes—rarely these days—the cache .它的名字太笼统,太糟糕了,以至于它还有两个名字:它也被称为staging area ,或者有时——现在很少被称为cache These days you mostly see the term "cache" in some of the flags to some commands, such as git rm --cached or git diff --cached .这些天来,您主要在某些命令的某些标志中看到术语“缓存”,例如git rm --cachedgit diff --cached But all three terms really refer to this same thing.但是这三个术语实际上都指的是同一件事。

The index's functions are complicated and numerous but there are really just a few that you have to know about.该索引的功能复杂且众多,但实际上您必须了解的只是少数几个。 The main one—which is also why people call it the staging area —is that it holds, at all times, copies of the files that will go into your next commit.主要的——这也是人们称之为暂存区的原因——是它始终保存将 go 进入您的下一次提交的文件的副本。

The word "copies" should perhaps be in quotes here, because what's in the index really is what will go into the next commit. “副本”一词可能应该在此处用引号引起来,因为索引中的内容实际上go 进入下一次提交的内容。 Commits do store files, but they store them in a frozen, compressed, Git-ified, and de-duplicated-content form.提交确实存储文件,但它们以冻结、压缩、Git 化和重复内容删除的形式存储它们。 This allows Git to store every file in every commit .这允许 Git 在每次提交中存储每个文件。 The fact that a new commit mostly stores the same files as the previous commit, and that Git de-duplicates the contents of each file, means that the new "copies" of the file take no space.事实上,新的提交主要存储与前一次提交相同的文件,并且 Git 对每个文件的内容进行重复数据删除,这意味着文件的新“副本”不占用空间。 This is true for the "copies" in the index as well: they're pre-de-duplicated, so as long as they match the current commit, they take no space.对于索引中的“副本”也是如此:它们是预先去重的,所以只要它们与当前提交匹配,它们就不会占用空间。 1 Other than this, though, they really do act like copies of each file. 1不过,除此之外,它们确实就像每个文件的副本一样。

In other words, Git has, at all times, three copies of each (committed) file that you're working on or with:换句话说,Git 始终拥有您正在处理或使用的每个(已提交)文件的三个副本:

  • There is a frozen one, saved for all time, in the current commit .当前提交中有一个冻结的,永久保存。 You can't change this one, and it's not in a format you could use for anything, but Git can read it.您无法更改此格式,并且它不是您可以用于任何内容的格式,但 Git 可以读取它。

  • There's a "copy" in Git's index, ready to go into the next commit. Git 的索引中有一个“副本”,准备 go 进入下一次提交。 This copy starts out matching the committed copy (well, normally anyway).这个副本开始匹配提交的副本(好吧,通常无论如何)。

    This index copy is in the frozen format , but it's not actually frozen.此索引副本采用冻结格式,但实际上并未冻结。 If you modify the work-tree copy, you must run git add to update the index copy too.如果修改工作树副本,则必须运行git add来更新索引副本。 2 2

  • Last, there is, of course, an ordinary read/write copy of the file.最后,当然还有文件的普通读/写副本。 This copy is in your working tree or work-tree .此副本位于您的工作树工作树中。 This is the one you can see and use and change, but it's actually not in Git at all .这是您可以看到和使用和更改的那个,但它实际上根本不在 Git 中 It's not the copy that's in the commit, and it's not the copy that's ready to go into the next commit either—which is why you have to git add the file if you change this work-tree copy.这不是提交中的副本,也不是准备好 go 进入下一次提交的副本 - 这就是为什么如果您更改此工作树副本,您必须git add文件。

When you run git commit , Git makes the new snapshot from whatever is in the index.当您运行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 . 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 . So the copies of files that are in Git's index can change, or even get removed entirely.因此,Git 索引中的文件副本可以更改,甚至完全删除。 This affects the next commit, once you actually get around to running git commit .这会影响下一次提交,一旦你真正开始运行git commit Until then, it just "stages" the updated file(s).在那之前,它只是“暂存”更新的文件。

(The git status command works by running two comparisons: git status命令通过运行两个比较来工作:

  • The first comparison tells you what's different between the current commit and the index.第一个比较告诉您当前提交和索引之间有什么不同 Whatever is different is staged for commit .任何不同的东西都是为 commit 上演的
  • The second comparison tells you what's different between the index and your work-tree.第二个比较告诉你索引和你的工作树有什么不同 Whatever is different is not staged for commit .无论有什么不同,都不会为 commit 上演

Since there are three copies, this is how a file can be both staged and not-staged at the same time: the committed version, the index version, and the work-tree version are just all different versions.)由于存在三个副本,这就是文件可以同时被暂存和未暂存的方式:提交版本、索引版本和工作树版本都是不同的版本。)

In any case, we get back to the definition of a tracked file: A tracked file is any file that is in your work-tree and in Git's index right now.无论如何,我们回到跟踪文件的定义:跟踪文件是您的工作树Git 索引中的任何文件。 An untracked file is a file that is in your work-tree right now, but not in Git's index right now.未跟踪的文件是现在在您的工作树中的文件,但现在不在 Git 的索引中。 It got into Git's index because (a) it came out of a commit, and/or (b) you ran git add on it.它进入 Git 的索引是因为 (a) 它来自一个提交,和/或 (b) 你运行了git add它。 It has to be in Git's index if it is to be in a new commit.如果要在新提交中,它必须在 Git 的索引中。 If it's not in Git's index now, eg, because you used git rm on it, it won't be in the next commit.如果它现在不在 Git 的索引中,例如,因为你在它上面使用git rm ,它就不会在下一次提交中。 If you don't want it in that commit, that's fine;如果您不想在该提交中使用它,那很好; but if you do want it in that commit, you will need to put it back into Git's index.但如果您确实希望在该提交中使用它,则需要将其放回 Git 的索引中。

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

This, and its related --assume-unchanged variant, just set a special bit in the index entry for the file (which has to be in Git's index, so that there's room for the bit to be set).这个及其相关--assume-unchanged变体,只需在文件的索引条目中设置一个特殊位(必须Git 的索引中,以便有空间设置该位)。 When the bit is set, Git will often—not always, but often— pretend that the work-tree copy of the file matches the index copy of the file.当该位被设置时,Git 将经常(并非总是,但经常)假装文件的工作树副本与文件的索引副本匹配。 It will then leave the index copy alone.然后它将不理会索引副本。 So if the index copy currently matches the current-commit copy, setting the bit makes sure that a future git add doesn't use the work-tree copy (or lack thereof) to update the index copy.因此,如果索引副本当前与当前提交副本匹配,则设置该位可确保未来的git add使用工作树副本(或缺少工作树副本)来更新索引副本。 The index copy just remains there, in the index, still matching the current commit.索引副本仅保留在索引中,仍与当前提交匹配。

(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 stop the commit-changing if changing the index copy will destroy any uncommitted work in your work-tree. But this is at least a little bit dangerous, because listing the file in .gitignore can give Git the right to destroy the work-tree copy.) (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 They take a little space to hold the file names , cache data, and whatever else Git finds useful in terms of making Git work and go fast. 1他们需要一点空间来保存文件、缓存数据以及 Git 发现在使 Git 工作和 go 快速工作方面有用的任何其他内容。 They also take some bytes—currently 20 bytes per file—to hold content hash IDs, which relates to Git's internal storage format.它们还需要一些字节(目前每个文件 20 个字节)来保存内容 hash ID,这与 Git 的内部存储格式有关。 This means that an index listing a few thousand files takes a few thousand KiB to store.这意味着列出几千个文件的索引需要几千 KiB 来存储。 For instance, in a Git repository for Git, we find:例如,在 Git 的 Git 存储库中,我们发现:

$ git ls-files | wc -l

says that there are 3865 files in the index, and ls -l on .git/index turns up an index size of 366964 (bytes).表示索引中有 3865 个文件,并且ls -l on .git/index的索引大小为366964 (字节)。 The index also stores headers and trailers and other items, so there's no guaranteed direct correlation here, but it usually averages out pretty much like this.该索引还存储标题和尾声以及其他项目,因此这里不能保证直接相关,但它通常平均起来非常像这样。

2 Technically, this git add compresses and de-duplicates the file's content immediately, and then updates the blob hash ID in the index. 2从技术上讲,这个git add会立即压缩和去重文件的内容,然后更新索引中的Blob hash ID If the content is already in the repository elsewhere, the new ready-to-commit file is de-duplicated.如果内容已经在其他地方的存储库中,则对新的准备提交文件进行重复数据删除。 If the content is new , it's now in the repository for the first time, ready to be committed.如果内容是的,它现在是第一次在存储库中,可以提交。

Note that if you git add a file after removing it from your working tree, Git will remove the index copy at this point.请注意,如果git add在从工作树中删除文件后添加文件,Git 将在此时删除索引副本。 The git add command really means make the index copy match the work-tree copy , and if the work-tree copy is gone, this means Git should remove the index copy to match. git add命令实际上意味着使索引副本与工作树副本匹配,如果工作树副本消失,则意味着 Git 应该删除索引副本以匹配。

Of course, if there's no index copy at all, Git will create a new index entry, compressing and de-duplicating the work-tree content as usual.当然,如果根本没有索引副本,Git 将创建一个新的索引条目,像往常一样对工作树内容进行压缩和去重。 The index now holds the file name, blob hash ID, and cache data, and the index copy now matches the work-tree copy.索引现在包含文件名、blob hash ID 和缓存数据,并且索引副本现在与工作树副本匹配。

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

相关问题 停止跟踪 git 中的文件(不删除它们) - Stop tracking files in git (without deleting them) 为什么 Git 忽略 png 文件,我如何“取消忽略”它们? - Why does Git ignore png files and how do I 'un-ignore' them? 如何在git中添加和跟踪文件而不跟踪它们所在的目录? - How can I add and track files in git without tracking the directories they are in? 如何在 GitHub 上保留最新版本的二进制文件而不完全跟踪它们? - How to keep newest version of binary files on GitHub without fully tracking them? 如何让 git 停止跟踪具有相同扩展名的文件? - How do I make git stop tracking files with the same extension? Git 从分支签出文件而不跟踪它们 - Git checkout files from a branch without tracking them 如何在不删除文件的情况下取消跟踪或忽略文件? - How Do I untrack or ignore files without having them deleted in Git? 如何在不跟踪文件的情况下将文件添加到git项目? - How do I add files to a git project without them being tracked? 如何使用 Git LFS 跟踪存储库的任何子目录中的任何(任意)文件 - 但不跟踪其根目录中的任何文件? - How do I use Git LFS to track any (arbitrary) file in any subdirectory of a repository - but without tracking any files in its root? 如何让git跟踪所有以“〜”结尾的文件? - How to keep git from tracking all files that end with a “~”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM