在git分支中修改的文件溢出到另一个分支

64

我正在处理一个包含主分支和另一个主题分支的git代码库。我已经切换到主题分支并修改了一个文件。现在,如果我切换回主分支,同一个文件会显示为已修改。

例如:

在git-build分支中运行git status命令:

# On branch git-build
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   cvsup_current
#

切换到主分支

[root@redbull builder_scripts (git-build)]# git co master
M       builder_scripts/cvsup_current
Switched to branch "master"

在主分支中的 git status 命令

[root@redbull builder_scripts (master)]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   cvsup_current
#

为什么文件在主分支中显示已修改,即使它是在git-build分支中修改的?
我理解分支彼此独立,当我从一个分支切换到另一个分支时,更改不会从一个分支“溢出”到另一个分支。所以我显然在这里有所错漏。
有人有什么线索吗?

不要以“root”身份开发代码。拥抱“sudo”。 - mirekphd
6个回答

71

为什么在主分支中显示该文件已修改,即使它是在git-build分支中被修改的?

记住的关键是该文件并没有在git-build分支中被修改。它只是在你的工作副本中被修改。

只有在提交更改后,才会将更改放回到你所检出的任何分支中。


谢谢,这些答案的结合让我对此有了更清晰的理解! - Rajkumar S
我刚刚意识到,从SVN的思维模式来看,在分支中提交实际上并没有将其提交到您的“SVN”服务器,而是更像是“保存我的更改到此分支”。我仍在努力适应。 - user76071
4
“它只在你的工作副本中被修改了” <-- 不对,它也在索引中被修改了,即该更改已被提交。 - Mark Longair
但是 Git 是如何做到这一点的呢?如果我在一个分支上修改了一个文件,然后切换到另一个分支,那个文件已经被更改了,也就是说这些文件不再共享相同的基础了,会发生什么?这与变基有什么不同?如果我修改了一些文件,Git 不允许我变基,直到我提交了这些更改。 - Milad
我在Windows上使用Git时遇到了这个污染问题。在切换到另一个分支后,已提交更改的文件仍然留在文件系统中。 - StingyJack

44

如果你想在离开当前分支去做其它工作之前,临时保存当前分支的修改,可以使用 git stash 命令。它是使用 git 的一个小而实用的功能。以下是一个示例工作流程:

git stash #work saved
git checkout master
#edit files
git commit
git checkout git-build
git stash apply #restore earlier work

git stash命令会创建一个变更集栈,让你可以安全地存储多个检查点。你还可以为这些检查点指定名称/描述。完整的使用信息在这里


1
尽管这并没有直接回答为什么的部分,但这个答案最符合OP试图做的意图。这正是我在寻找的。 - Carl Pritchett
1
git stash 不会保护新文件。它只会储存已经被追踪的文件。所以,如果有人创建了新文件,即使进行了储存,这些新文件仍然会在其他文件夹中可用。 - raghu

15

这是git的默认行为。

如果您愿意,您可以使用-f标志来进行“干净的检出”操作。


16
请注意,这不会保留您所离开的分支上的更改或其他任何内容。这将丢弃未提交的更改(除非文件未被跟踪)。 - webmat
12
很少有情况需要使用 git checkout -f,因为它会立即、不可撤销地丢弃所有未提交的更改,而且不会提示。Git 选择以这种方式工作是有原因的,建议阅读 Gareth 在下面的评论。 - Peter Burns

10

只有在你添加并提交修改后,修改的文件才会被放入代码库中。如果你切换回自己的分支并提交了该文件,则它不会出现在主分支上。


3
  • 与git分支不仅相互依赖,也没有完整的代码库为每个分支单独保存。
  • 对于每个提交,Git存储包含指向更改的指针的对象。因此,每个分支都指向其自己的最新提交,HEAD指向当前所在的分支。
  • 当你切换分支时,HEAD指针指向该分支的特定提交。因此,如果有修改过的文件,默认行为是复制它们。

您可以采取以下措施来解决此问题。

  1. 使用 -f 选项忽略更改。

如果您想保存更改:

  1. 在同一分支中本地提交更改,然后切换分支。
  2. 使用 git stash,切换分支,完成工作后切换回原始分支并执行 git stash apply

1
在我的经验中,这个“溢出”问题是由于git没有保护“未跟踪”的文件免受git checkout的影响(只有被跟踪但未提交的文件才会受到保护,即在允许切换到另一个分支之前,用户必须将它们git commit)。
如果您切换回创建这些文件的原始分支(并将其“取消跟踪”),则这些文件将再次变为“未跟踪”,可以git addgit rm
对我来说,这看起来像是一个错误:即使“未跟踪”的文件也应该受到git checkout的保护。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接