gitignore会阻止git提取文件吗? [英] Does a gitignore prevent git from pulling files?

查看:120
本文介绍了gitignore会阻止git提取文件吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


gitignore - 指定有意未被跟踪的文件忽略 - git



有时候会有文件不希望Git检入GitHub。有几种方法可以告诉Git忽略哪些文件。 - github


如果文件未被跟踪并被添加到gitignore文件中,如果我提交了存储库,它们将不会被推送到服务器。

如果我在github上的存储库中有文件,并且它们被添加到.gitignore中,会发生什么情况。如果他们克隆存储库,人们会收到这些文件吗?


  1. 我想提供一个默认的凭证文件,但是如果被所述人改变了,不会被推回。

  2. 我想在存储库中提供一个doc文件夹,如果克隆的话不应该导入到eclipse中。

git是否能够处理这两种情况,以及如何正确设置?

解决方案

答案是不,或者可能,甚至是是的,但可能不是您想要的方式。更具体地说,如果有的话, .gitignore 只会间接起作用。原因是你只能忽略未跟踪的文件。还有一种方法,告诉Git应该将跟踪文件 视为未改变。此替代方法根本不使用 .gitignore 。 (我也不特别推荐它。



很多关于 .gitignore 的描述都很模糊,很难理解 .gitignore 是Git的索引,它也被称为暂存区缓存。但在开始之前,我们需要一个甚至更基本的项目。

基础知识:提交,索引和工作树



请记住,首先Git存储的是操作单元 - 它是 commit 。一个提交包含一个文件树的单个快照,以及元数据(谁做了提交和何时;他们对提交的描述;以及一些关键的 parent 提交信息)。把Git当作存储文件,这并不完全错误,但事实上,Git存储了提交,并且它是提交文件的提交。一个Git仓库通常意味着用commit来做某件事。请注意,所有现有的提交都是只读的:不能更改任何提交的任何内容。 (可以添加 new 提交。)



提交或Git中的文件通常包括存储在索引中的文件 - 以特殊的,压缩的,仅Git形式存储。这些文件对你计算机上几乎所有的东西(包括你自己)都是没用的,所以Git必须将它们解压缩到一个工作树中。这是你可以看到,编辑,用作证书等等的这些工作树副本。



当某人克隆存储库时,他们首先获得提交 - 通常是<他们全部。他们还没有索引,他们还没有工作树。因此,作为 git clone 的最后一步,Git运行 git checkout 来创建 索引和工作树 这个 git checkout 步骤选择一个特定的提交,通常是由a分支名称,如 master 。该提交存储快照 - 一组文件 - 现在Git将这些文件从提交复制到索引,然后从索引复制到工作树中。



然后,当你第一次克隆一个版本库或者使用 git checkout 来干净地切换到一个新的提交时,你会得到的是一个索引,它包含所有相同的文件当前的提交以及一个完整的索引中所有相同文件的工作树。该索引的存在是因为该提交是只读的,并且存在与索引分开的工作树,因为索引将文件以其特殊的,仅限内部的Gitty格式存储。



要创建一个新的提交,您首先要处理工作树中的文件,然后在部分或全部这些文件上运行 git add 。什么 git add 是将文件复制回索引(将它们转换为特殊的Gitty格式)。最终,您将运行 git commit ,并且它会立即使用索引中的所有内容,然后使用它为新提交创建快照。






1 请注意索引和工作树是成对的。如果您使用 git worktree add 为存储库创建第二个工作树,则会创建一个新的索引以与新的工作树一起使用。由于历史原因,底层实现有点奇怪,但这些应该总是被视为一种配对。






定义索引



然后,索引可以描述为下一次提交进行的操作 。最初,它拥有当前提交中的每个文件,并且它也用于填充工作树。随着时间的推移,您可以更改存储的数据,甚至可以更改一组文件,并从修改后的索引创建新的提交。所以,在任何时候,索引都有一堆文件。包含路径 P 的某个文件的索引副本通常会与其他两个副本中的至少一个相匹配:当前提交中的 P 副本,或者

在工作树中。



正如我们上面看到的,初始状态是每个文件工作树在索引和当前提交中都有一个副本。所有三个副本相匹配。你可以阅读所有你想要的东西,但是如果你在工作树中改变它们,你会进入一个有趣的情况: Git现在希望你 git add 它们,将更新后的版本复制回索引,以便在下一次提交时进行更新。

工作树文件追踪未追踪



您可以自行创建个文件工作树,没有索引条目。这样的文件称为未跟踪文件。未跟踪文件的定义是不在索引中的任何文件。而且,如果它不在索引中,它也不会在下一次提交中。



请注意,索引中的内容可能会随时间而改变。你现在可以有一个在索引中的文件,然后使用 git rm git rm --cached 从索引中删除文件。现在它不再处于索引中,并且不会处于下一个提交中。但通常这些也会删除工作树副本。



您可能需要未跟踪的文件。如果您在工作树中创建文件没有相应的索引和提交条目,这是一个未跟踪文件。 (因此,索引和工作树中的 是一个跟踪文件。)但是,未跟踪文件存在一个烦恼:Git一直在抱怨他们。



这是 .gitignore 文件的来源。 A .gitignore 文件列出了特定的路径名​​称或名称模式。在Git声明一个未被跟踪的文件之前,Git检查适用于该路径的 .gitignore 文件。如果路径被列出,Git只会关闭。 这仅影响未跟踪的文件。 如果文件被跟踪 - 我们指的是文件名称是否在索引中 - 那么 .gitignore code>根本不适用。



替代方案是 git update-index --skip-worktree



请注意,要忽略的文件的前提条件是它也必须未被跟踪。如果它没有被跟踪,那么根据定义,它不是你所做的任何新的提交。对于 作为未跟踪的,它不能位于你用 git checkout 检出的提交所产生的索引中。所以它可能不在任何有趣的提交中。 (例如,它可能在提交历史记录中提交的内容比较单调乏味,但是只要您检查其中的一个,就会跟踪文件,并且当您切换回最近的提交时,Git 将删除<因此,最好避免这种情况。)



你可以在索引中有一个文件(因此可以跟踪),但告诉Git否无论工作树版本发生了什么,Git都应该假装没有发生任何事情,并继续使用索引版本。你可以使用 --skip-worktree 选项来执行 git update-index 。 (另请参阅 Git - '假定 - 无变化'和'skip-worktree'之间的区别)。



查看或者没有好的答案



如果文件不在提交中,当你签出这个提交时,它不会在索引中。如果您将该提交签出为 git clone 的最后一步,那么您只需创建一个新的索引和工作树对,根本没有任何未跟踪的文件。您所需的凭证文件只是不存在。您必须至少运行一条命令才能创建它。 (它可以预先列在 .gitignore 文件中。)



如果文件 / em>在提交时,它将位于索引和工作树中,随时可以使用。但是不会在索引中标记为跳过,以便如果有人触及它,Git会告诉他们提交它。将它添加到 .gitignore 不会帮助,因为该文件是跟踪的。您必须运行至少一条命令才能跳过它。

无论采用哪种方式,至少需要一个 git clone code>。我相信更好的方法是提供已提交的模板文件,并让一个命令将这些模板复制到未跟踪的,预先忽略的工作树文件中,但 - skip-worktree 变种也可以。


There are several descriptions for what a gitignore file achieves:

gitignore - Specifies intentionally untracked files to ignore - git

From time to time, there are files you don't want Git to check in to GitHub. There are a few ways to tell Git which files to ignore. - github

If files are untracked and are added to a gitignore file they will not be pushed to the server if I commit my repository.

What happens if I have files in the repository on github and they are added in the .gitignore. Will people receive those files if they clone the repository?

  1. I would like to provide a default credentials file which shall be cloned into peoples repository but not pushed back if altered by said people.

  2. I would like to provide a doc folder in the repository which should not be imported into eclipse if cloned.

Is git able to handle these two situations, and how would this be correctly set up?

解决方案

The answer is "no", or "maybe", or even "yes, but probably not the way you're thinking". More specifically, .gitignore is only going to help indirectly, if at all. The reason is that you can only ignore untracked files. There is an alternative, which is to tell Git that tracked files should be treated as unchanged. This alternative does not use .gitignore at all. (I also don't particularly recommend it.

Many of these descriptions about .gitignore are vague and difficult to interpret because they don't start with the correct foundation. The proper foundation for understanding .gitignore is Git's index, which is also called the staging area and the cache. But before we get to this, we need one even-more-basic item.

Basics: commits, the index, and the work-tree

Remember first that what Git stores—the unit of operation, as it were—is the commit. A commit holds a single snapshot of a file tree, along with metadata (who made the commit and when; their description of the commit; and some crucial parent commit information). People like to think of Git as storing files, and that's not completely wrong, but in fact, Git is storing commits, and it's the commits that have the files. Doing something with a Git repository generally means doing something with a commit. Note that all existing commits are read-only: you cannot change anything about any commit. (You can instead add new commits.)

The files in a commit, or in Git in general—this includes files stored in the index—are stored in a special, compressed, Git-only form. These files are useless to almost everything else on your computer (including yourself) so Git has to extract them into a work-tree. It's these work-tree copies that you can see, edit, use as credentials, and so on.

When someone clones a repository, they first get the commits—usually all of them. They don't yet have an index and they don't yet have a work-tree. So, as the last step of git clone, Git runs git checkout to create the index and the work-tree.1 This git checkout step selects one particular commit, typically the commit named by a branch name like master. That commit stores a snapshot—a set of files—and Git now copies those files from the commit into the index, and then from the index into the work-tree.

What you have, then, when you first clone a repository, or use git checkout to switch cleanly to a new commit, is an index full of all the same files as are in the current commit, and a work-tree full of all the same files as are in the index. The index exists because the commit is read-only, and the work-tree exists, separately from the index, because the index stores the files in their special, internal-only, Gitty format.

To create a new commit, you first work on the files in the work-tree, then run git add on some or all of these files. What git add does is copy the files back into the index (converting them to the special Gitty format). Eventually you will run git commit, and that takes whatever is in the index right then and uses that to make the snapshot for the new commit.


1Note that the index and the work-tree come as a pair. If you use git worktree add to create a second work-tree for a repository, that creates a new index to go with the new work-tree. The underlying implementation is a bit odd for historical reasons, but these should always be treated as a sort of mated pair.


Defining the index

The index, then, can be described as what will go into the next commit you make. Initially, it has every file that's also in the current commit, and it gets used to populate the work-tree as well. Over time, you change the stored data, and maybe even the set of files, and make new commits from the modified index. So, at any given time, the index has a bunch of files in it. The index copy of some file with path P will usually match at least one of two other copies of the files: the copy of P in the current commit, or the copy of P in the work-tree.

The initial state, as we saw above, is that every file in the work-tree has a copy in the index and in the current commit. All three copies match. You can read them all you want, but if you change them in the work-tree, you get into an interesting situation: Git now "wants you" to git add them, to copy the updated versions back into the index so that they will be updated in the next commit you make.

Work-tree files are either tracked or untracked

You can, on your own, create new files in the work-tree, that have no index entry. Such a file is called an untracked file. The definition of an untracked file is any file that is not in the index. And, if it's not in the index, it won't be in the next commit either.

Note that what's in the index can change over time. You could have a file that is in the index right now, and then use git rm or git rm --cached to remove the file from the index. Now it's no longer in the index, and won't be in the next commit. But in general these also remove the work-tree copies.

You probably want untracked files. If you create a file in the work-tree that has no corresponding index and commit entry, this is an untracked file. (Hence a file that is in the index and work-tree is a tracked file.) But there's an annoyance with untracked files: Git keeps whining about them.

This is where .gitignore files come in. A .gitignore file lists particular path names or name patterns. Before Git whines about a file being untracked, Git checks the .gitignore files that apply to that path. If the path is listed, Git simply shuts up. This affects only untracked files. If a file is tracked—by which we mean if the file's name is in the index—then .gitignore does not apply at all.

The alternative is git update-index --skip-worktree

Note that the pre-condition for a file to be ignored is that it must also be untracked. If it is untracked, it is, by definition, not in any new commits you make. For it to start out as untracked, it must not be in the index made from the commit you check out with git checkout. So it's probably not in any interesting commits. (It may be in dull, boring commits deep in the commit history, for instance, but as soon as you check one of those out, the file is tracked, and when you switch back to a recent commit, Git removes the file. So it's best to avoid this entirely.)

You can, instead, have a file in the index (hence tracked) but tell Git that no matter what happens to the work-tree version, Git should pretend that nothing happened, and keep using the index version. You do this with git update-index, using the --skip-worktree option. (See also Git - Difference Between 'assume-unchanged' and 'skip-worktree'.)

Review, or, there's no good answer

If a file isn't in a commit, it won't be in the index when you check out that commit. If you checked out that commit as the last step of git clone, you just made a new index-and-work-tree pair, so you don't have any untracked files at all. The credentials file you want is simply not there. You must run at least one command to create it. (It can be pre-listed in the .gitignore file.)

If the file is in a commit, it will be in the index and work-tree, ready to use. But it won't be marked "skip" in the index, so that if someone touches it, Git will tell them to commit it. Adding it to .gitignore won't help because the file is tracked. You must run at least one command to make it skipped.

Either way, you need at least one command beyond git clone. I believe the better approach is to have template files that are committed, and to have the one command copy those templates to untracked, pre-ignored work-tree files, but the --skip-worktree variant also works.

这篇关于gitignore会阻止git提取文件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆