为什么git需要stash save-pop来切换分支?

时间:2012-11-01 08:39:12

标签: git git-branch git-stash

有时当工作目录发生本地更改时,切换分支失败,但以下流程有效:

  • 存储保存
  • 切换分支
  • Stash pop

为什么? git不知道如何将本地工作目录更改应用于目标分支吗?什么设计选择使这个程序成为必要?是否有一个标志我可以用来避免这个稍长的程序?

更新
假设我想在切换分支时将本地更改保持为本地更改。有时这是一个实际的场景......

3 个答案:

答案 0 :(得分:4)

当前分支很脏并且您尝试切换分支时有两种情况:

  1. 您忘了提交更改。

    在这种情况下,git会警告您切换到另一个分支 导致您丢失更改。这基本上是默认值 假设这就是为什么错误信息是按原样编写的。

  2. 您的更改是暂时的,无论如何都要切换。

    在这种情况下,您需要存储更改,然后再将其应用 交换。 Git从不认为这是你想要的。如果我不得不猜 为什么这可能是因为Linus经常不这样做。

  3. 由于git无法读懂你的想法,它会等你告诉它要么提交还是藏匿。虽然通过错误消息我会说如果git试图读取你的想法,它会猜测你想要提交而不是藏匿 - 但在你的情况下这将是一个错误的猜测。


    其他答案

    很抱歉回复之间的延迟很长,但我今天才注意到你的更新问题。

    对于本地更改,我的策略是创建一个本地更改分支。然后从中而不是master分叉所有功能分支。这是有效的,因为本地更改通常适用于所有工作分支。

    但这样做会让主人的变基有点单调乏味,因为你基本上需要两次变基 - 一次到local_changes然后从local_changes到你的主题分支。但是你可以轻松地为此编写一个shell脚本:

    # rebase_master.sh
    git rebase master local_changes
    git rebase local_changes
    

    这样做的另一个好处是,如果您需要重新配置环境,那么更改local_changes会将您的更改传播到所有主题分支。

    要合并回master,您可以在合并之前使用git rebase master从主题分支中删除local_changes。

答案 1 :(得分:2)

要涵盖问题的最后部分,如果你这么做很多,你可以创建一个别名来缩短程序:

switch = !f() { git stash && git checkout $1 && git stash pop; }; f

用法:git switch branchName

答案 2 :(得分:2)

只要您没有修改当前HEAD和目标提交之间不同的任何文件,使用脏工作树切换分支就会成功。如果不是这种情况,则需要合并对这些文件的更改,git checkout无法警告您正在尝试执行一些无法轻易撤消的操作。如果您仍想执行此操作,则可以使用--merge的{​​{1}}或-m选项:

git checkout