Mar*_*rra 6 git github repository gitignore
我一直在学习有关 .gitignore 文件的所有内容,但有一个问题我想解决。.gitignore 应包含您要忽略的所有文件。因此,您应该忽略操作系统、您正在使用的 IDE 生成的文件...当存储库位于 Github 上并且人们可以克隆它并推送更改时,我的问题就会出现。这些人可以使用其他操作系统,也可以使用其他IDE。因此,gitignore 应该忽略这些其他操作系统和 IDE 生成的文件。
你该怎么办?是不是要把所有操作系统生成的、所有IDE生成的文件都写到gitignore里呢?
tor*_*rek 11
我想立即强调两个背景点:
\n\n如果您拥有该存储库,则您可以设置规则。你所做的任何迁就他人的行为都只是一般的友善。
动词“忽略”充其量是……很棘手。稍后我将描述我的意思。重要的是列出文件并.gitignore不会完全忽略它,除非您对“忽略”一词有奇怪的个人定义。
也就是说,友好的方法是让您的存储库仅忽略您的项目将生成的文件。然后,让您的个人忽略文件忽略您的系统的文件。
\n\n让我们举一个具体的例子。假设您有一个使用 Python 的项目,其中运行会python foo.py创建foo.pyc、foo.pyo和/或__pycache__/*文件,但这些文件都不应该被提交。因此,您可以从以下开始:
*.pyc\n*.pyo\n__pycache__/\nRun Code Online (Sandbox Code Playgroud)\n\n在你的.gitignore,因为使用你的项目\xe2\x80\x94的任何人,或者你的同事,或者其他任何人\xe2\x80\x94最终都会得到这些Python“目标代码”文件,这些文件特定于特定的Python版本,并且因此不应包括在内。
但假设您个人正在使用 MacOS 及其 Finder。Finder 程序创建的文件名为.DS_Store. 所以你很可能会想添加:
.DS_Store\nRun Code Online (Sandbox Code Playgroud)\n\n给你的.gitignore. 这并没有错,但它对使用 Windows 的人没有任何好处。Windows 用户需要忽略哪些文件?我不确定,我不使用 Windows。然而,Linux 人员可能喜欢忽略.*.swp文件,这些文件vim。
如果您放入.DS_Store自己的$HOME/.gitignore,并且 Linux 人员放入.*.swp他们的 $HOME/.gitignore,那么你们所有人都会对您的项目有一个愉快的体验。此外,您将对他们的项目有一个愉快的体验,他们没有列出该项目.DS_Store,因为他们是在 Linux 上启动的。
这就是一般的想法:您的项目(存储库).gitignore应该列出在使用您的项目时将在工作树中找到的文件的名称或名称模式,但不应将其提交给项目。换句话说,它不是特定于操作系统的,而是特定于项目的。 其他文件名模式\xe2\x80\x94特定于操作系统、特定于编辑器、特定于IDE等\xe2\x80\x94可以放入其他忽略文件中,因此不需要在项目文件中列出.gitignore。将它们列在项目文件中并不一定有坏处,但如果每个人都对事情很明智,那也没有帮助。
人们发现 Git 的.gitignore文件令人困惑。(我确实这么做了,而且从 StackOverflow 上的数百个问题来看,几乎每个人都这么做了。)我认为这很大程度上来自于对 Git 存储模型的误解。
关于 Git\xe2\x80\x94 要了解的第一件事可能是要了解的最重要的事情\xe2\x80\x94 是 Git 不是关于文件的,也不是真正关于分支的。Git 实际上就是关于提交。Git 存储库的核心由两个数据库组成。大数据库保存提交和支持提交所需的其他内部 Git 对象。
\n\n这个包含 Git 提交和其他 Git 对象的大型数据库就是git clone复制的内容。还有第二个较小的名称数据库:分支名称、标签名称等。该数据库对其他 Git 是可见的,因此可以通过 复制它git clone,但通常不仅仅是复制它。相反,git clone读取较小的数据库并对其进行修改,完全丢弃一些名称并更改其他名称。因此,当您使用 时git clone,您将获得大数据库的副本(所有提交)以及小数据库的修改和精简副本。(我们不会在这里太仔细地观察较小的一个,因为它不会影响.gitignore文件。)
提交本身都有唯一的哈希 ID。这些是由字母和数字组成的丑陋的大字符串,例如b994622632154fc3b17fb40a38819ad954a5fb88。Git 存储库可以快速判断它是否与其他 Git 存储库具有相同的提交:发送的 Git 仅列出哈希 ID。接收 Git 只是检查:我是否有使用该哈希 ID 的提交? 如果是这样,接收的 Git 就会有提交。它不需要再次获取它。如果没有,接收的 Git 需要获取该提交。
这意味着您的第一个git clone可能会很慢:您可能必须获取许多兆字节的对象。不过,在那之后,更新克隆只需获取您仍然需要的任何新提交即可。你的 Git 调用他们的 Git,他们列出一些哈希 ID,你的 Git 知道要获取什么,他们的 Git 也知道你拥有什么。或者,如果你已经做出了新的提交给他们,你的 Git 会调用他们的 Git,为他们提供一些哈希 ID,他们可以说我已经有了那个,或者我没有那个,给我!
当然,还有更多的事情要做。接下来要知道的是,每次提交都会存储每个文件的完整快照。这些文件以特殊的、只读的、仅限 Git 的冻结格式存储,其中的文件已进行重复数据删除。事实上,提交存储文件就是 Git 为我们存储文件的方式,它实际上只关心提交本身。冻结和重复数据删除的格式是存储库不会变得非常庞大的原因,即使每次提交都有每个的完整副本:大多数提交只是重复使用前一次提交中的文件,这意味着 Git 不必存储一个新副本。
\n\n但是,如果提交中的文件采用冻结的、仅限 Git 的格式,您计算机上的其他程序都无法使用该格式,那么您将如何实际使用这些文件呢?答案是:你不会。也就是说,您不会使用这些文件。Git 要做的就是将这些文件提取到某个地方。那个“某处”是你的工作树或工作树。
\n\n这里值得一提的是,尽管我们不会进一步讨论,但每次提交不仅存储冻结快照,还存储一些额外的元数据。这主要是您在输出中看到的内容git log:例如,谁进行了提交、何时以及为什么。为什么部分取决于提交的人:它是日志消息。一条好的日志消息非常有价值。Git 可以告诉您发生了什么: Git 会将上一个提交或父提交的快照与当前或子提交的快照进行比较,对于每个不同的文件,Git 都会向您显示一个更改的配方将父副本复制到子副本中。但 Git 无法告诉您为什么添加或删除某些行。只有这样做的人才能说出他们为什么这样做。
如果您运行过:
\n\ngit clone https://github.com/git/git\nRun Code Online (Sandbox Code Playgroud)\n\n并拥有 Git 的副本,您可以查看 Git 的源代码:有 sa Makefile、 aREADME.md等等。但这些是您计算机上的普通文件。它们不是提交 中的文件。它们是 Git 通过从快照中提取已提交文件而制作的副本。 这些副本位于您的工作树或工作树中。您可以使用文件查看器查看它们,在编辑器中打开它们,等等。但它们不在Git中。它们在您的工作树中,供您随心所欲地使用。
每当您要求时,Git 都会将任何给定的提交提取到您的工作树:
\n\ngit checkout v2.21.0\nRun Code Online (Sandbox Code Playgroud)\n\n例如,将使用标签 v2.21.0来查找特定的提交哈希 ID(8104ec994ea3849a968b4667d072fedd1e688642准确地说,是 )并将该提交提取到您的工作树中。(如果您有 2.23 或更高版本的 Git,则可以使用git switch代替git checkout:它们在这里执行完全相同的操作。)此提取过程包括从工作树中删除 文件并根据您的提交创建新文件\正在切换到。但所有这些文件都是你的文件,而不是 Git 的文件。
幸运的是,git checkout/git switch有一些安全检查,以避免在您未保存所做的某些更改时删除您的文件。您可以关闭此功能(git checkout --force例如 )或故意使用其他破坏性命令(git reset --hard)来删除未保存的工作。在所有情况下,你基本上只是告诉 Git 删除你对文件所做的事情,并从Git 的文件中获取其他版本,例如保存在其他提交中的版本。
如果 Git 仅使用两件事\xe2\x80\x94 提交,其中之一是当前提交,以及你的工作树\xe2\x80\x94 那么git commit它本身就会很简单。不幸的是,Git 隐藏了第三个地方来保存每个文件。当您选择某个提交\xe2\x80\x94viagit checkout或git switch\xe2\x80\x94 作为当前提交时,Git 不仅仅将该提交的快照提取到您的工作树中。相反,它首先将该提交的快照提取到 Git 的索引。
索引很复杂并且有多种用途,但它的主要用途实际上很容易描述,并且是您应该记住的开始: 索引是您计划进行的下一次提交的构建位置。 这就是它被称为暂存区的原因。该索引保存每个文件的副本1,最初是从提交中获取的。你的工作树也有一个副本。因此存在三个活动副本:
\n\ngit show HEAD:README.md被冻结到提交中。git show :README.md您可以在 Git 的索引中看到它。它是冻结格式的,但与提交中的格式不同,它是可替换的。(这些文件有点像 Git 中的一半:准备好提交,但尚未实际提交。)README.md。这是你的,它根本不在 Git 中。当您运行时git commit,Git 会收集适当的元数据,然后冻结其索引中的所有文件并将它们用作新提交的新快照。
如果 与:README.md匹配HEAD:README.md,则这两个文件是重复的,因此新提交只是重新使用该文件。如果不是,也许它与其他提交匹配并以这种方式去重复,或者它可能是全新的,并且实际上被真实存储。无论如何,一旦你提交了它,它就会被冻结,并且现在完全在 Git 中。但是如果您更改了 的工作树副本 ,您可能希望 Git 冻结更新的. 这是哪里README.mdREADME.mdgit add切入点。
该git add命令告诉 Git:使索引副本与我的工作树副本匹配。 也就是说,Git 将从README.md工作树中复制(并压缩为冻结格式)更新的文件,并将副本放入:README.md其索引中。因此,这就是为什么您不断需要git add归档的原因:每次您更改副本时,如果您希望 Git 更改其建议的下一个提交副本,您必须git add再次更改。
当您git commit稍后运行时,Git 将获取所有索引文件并将它们冻结到新的提交中。由于索引副本均采用冻结格式,因此此过程通常可以非常快。
1从技术上讲,索引包含的不是数据的实际副本,而是文件的名称、模式和blob 哈希 ID。git ls-files --stage除非您开始使用or直接深入索引,否则您无法真正分辨出差异git update-index。因此,可以将索引视为具有文件的完整副本:Git 很好地隐藏了 blob 对象技巧,因此您无需关心。
.gitignore进来的地方Git 从它的索引而不是你的工作树中进行新的提交。你的工作树是你的,你可以随心所欲地做事。当您告诉 Git 覆盖它时,您只需要小心一点,因为工作树中的所有文件都不在Git 中(它们最多位于 Git 旁边或旁边)。但这也意味着您可以在工作树中创建您不希望 Git 存储到其任何提交中的文件。由于这些文件不在提交中,并且只是由 复制的提交git clone,因此这些文件不会出现在任何克隆中。
*.pyc对于诸如、 或*.o来自cc或 的编译器输出文件c++,或来自 Java 编译器的输出或其他文件,这是一件好事:您通常不希望这些文件出现在任何克隆中。
但是,如果这些文件只是位于您的工作树中,则可能会出现两件事:
\n\ngit status会向你唠叨他们的事。git add everythinggit addgit commit.列出文件名.gitignore是防止这两件事发生的一种方法。但这里有一个技巧:如果文件已经在 Git 的索引中,则将其列在.gitignore没有任何效果。
Git 索引中的文件称为tracked。跟踪文件是当前位于 Git 索引中的文件。未跟踪的文件是存在于您的工作树中,但目前不在 Git 索引中的文件。
\n\n请记住,您现在可以使用 .gitignore 将全新(Git)文件放入 Git 的索引中git add。您现在还可以使用git rm. 所以索引的内容不是固定的。Agit checkout 填充索引,然后您可以\xe2\x80\x94 并\xe2\x80\x94 修改它:您将替换您想要在下一次提交中更新的任何文件。
当您运行时git status,该status命令会进行两次单独的比较。首先,它告诉您其他有用的信息,但我们将直接跳过它并进行两个比较:
两个比较中的第一个将当前提交或HEAD与索引中的内容进行比较。对于每个完全匹配的文件,git status什么也不说。如果有一些文件与xe2\x80\x94不git status匹配或者是新文件或丢失,\xe2\x80\x94会显示更改暂存以供提交并列出这些文件的名称。
第二个比较将索引与工作树进行比较。对于每个完全匹配的文件,git status什么也不说。如果有一些文件不匹配或丢失,git status则会显示更改未暂存以进行提交并列出这些文件的名称。
这里的一个特殊情况是针对未跟踪的文件:对于每个未跟踪的文件,git status列出文件的名称,2调用这些未跟踪的文件。但如果你把这些名字列在 中.gitignore,你就对他们git status 闭嘴。
请注意,跟踪文件不会发生任何特殊情况。这些已经在 Git 的索引中了。它们被第一次比较所覆盖,Git 会将索引副本与工作树副本进行比较,无论文件是否在.gitignore.
所以从这个意义上说,这些.gitignore条目并不意味着忽略该文件。他们的意思是当文件未被追踪时就闭嘴。当它被跟踪时,它们没有任何作用。
同时,git add具有.和(除其他外)用于对许多或所有文件*进行集体添加操作。如果所有文件都包含未跟踪的文件,这些操作将非常不方便。因此,列出文件名或模式会.gitignore抑制批量添加操作。它甚至压制了一种故意的git add:
*.pyc\n*.pyo\n__pycache__/\nRun Code Online (Sandbox Code Playgroud)\n\n所以也许.gitignore应该被称为.git-do-not-complain-about-these-untracked-files-and-do-not-automatically-add-them-when-using-en-masse-add-operations-or-even-explicit-requests,或类似的东西。但谁愿意输入这样的名字呢?确实如此.gitignore。
2从技术上讲,每次您需要git status -uall或git status -u。否则,有时它会合并一堆物理存储在单个文件夹中的文件,并且只需要提及文件夹名称。
| 归档时间: |
|
| 查看次数: |
17352 次 |
| 最近记录: |