简体   繁体   English

Git合并和未暂存的文件

[英]Git merge and unstaged files

Picture of the situation: you fetch from remote repository and you run a git merge with remote origin having some unstaged files. 情况图片:您从远程存储库中获取数据,并与具有某些未暂存文件的远程源一起运行git merge。

How does git merge behave towards unstaged files? git merge如何处理未暂存的文件?

Assuming you have example.md as an unstaged file in your working directory and try to merge origin/remote1 which already tracks example.md : 假设您在工作目录 中将 example.md作为未暂存的文件,并尝试合并已经跟踪example.md origin/remote1

When trying to merge you will get the following error: 尝试合并时,将出现以下错误:

error: The following untracked working tree files would be overwritten by merge:
    example.md
Please move or remove them before you merge.
Aborting

That happens even if the content of the files is identical. 即使文件的内容相同,也会发生这种情况。


TLDR: git merge prevents you from merging if currently untracked files in your working directory could be overwritten by a merge. TLDR:如果合并可能覆盖工作目录中当前未跟踪的文件,则git merge 阻止您合并。

git will only prevent the merge if local changes would be overridden, if the remote did no changes to files you modified locally the merge will finish without any problems. git仅在覆盖本地更改的情况下才阻止合并,如果远程对本地修改的文件没有更改,则合并将毫无问题地完成。

This is all an aside; 放在一边。 AnimiVulpis' answer is fine. AnimiVulpis的回答很好。 This should be a comment, in other words, but it's much too big to fit as a comment. 换句话说,这应该是评论,但太大而无法作为评论。 :-) :-)


You need to define a bit more carefully what you mean by "unstaged file". 您需要更仔细地定义“未暂存文件”的含义。

In Git, there are three important things to keep in your head at all times: 在Git中,始终需要牢记三件重要的事情:

  • Which commit is the current commit , ie, what is in HEAD right now? 当前提交是哪个提交,即HEAD现在有什么? Usually HEAD contains the name of a branch, and the branch-name itself contains the hash ID of a commit. 通常, HEAD包含分支的名称,而分支名称本身包含提交的哈希ID。 Then that hash ID is the current commit. 然后,该哈希ID是当前提交。

  • What is in the index right now? 现在索引中有什么? The index, also called the staging area or sometimes the cache , contains what will go into the next commit you make. 索引,也称为暂存区或有时称为缓存 ,包含将进入下一次提交的内容。 If you make a new commit right now, whatever is in the index right now becomes the content of that new commit. 如果您现在进行新的提交,则索引中的任何内容现在都将成为该新提交的内容。

  • What is in the work-tree right now? 现在工作树中有什么? The work-tree is the easiest thing to see because it contains all your files, in the normal form your computer has them. 工作树是最容易看到的东西,因为它包含您所有的文件,而计算机以通常的形式包含它们。 All you have to do is look, and there they are. 您所要做的就是看,就在那里。

The index is a little hard to see, because Git mostly shows it to you by comparing it to the current commit and to the work-tree . 索引有点难看,因为Git主要通过将索引与当前提交工作树进行比较来向您显示索引。 But normally, initially, it contains all the same files as the current commit, in the special Git-oriented format that makes Git fast. 但是通常,最初,它以面向Git的特殊格式包含与当前提交相同的所有文件,从而使Git快速。 Once you git add a file, though, the index version of that file gets copied from the work-tree version. 但是,一旦git add了一个文件,该文件的索引版本就会从工作树版本中复制出来。 Now it matches the work-tree file and not the HEAD file. 现在,它与工作树文件而不是HEAD文件匹配。 That's what most documents and people call staging the file: copying it from the work-tree into the index. 这就是大多数文档和人们所说的暂存文件的方式:将其从工作树复制到索引中。

Some files that are in your work-tree may not be in your index and/or your current commit at all. 工作树中的某些文件可能根本不在索引和/或当前提交中。 In some cases, this is what you want: you want the work-tree to hold the compiled code, or the PDF output from a document, or whatever, but you don't want that code to get committed. 在某些情况下,这就是您想要的:您希望工作树保存已编译的代码,或者文档的PDF输出,等等,但是您不希望提交这些代码。

A file that is in your work-tree, but not in your index, is untracked . 在您的工作树中但不在索引中的文件未跟踪 Since it is untracked, it won't be in the next commit. 由于未跟踪,因此不会在下一次提交中。 But git status will complain about it: "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 status会抱怨:“嘿,这个文件没有被跟踪!您忘记了这个文件吗?最好添加这个文件,对吗?嗯?现在就跟踪这个文件,对吗?Pester!Pester!Pester!” To get Git to shut up about this untracked file, you can list it in a .gitignore file. 要让Git关闭该未跟踪的文件,您可以在.gitignore文件中列出它。 Then Git knows that the untracked file is not meant to be complained-about. 然后,Git知道未跟踪的文件不是要抱怨的。 That's most of what .gitignore does. 这就是.gitignore所做的大部分工作。 In particular, if a file is tracked, adding it to .gitignore has no effect at all. 特别是,如果一个文件跟踪,增加它.gitignore具有完全没有效果。 It's only applied to untracked files. 它仅适用于未跟踪的文件。 Once the file is in the index, you are stuck with it: you have to explicitly remove it to take it away. 将文件放入索引后,便会陷入困境:您必须明确删除它才能将其删除

Since an untracked file is not in the index, some people call this "unstaged" as well. 由于未跟踪的文件不在索引中,因此有些人也称其为“未暂存”。 That's why you have to be careful when talking about "unstaged files": some people consider untracked files "unstaged" too. 这就是为什么在谈论“未暂存文件”时必须小心的原因:有些人也将未跟踪文件视为“未暂存文件”。


In any case, git merge itself is a bit complicated. 无论如何, git merge本身有点复杂。 Sometimes it actually merges, and sometimes it does what Git calls a fast-forward , which is not really a merge at all. 有时它实际上是合并的,有时它会执行Git所说的快进 ,这根本不是真正的合并。 When Git does a fast-forward instead of a merge, many more things are allowed in terms of what's different in HEAD , index, and work-tree. 当Git执行快进而不是合并时,就HEAD ,索引和工作树的不同而言,允许做更多的事情。 When Git does a real merge, Git needs to use the index to do it, and fewer special cases are allowed. 当Git进行真正的合并时,Git需要使用索引来进行合并,并且允许较少的特殊情况。

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

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