【问题标题】:How is `git pull --rebase` different than `git reset --soft origin/b``git pull --rebase` 与 `git reset --soft origin/b` 有何不同
【发布时间】:2019-02-06 23:41:32
【问题描述】:

我试图了解git pull --rebase...为了做到这一点,该命令与:

git fetch origin
git reset --soft remotes/origin/foo
git add .
git commit -am "bar"
git merge remotes/origin/foo

git pull --rebase是和上面的命令一样还是不同?当然是不那么冗长,显然。

【问题讨论】:

  • git pull 只是git fetch + git merge 的简写。 git pull --rebasegit fetch + git rebase

标签: git git-rebase git-reset


【解决方案1】:

不,它们完全不同。

假设您已使用干净的树检出 master,那么您建议的命令集将具有将 master 指向单个提交的效果,该提交的父级是上游提取的,但其 内容具有用您的预取 master 的副本替换新上游树的效果,而不合并任何上游更改。 (特别是,最后的git merge remotes/origin/foo 总是会说“已经是最新的。”并且永远不会进行任何更改。)

那是因为命令:

git reset --soft remotes/origin/foo

master 设置为指向remotes/origin/foo,而不更改当前工作目录(或索引)。然后,命令:

git commit -am "bar"

从您当前的 master 中检查(未更改的)树的单个提交。就 Git 而言,您刚刚获取了上游,然后有条不紊地将其更改为与您自己的 master 基于较早的上游完全一样,撤消自上次拉取以来所做的任何更改,然后将其签入顶部的上游。由于这个提交现在是上游的后代,它已经被认为是合并的,并且:

git merge remotes/origin/foo

不会有任何影响。

相比之下,git pull --rebase 相当于

git fetch origin
git rebase remotes/origin/foo  # or wherever you pull from

这具有重放自您上次从上游拉到上游分支顶部并指向master 上提交的序列的效果结果为 987654334@。

因此,它与上述命令的不同之处在于它向上游添加 sequence 提交而不是添加单个提交,并且它重放提交的内容(这意味着它试图重放在这些提交中所做的更改)在上游之上,而不是用 master 的旧内容替换上游并消除上游更改。最后,master 仍然remotes/origin/foo 的后代,所以运行:

git merge remotes/origin/foo

仍然不会做任何事情,但它不必做任何事情,因为新获取的上游更改将被合并到新的 master 分支中。

【讨论】:

  • 注意:以上假设(至少在我输入的那一刻)当前分支是master。 (git reset 命令总是影响当前分支。)(注意git commit 也基于索引内容提交更正确,但git commit -a 具有首先运行git add --all 的效果,因此索引内容根据工作树更新。)
  • master 上的好点。我编辑了答案以提及这一点。在这种情况下,因为重置是软的,所以索引和工作树实际上是相同的,所以据我所知,git commitgit add-a 标志没有做任何事情。
  • 对,这就是为什么我说“更正确”并将其放在括号中(尽管我们假设它们的开头相同!)。如果要使用混合重置,则添加步骤会更改索引。
猜你喜欢
  • 2017-12-07
  • 2021-02-05
  • 1970-01-01
  • 2021-10-28
  • 2021-10-14
  • 2017-08-19
  • 2012-06-28
  • 2013-01-31
  • 1970-01-01
相关资源
最近更新 更多