Git checkout不会改变任何东西。

68

我非常喜欢git,至少我喜欢git的理念。能够将我的主项目作为独立的分支检出,在其中更改任何内容而不会破坏其他项目的风险是非常棒的。但它现在并没有发挥作用。

基本上,我的工作流程如下:

  1. 将稳定版本检出到一个新分支以尝试新的代码
  2. 进行一些更改-我不想保留这些更改,只是进行实验。
  3. 查看我所做的所有更改
  4. 添加所有要跟踪的更改
  5. 提交分支并将分支推送到origin(如果成功,否则跳过此步骤)
  6. 决定尝试另一种方法,返回到主分支
  7. 观察到实验性分支中的工件,即使我在主分支中也是如此。

每次将一个分支检出到另一个分支时,在一个分支上进行更改,然后检出原始分支时,我仍然拥有所有在另一个分支中发生的文件和更改。这让我非常沮丧。我读到过当您在IDE中打开文件时会发生这种情况,但我很小心并且在切换分支之前关闭了IDE中的文件,关闭了IDE并且关闭了我的rails服务器,但这仍然会发生。此外,运行“git clean -f”要么删除某个任意提交后发生的所有内容(而且是随机的),要么像最新情况一样,没有将任何内容更改回其原始状态。

我以为我正在正确地使用git,但现在我已经束手无策了。我正在尝试使用稳定版本的项目来处理一堆实验性代码,但我不断地必须手动跟踪和修复我所做的所有更改。有任何想法或建议吗?

git checkout -b photo_tagging
git branch # to make sure it's right
# make a bunch of changes, creations, etc
git status # see what's changed since before
git add . # approve of the changes, I guess, since if I do git commit after this, it says no changes
git commit -m 'these are changes I made'

git checkout master
git branch #=> *master

# look at files, tags_controller is still there, added in photo_tagging
# and code added in photo_tagging branch are still there in *master

无论我在分支上是否进行提交,这似乎都会发生。


1
你能给一个更具体的例子吗?比如你输入的一系列命令:git clone x; echo "foo" >> y; git clone x; grep y foo. - Nick Orton
你在其中提交或存储了你的更改吗?没有更多的细节,这不是一个问题,而是一种抱怨。 - Brad Mace
我刚刚添加了我一直在使用的命令列表。也许我做错了什么。 - Josh Kovach
这种情况也发生在我身上,答案让人非常沮丧,因为我做得没错,有时它能正常工作,有时却不能。我决定放弃一个相当大的代码块,该代码块是在一个单独的分支上创建的,结果发现所有的代码仍然停留在我的主分支上,就好像我从未首次检出过一样。 - Nathaniel Hoyt
6个回答

36

我曾经在从主分支切换到另一个临时分支时遇到过这个问题,如果我在那个临时分支上更改了内容但没有提交更改,然后再次切换到主分支,它实际上会将TEMP分支中的所有更改合并到MASTER中。

回答:

每当你切换到TEMP分支时,请先提交你所做的更改。这样,如果你在TEMP分支上提交更改并再次切换到MASTER分支,它就会按照预期的方式工作。


5
有人知道这是为什么吗?如果只完成了一半的工作就被迫提交以切换分支,这似乎有些可惜...并不是我害怕承诺。 - Chortle
5
你可以使用 git stash 替代。不需要进行提交。 - shabany
1
@Chortle 只需使用 git stash pop,它将在该分支上恢复您的更改。但是,如果您希望这些更改存在于另一个分支中,则必须提交更改并合并分支。 - shabany
1
这绝对是答案!提交确实适用于临时分支。 - impression7vx
1
这个提交的解决方案可行,并且它也训练了我的语法技能。 - Hang Chen
显示剩余2条评论

20

这里有一个使用git和分支的示例。

$ git branch
* master
  organize

$ git branch networking
$ git checkout networking

$ git branch
  master
* networking
  organize

自从有人停止网络开发以来,Master已经多次更新。

$ git pull origin networking
From github.com:dlundquist/Asteroids
 * branch            networking -> FETCH_HEAD
CONFLICT (rename/delete): Rename src/ServerClientThread.java->src/ServerConnectionThread.java in 92d5b7c4e7c4110803eabf5d5152e7f2a337d722 and deleted in HEAD
Auto-merging src/Actor.java
Auto-merging src/Asteroids.java
CONFLICT (content): Merge conflict in src/Asteroids.java
Auto-merging src/BasicWeapon.java
CONFLICT (content): Merge conflict in src/BasicWeapon.java
CONFLICT (delete/modify): src/DedicatedServer.java deleted in HEAD and modified in 92d5b7c4e7c4110803eabf5d5152e7f2a337d722. Version 92d5b7c4e7c4110803eabf5d5152e7f2a337d722 of src/DedicatedServer.java left in tree.
Auto-merging src/MainMenu.java
CONFLICT (content): Merge conflict in src/MainMenu.java
CONFLICT (delete/modify): src/NetworkClientThread.java deleted in HEAD and modified in 92d5b7c4e7c4110803eabf5d5152e7f2a337d722. Version 92d5b7c4e7c4110803eabf5d5152e7f2a337d722 of src/NetworkClientThread.java left in tree.
CONFLICT (delete/modify): src/NetworkUpdate.java deleted in HEAD and modified in 92d5b7c4e7c4110803eabf5d5152e7f2a337d722. Version 92d5b7c4e7c4110803eabf5d5152e7f2a337d722 of src/NetworkUpdate.java left in tree.
Auto-merging src/ScenePanel.java
CONFLICT (content): Merge conflict in src/ScenePanel.java
Auto-merging src/Shield.java
CONFLICT (content): Merge conflict in src/Shield.java
Auto-merging src/Sprite.java
Auto-merging src/TripleShotWeapon.java
Auto-merging src/Weapon.java
Automatic merge failed; fix conflicts and then commit the result.
mjolnir:Asteroids Durandal$ git status
# On branch networking
# Changes to be committed:
#
#   modified:   src/Actor.java
#   modified:   src/Sprite.java
#   modified:   src/TripleShotWeapon.java
#   modified:   src/Weapon.java
#
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      src/Asteroids.java
#   both modified:      src/BasicWeapon.java
#   deleted by us:      src/DedicatedServer.java
#   both modified:      src/MainMenu.java
#   deleted by us:      src/NetworkClientThread.java
#   deleted by us:      src/NetworkUpdate.java
#   both modified:      src/ScenePanel.java
#   added by them:      src/ServerConnectionThread.java
#   both modified:      src/Shield.java

哇,git真的很生气。看起来Master版本已经超前于Networking分支了,所以git不能为我完成所有的工作。

$ git reset --hard networking
HEAD is now at 20d6ee8 done tweaking game on the main branch.  Fixed a few bugs with the TripleShotWeapon.  Rebalanced the gameMechanics() in Asteroids to increase the difficulty as the levels increase.
mjolnir:Asteroids Durandal$ git status
# On branch networking
nothing to commit (working directory clean)

现在,我回到了上次将网络推到远程时的状态。但在进行任何工作之前,我真的应该回去并与主分支合并。否则,合并会更加困难。

合并文件所花费的时间

$ git add (insert conflict resolved files here)
$ git commit -a -m "Merged networking with master"
$ git checkout master
$ git branch
* master
  networking
  organize

现在让我们应用我们所做的更改。

$ git merge networking
Already up-to-date.

如果你喜欢“Yeah!”的话,你可能想这样做。

$ git merge origin networking
Already up-to-date. Yeeah!

将我们的更改推送到世界上

$ git push origin master

8
这很有用,但实际上并不是正在发生的问题。我是唯一在这个项目上工作的人,所以没有需要解决的冲突。我认为问题在于当(我认为)切换到另一个分支时,应该替换或隐藏在其他分支中进行的任何更改,但是从 networking 切换到 master (非合并)仍然显示了在 networking 中发生的所有事情。 - Josh Kovach
6
我怀疑你的错误在于使用了 "git add ."。我通常使用 "git add *" 来添加目录中的所有内容,而不是仅添加目录本身。请注意不要改变原意。 - EnabrenTane
7
了解,Enabren。就是这样了。当我开始使用Git时,我使用的是 'git add *',但在尝试学习它时,我在某个地方读到要使用 'git add .'。我刚刚做了几个实验,发现 'git add .' 正好是问题的源头。非常感谢你。头疼已经消失了。 - Josh Kovach
如果这个解决了你的问题或回答了你的疑问。@Mitch Wheat指出你应该标记为已解决并点赞。这将会吸引更多的人在未来帮助你。 - EnabrenTane
4
我在我的分支中使用 git add <file>,遇到了你所遇到的相同问题。我真的不喜欢 add *,因为我很少想将所有更改的文件都添加到提交中。你的意思是说,我不应该使用这种工作流程将单个文件添加到暂存区吗? - chwi
如果 git add * 是答案而不是所需的内容,那么请创建一个新答案或更新现有答案,以使答案中包含所需内容,而不是注释。 - goryh

5
我喜欢用通俗易懂的语言解释git。答案是因为有一种假设,认为改变分支(checkout)就可以进入另一个“工作区”。Git并不会这样做(尽管这样感觉更自然,很多人都有这种误解)。
相反,分支就像标签一样。所以你可以在分支之间跳来跳去,做些工作,修改一下,再跳回去,然后提交。那么提交就会在你最后到达的分支上!checkout只是改变你将要使用的“标签”/分支,仅此而已。
更新:根据Martas的评论
这适用于您的分支和主分支同步(关于被跟踪的文件),或者有未被跟踪的文件。如果实际上它们处于不同的状态,当您checkout时文件和文件夹实际上会消失并重新出现。如果您有被跟踪但未提交的更改,则git实际上会中止检出,您必须提交或保存它们。

你描述了我观察到的真实行为,但我仍然不确定并且犹豫不决它是正确的行为还是错误。我真的期望改变分支将获取工作树中所有未提交的文件更改,在某个地方整理它们,并放置先前制作的新分支中的未提交更改。当切换回分支时也是同样如此,没有任何提交。 - Marťas
1
@Martas,你说得没错。我的回答适用于当你的分支和主分支同步(关于被跟踪的文件),或者有未被跟踪的文件。如果实际上它们处于不同的状态,那么当你切换时,文件和文件夹将会消失并重新出现。如果你有已被跟踪但未提交的更改,那么git将会中止检出,你必须要么提交它们,要么将它们存储起来。 - Bernardo Dal Corno

2
请检查您是否具有写入权限。只读访问存储库会导致此错误。

谢谢!奇怪的错误,但在分叉和克隆该存储库后正常工作。 - Just Mohit

0
简而言之:提交您的更改(确保您已经检出了正确的“实验性”分支),即使您不想保留它,稍后也可以删除该分支。然后检出您想要的分支(在进行更改之前),您的IDE现在将显示/更新到您刚刚检出的分支中文件的状态。

0
$ git branch
* master
$ git checkout -b develop
$ git branch
  master
* branch

现在您可以更改任何内容并执行 git add . 命令。

$ git add .   <--Here is the source of the problem, always git add . at your branch to see the observable difference between two branches.
$ git commit -m "Some messages"

$ git checkout master
$ git branch
*master
develop

一切都整洁干净。


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