git-stash和git-rebase的真正功能是什么?

时间:2013-05-16 06:18:48

标签: git

我正在研究git,我对一些命令问题感到困惑:

  1. 我创建了两个分支A和B.在我的本地存储库中,A已经存在。现在我想将B检查到同一个本地存储库中,并在B处运行而不会打扰A.所以我可以在没有git -stash A的情况下查看B吗? (就在不久之前,我只是直接输入结账B,没有git -stash A,我认为它也可以工作。为什么?)git -stash的功能是什么?

  2. 我对git -merge和git -rebase感到困惑。我应该选择哪种情况?

3 个答案:

答案 0 :(得分:4)

Stash只会隐藏您未提交的更改,以便您可以暂时处理其他内容。在过去,您曾经提交更改,切换分支,切换回来,然后使用“git reset HEAD ^”来反转您的提交。

关于rebase,这是我的笔记:

与merge类似,但保持一个连续的线程。

简而言之,rebase获取当前分支并在其历史记录中搜索从指定分支分叉的点。然后它将所有这些提交作为补丁并将它们应用于指定的分支,从而有效地将这些提交移植到指定分支的末尾。

之前:

     E--F--G        mybranch
    /
A--B--C--D          upstream

在“rebase upstream”之后:

           E'-F'-G' mybranch
          /
A--B--C--D          upstream

如果两个分支中都有任何提交(例如,因为您将某个补丁邮寄给某人并且已应用),那么它们就不会被冗余应用。见手册页。

注意:这会弄乱任何已经拥有分支副本的人。此命令最好仅用于尚未推送到另一个存储库的提交。

上游可以是分支或任何其他有效提交。

如果遇到冲突,git会向受影响的文件添加冲突标记(<<<<<<<<<<<<<<<<<解决冲突后,请使用“git add file ”。处理完所有冲突后,请使用“git rebase --continue”。您也可以使用“git rebase --abort”

取消rebase

如果您当前分支中有未经修改的更改,则必须先进行存储,然后再进行rebase。


还允许您使用“-i”选项重新写入当前分支的历史记录(请参阅“重新排列提交”):

之前:

A--B--C--D--E

后:

A--B--E'-C'-D'

甚至组合(壁球)提交:

A--B--CE'-D'

或完全删除链中的提交:

A--B--D'-E'

<强>到

--onto branch选项允许您将更改完全移植到其他分支。例如,假设您的分支是从分支'foo'分叉的:

o--o--o--o--o  master
    \
     o--o--o--o--o  foo
                  \
                   o--o--o  mybranch

但是现在你想要它从主人那里分叉出来:

o--o--o--o--o  master
    \        \
     \        o--o--o  mybranch
      \
       o--o--o--o--o  foo

你会检查mybranch并给出这个命令:

git rebase --onto master foo

在英语中,这表示“自从(但不包括)foo之后进行所有更改,并将它们应用于主人。”

- 在也可用于拼接链中的提交。请参见手册页。 -i也可用于此。


注意: rebase被视为有害:此命令通过有效重写历史记录来工作。有可能将自己置于一个不可能从过去的某个时刻重建存储库状态的状态。例如,在上面给出的第一个示例中,存储库状态E,F和G现在永远丢失。

好消息是,如果在进行rebase之前将分支名称或标签分配给事物,那么什么都不会真正丢失。如果我在执行rebase之前已经完成git branch foo,则分支“foo”将指向存储库的原始状态G,使其可以在以后恢复(直到您删除分支foo)。

       E-F-G   foo
      /
     /     E'-F'-G' mybranch
    /     /
A--B--C--D          upstream

答案 1 :(得分:2)

git stash存储您未提交的更改。例如,你开始处理分支A上的一个功能,然后意识到你应该在分支B上工作,你会这样做

git stash
git checkout B
git stash pop

the book中有一章关于它。

Rebase / merge几乎是一个意见问题。我经常喜欢rebase。根据经验,你不应该重新定义任何已公开的内容,因为rebase会重写历史记录。

答案 2 :(得分:2)

在英语中“藏匿”表示“存放一些地方”或“收起或保管以备将来使用”。这正是git stash的作用。如果您正在处理某些事情但又不想提交它,因为它没有完全完成但需要处理其他紧急事件,那就是当您使用git stash时。存储您最近的更改并分支到您需要工作的新紧急事项。有关存储方式的详细说明,请参阅this chapter (6.3 Git Tools - Stashing) in ProGit book

简单来说,变基是指理顺你工作历史的行为。要完全理解它意味着什么,您需要了解分支是什么以及合并意味着什么。所以我建议你阅读the chapter on branching from the ProGit book