Git 合并和未暂存的文件
Git merge and unstaged files
情况图片:您从远程存储库获取数据,然后 运行 与具有一些未暂存文件的远程源合并 git。
git 合并如何处理未暂存的文件?
假设您的 工作目录 中有 example.md
作为 未暂存 文件并尝试合并 origin/remote1
已经跟踪 example.md
:
尝试合并时会出现以下错误:
error: The following untracked working tree files would be overwritten by merge:
example.md
Please move or remove them before you merge.
Aborting
即使文件内容相同也会发生这种情况。
TLDR: git merge
阻止 如果当前 未跟踪文件,则您无法合并在您的工作目录中 可能 被合并覆盖。
git
只会 阻止 如果本地更改了合并 会 被覆盖,如果远程没有更改文件您在本地进行了修改,合并将完成 而不会出现 任何问题。
这些都放在一边; 没问题。换句话说,这应该是一条评论,但它太大了,不适合作为评论。 :-)
您需要更仔细地定义 "unstaged file" 的意思。
在Git中,请时刻牢记三件重要的事情:
哪个提交是当前提交,即现在HEAD
中有什么?通常 HEAD
包含分支名称,而分支名称本身包含提交的哈希 ID。那么该哈希 ID 就是当前提交。
现在 index 中有什么?索引,也称为 暂存区 或有时称为 缓存 ,包含将进入 下一个 的内容承诺你所做的。如果您现在进行新提交,索引中的任何内容都会成为该新提交的内容。
工作树现在有什么?工作树是最容易看到的,因为它包含您的所有文件,以您的计算机拥有它们的正常形式。你只需要看,它们就在那里。
索引有点难看,因为 Git 主要通过将其与 当前提交 和 进行比较来向您显示工作树。但通常情况下,最初,它包含与当前提交相同的所有文件,采用特殊的 Git 导向格式,使 Git 快速。但是,一旦 git add
一个文件,该文件的索引版本就会从工作树版本中复制。现在它匹配工作树文件而不是 HEAD
文件。这就是大多数文档和人们所说的 暂存文件: 将其从工作树复制到索引中。
您的工作树中的某些文件可能根本不在您的索引中 and/or 您当前的提交。在某些情况下,这就是您 想要的: 您希望工作树保存编译后的代码,或文档的 PDF 输出,或其他任何内容,但您不希望这样要提交的代码。
在您的工作树中但不在您的索引中的文件是未跟踪。由于它未被跟踪,因此不会出现在下一次提交中。但是 git status
会抱怨它: "Hey, this file is untracked! Did you forget about this file? Better add this file, right? Huh? Track this file now, right? Pester! Pester! Pester!" 要让 Git 闭嘴这个未跟踪的文件,您可以将它列在 .gitignore
文件中。然后 Git 知道未跟踪的文件不应该被抱怨。这就是 .gitignore
所做的大部分工作。特别是,如果文件 被 跟踪,将其添加到 .gitignore
根本没有任何效果。它仅适用于 未跟踪的 文件。一旦文件在索引中,您就无法摆脱它:您必须显式 删除 才能将其删除。
由于未跟踪的文件不在索引中,因此有些人也称其为 "unstaged"。这就是为什么在谈论 "unstaged files" 时必须小心:有些人也认为未跟踪文件 "unstaged"。
无论如何,git merge
本身就有点复杂。有时它实际上合并,有时它执行 Git 所谓的 快进 ,这根本不是真正的合并。当 Git 执行快进而不是合并时,就 HEAD
、索引和工作树的不同之处而言,允许更多的事情。当Git做真正的合并时,Git需要使用索引来做,允许的特殊情况较少。
情况图片:您从远程存储库获取数据,然后 运行 与具有一些未暂存文件的远程源合并 git。
git 合并如何处理未暂存的文件?
假设您的 工作目录 中有 example.md
作为 未暂存 文件并尝试合并 origin/remote1
已经跟踪 example.md
:
尝试合并时会出现以下错误:
error: The following untracked working tree files would be overwritten by merge:
example.md
Please move or remove them before you merge.
Aborting
即使文件内容相同也会发生这种情况。
TLDR: git merge
阻止 如果当前 未跟踪文件,则您无法合并在您的工作目录中 可能 被合并覆盖。
git
只会 阻止 如果本地更改了合并 会 被覆盖,如果远程没有更改文件您在本地进行了修改,合并将完成 而不会出现 任何问题。
这些都放在一边;
您需要更仔细地定义 "unstaged file" 的意思。
在Git中,请时刻牢记三件重要的事情:
哪个提交是当前提交,即现在
HEAD
中有什么?通常HEAD
包含分支名称,而分支名称本身包含提交的哈希 ID。那么该哈希 ID 就是当前提交。现在 index 中有什么?索引,也称为 暂存区 或有时称为 缓存 ,包含将进入 下一个 的内容承诺你所做的。如果您现在进行新提交,索引中的任何内容都会成为该新提交的内容。
工作树现在有什么?工作树是最容易看到的,因为它包含您的所有文件,以您的计算机拥有它们的正常形式。你只需要看,它们就在那里。
索引有点难看,因为 Git 主要通过将其与 当前提交 和 进行比较来向您显示工作树。但通常情况下,最初,它包含与当前提交相同的所有文件,采用特殊的 Git 导向格式,使 Git 快速。但是,一旦 git add
一个文件,该文件的索引版本就会从工作树版本中复制。现在它匹配工作树文件而不是 HEAD
文件。这就是大多数文档和人们所说的 暂存文件: 将其从工作树复制到索引中。
您的工作树中的某些文件可能根本不在您的索引中 and/or 您当前的提交。在某些情况下,这就是您 想要的: 您希望工作树保存编译后的代码,或文档的 PDF 输出,或其他任何内容,但您不希望这样要提交的代码。
在您的工作树中但不在您的索引中的文件是未跟踪。由于它未被跟踪,因此不会出现在下一次提交中。但是 git status
会抱怨它: "Hey, this file is untracked! Did you forget about this file? Better add this file, right? Huh? Track this file now, right? Pester! Pester! Pester!" 要让 Git 闭嘴这个未跟踪的文件,您可以将它列在 .gitignore
文件中。然后 Git 知道未跟踪的文件不应该被抱怨。这就是 .gitignore
所做的大部分工作。特别是,如果文件 被 跟踪,将其添加到 .gitignore
根本没有任何效果。它仅适用于 未跟踪的 文件。一旦文件在索引中,您就无法摆脱它:您必须显式 删除 才能将其删除。
由于未跟踪的文件不在索引中,因此有些人也称其为 "unstaged"。这就是为什么在谈论 "unstaged files" 时必须小心:有些人也认为未跟踪文件 "unstaged"。
无论如何,git merge
本身就有点复杂。有时它实际上合并,有时它执行 Git 所谓的 快进 ,这根本不是真正的合并。当 Git 执行快进而不是合并时,就 HEAD
、索引和工作树的不同之处而言,允许更多的事情。当Git做真正的合并时,Git需要使用索引来做,允许的特殊情况较少。