75

git rebase最近开始使用,并不能 100% 确定我做得对。为了这个问题,在 origin 有两个分支,masternext,从 分支出来master

自两者之间上次同步以来,master有 2 次提交和next6 次:

$ git log --oneline origin/next..origin/master
59b5552 master commit #2
485a811 master commit #1

$ git log --oneline origin/master..origin/next
4ebf401 next commit #6
e9b6586 next commit #5
197ada0 next commit #4
4a2c3c6 next commit #3
040a055 next commit #2
84537bf next commit #1

当我结帐next并执行git rebase -i origin/master时,我得到以下信息:

$ git status
# On branch next
# Your branch and 'origin/next' have diverged,
# and have 8 and 6 different commits each, respectively.

最后在完成之后git pull --rebase,来自的两个提交masternext

$ git log --oneline origin/next..next 
8741d09 master commit #2
485a811 master commit #1

问题:

  1. 这是正确的方法吗?
  2. 为什么在运行之前会有8 and 6不同的提交pull --rebase
  3. 是否可以简化流程?

非常感谢 :)

4

2 回答 2

83

让我们从头开始。这是您原始状态的图表:

ABC(主,原点/主)
 \
  DEFGHI(下一个,原点/下一个)

当您签出next并重新设置为基础时,它nextorigin/master两个已经打开的提交之后创建了 6 个新提交origin/master。这些新提交将“主提交 #2”(C在我的图表中)作为它们的祖先,而不是它们的原始祖先在哪里origin/masterorigin/next分歧(A在我的图表中),因此它们的哈希值会有所不同。我相信这就是为什么你会看到它next有 8 个不同的提交 from origin/next: 2 fromorigin/master和 6 个“rehashed”提交 on origin/next

之后git checkout next ; git rebase -i origin/master,你应该有这个:

ABC(主,原点/主)
 \ \
  \D'-E'-F'-G'-H'-I'(下)
   \
    DEFGHI(原点/下一个)

您可以看到next确实有 8 个未提交的提交origin/next,并且origin/next确实有 6 个未提交的提交next。当然,这只是根据提交的 SHA-1 哈希值。如果您,实际内容应该非常匹配git diff origin/next next——差异应该只显示来自B和的更改C(如图所示)。

当您git pull --rebase仍在 on时执行此操作时next,它会从源(远程origin/next)获取更改并将当前分支(next)重新定位到该远程。这会导致在新分支之后出现next不在其中的更改。它应该如下所示:origin/nextorigin/nextnext

ABC(主,原点/主)
 \
  DEFGHI(原点/下一个)
             \
              B'-C'(下一个)

如果这是您希望历史图表的样子,那么您就成功了。

但是,我怀疑您真的希望事情看起来像中间图,特别是如果next您正在处理项目的下一部分并且master用于稳定代码和小错误修复的功能分支。如果是这样,那么您应该这样做git push而不是git pull --rebase让遥控器反映您的历史版本,而不是相反。

于 2012-07-19T17:48:47.137 回答
2

从使用 master 重新定位分支的非常简单的步骤开始;姓名;

git-rebase

概要;

git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
        [<upstream>] [<branch>]
git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
        --root [<branch>]
git rebase --continue | --skip | --abort | --edit-todo

描述; 假设存在以下历史并且当前分支是“sample”:

 A---B---C sample
         /
    D---E---F---G master

从这一点来看,以下任一命令的结果:

git rebase master
git rebase master sample

将会:

A'--B'--C' sample
                 /
    D---E---F---G master

注意git checkout sample:后一种形式只是 . 的简写形式git rebase master。当 rebase 退出时,sample 将保留已签出的分支。

如果上游分支已经包含您所做的更改(例如,因为您邮寄了一个应用于上游的补丁),那么该提交将被跳过。例如,在以下历史记录上运行“git rebase master”(其中 A 和 A 引入了相同的更改集,但具有不同的提交者信息):

A---B---C sample
         /
    D---E---A'---F master

将导致:

 B'---C' sample
              /
D---E---A'---F master

所有这些都是对变基过程的图解理解。一旦解决了键入后发现的冲突,请git rebase master 解决冲突并键入git add -u以将更改的代码添加到存储库。之后执行命令git rebase --continue并继续解决冲突并重复命令;

git add -u 

git rebase --continue 

直到没有发现冲突。最后的命令将是,

git push --force origin sample(your branch name)
于 2013-12-26T10:37:57.600 回答