git rebase基础知识

时间:2012-07-19 14:44:09

标签: git git-rebase

我最近开始使用git rebase并且不是100%确定我做得对。出于问题的原因,有两个分支来源masternext,它们来自master

自上次同步以来,master有2个提交,next 6:

$ 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之后,来自master的两次提交都在next中:

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

问题:

  1. 这是正确的方法吗?
  2. 为什么在8 and 6运行之前会有pull --rebase次提交?
  3. 是否可以简化流程?
  4. 非常有责任:)

2 个答案:

答案 0 :(得分:51)

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

A-B-C  (master, origin/master)
 \
  D-E-F-G-H-I  (next, origin/next)

当您签出next并将next重新定位到origin/master时,它会在origin/master上的两个提交后创建6个新提交。这些新提交的“主提交#2”(我的图中为C)作为他们的祖先,而不是他们的原始祖先origin/masterorigin/next分歧(A在我的图表中),所以他们的哈希会有所不同。我相信这就是为什么你会看到next有8个与origin/next不同的提交:origin/master中的2个和origin/next上的6个“重新提交”提交。

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

A-B-C  (master, origin/master)
 \   \
  \   D'-E'-F'-G'-H'-I' (next)
   \
    D-E-F-G-H-I  (origin/next)

您可以看到next确实有8个提交未在origin/next上,而origin/next确实有6个提交未在next上。当然这只是根据提交的SHA-1哈希值。如果您git diff origin/next next,实际内容应该非常接近 - 差异应该只显示来自BC的更改(如图中标记的那样)。

当您在git pull --rebase时执行next时,它会从源(远程origin/next)获取更改并将当前分支(next)重新绑定到该远程。这会导致next中的origin/next中的更改显示在新origin/next分支上的next之后。它应该是这样的:

A-B-C  (master, origin/master)
 \
  D-E-F-G-H-I  (origin/next)
             \
              B'-C' (next)

如果这是您想要的历史图表,那么您已经成功了。

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

答案 1 :(得分:0)

从与主人重新分支你的分支的非常简单的步骤开始; 名称;

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退出时,样本仍将是签出分支。

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

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

将导致:

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

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

git add -u 

git rebase --continue 

直到找不到冲突。 最后,最后的命令是,

git push --force origin sample(your branch name)