为什么一个分支的更改在另一个分支中可见?

33

我执行以下命令序列:

git init rep
cd rep/
echo '111' > 1.txt
git add 1.txt 
git commit -m '1'
git checkout -b dev
echo '222' > 1.txt 
git checkout master
more 1.txt 

由于这些命令,我看到了以下结果

222

我不明白为什么。你可以看到我创建并进入了“dev”分支。我在那里做了一些更改,但我没有添加或提交它们。为什么在从“dev”回到“master”后,我可以看到我在“dev”中所做的更改呢?难道它们不应该留在“dev”中,直到我将它们添加、提交并合并回到“master”中吗?


1
更改已在工作树中进行。git add将更改提交到索引中。git commit将索引中所有跟踪文件的快照作为提交。分支是指向提交的引用。在您的情况下,更改仍然在工作树中。分支还不知道它们。 - ElpieKay
Roman,请将其中一个答案标记为被接受的答案。它们中有多个很好的答案。 - Natan
我觉得这个问题值得获得数百个赞。 - eric
7个回答

34

所有未跟踪的文件在你在不同分支之间移动时不会受到影响。因为它们属于你的文件系统,GIT 不知道这些文件属于哪个分支。所以当你提交这些文件时,GIT 知道哪些文件属于哪个分支。并且可以根据你的分支在工作区中添加或删除文件。


1
很容易忽略这一点 - 这是简单但非常重要的一点。谢谢! - Alexey Shevelyov
1
但是 Git 不应该警告您将要用主分支中的文件覆盖现有文件吗? - Wakan Tanka
是的,但是当在一个分支下创建文件时,它知道该分支的编号吗? - herve

17

这是因为您没有将更改提交到dev分支,因此未提交的更改尚未与父提交关联。

git checkout dev
git add .
git commit -m "changed 1.txt"

如果您想撤消更改,请执行以下操作

git reset --hard master

编辑

开发分支和主分支指向相同的提交哈希值。请查看文件夹 .git/refs/heads 中的内容,这是分支存储在单独文件中的位置。该文件的内容是特定分支所指向的提交哈希值。因此,分支只是指向提交的指针。

在您的情况下,当您检出主分支或开发分支时,它们都指向相同的提交,因此该操作不会更改工作树。否则,您将收到错误提示。现在尝试更改dev分支上的某些内容,然后执行git checkout master,您应该会收到一个错误提示。


3
您的指示很有效。现在两个分支有不同版本的文件,而在“dev”分支中进行的更改在主分支中是不可见的(正如我所希望和预期的那样)。但是,我仍然不明白为什么我在“dev”分支中所做的更改会迁移到“master”上。难道未提交的更改不应该消失或留在原始分支中吗? - Roman
@Roman 我已经编辑了问题来回答你的问题。 - smerlung

11
作为其他人所指导的,要么提交您的更改,要么将它们藏起来。一个简单的解决方案是在检出之前将您的更改藏起来(即临时保存)。例如:
git checkout -b dev
echo '222' > 1.txt 
git stash
git checkout master
# on return to dev, restore changes via following
git stash pop

现在您正在查看旧版文档。


4
git checkout -b dev
echo '222' > 1.txt 
git checkout master

在上文中,您对文件1.txt所做的更改并未属于任何分支,因为它们尚未被提交(甚至还未被添加到索引中)。
Git分支只是指向提交的指针。当您将分支从dev更改为master时,实际上并没有更改当前已检出的提交。这就是为什么Git不需要更新索引或工作目录中1.txt的内容。

1
  1. git checkout branch2,在你进行修改的分支中。

  2. git add .

  3. git commit -m "message"

  4. git push -u origin branch2

检查本地仓库,你会发现修改只出现在 branch2 分支中,而不是主分支。你的主分支将保持不变。


0

我也遇到了同样的问题,甚至已经提交了更改但没有反映出来,然后我尝试运行了这个命令:

git status

我收到了一条消息,指示没有要提交的内容,即使我对文件进行了一些更改,也是如此:尝试保存您的文件,然后再提交。


0

我也遇到了同样的问题,但是添加和提交文件并没有帮助。后来我发现,在使用checkout -b本地创建分支之后,我还必须将该分支推送到远程:

git push origin [name_of_your_new_branch]

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