合并后如何变基?

时间:2012-05-15 10:05:33

标签: git git-merge git-rebase

我们有一系列事件如下:

  1. 创建分支A,并向其添加一些提交
  2. 时间过去了,数百次提交已添加到主
  3. Master合并为A
  4. 时间过去了,可能还有另外50个提交添加到主
  5. 是否可以将步骤3中的合并转换为rebase?如果不出意外,它会使即将发生的合并变得更简单,因为可以看到更少的历史记录。

    我们没有启用rerere。

1 个答案:

答案 0 :(得分:3)

考虑以下Git图:

A...C...D...F
^       ^   ^ master
 \       \
  G...H...I...J
              ^ feature

......意味着“许多提交”。

假设我们想要实质上重新定义,即在特征历史中但不在主历史中进行提交,并将它们改为主数据提交的线性序列。我们在提交I中将master合并到feature中这一事实使我们感到困惑。如果我们试图改变,Git会搞砸,因为它试图应用例如C位于主人之上并发现冲突。

我们可以通过从feature获取实际更改并将它们打包到新提交中来解决此问题。 这是使用非常基本的Git命令执行此操作的方法:

(1) git checkout feature
(2) git merge master
(3) git reset A
(4) git add -A  # This stages all working copy changes
(5) git commit -m "Every change between A and J"

在步骤(2)中,feature分支在masterJ中都有所有更改。 在步骤(3)之后,HEAD指向A,但我们的工作副本包含masterJ的所有更改,以及步骤(4)和(5)阶段并提交这些更改

此时我们的图表看起来像这样

A...C...D...F
^           ^ master
 \
  J'
  ^ feature

请注意,J'包含A...F中的所有内容。现在我们做

git rebase master

Git愉快地将J'中的更改应用为新提交J'',但要添加的唯一更改是G...J中的更改,因为其他更改已在主服务器中。所以我们现在有了

  A...F<--J''
master^   ^feature

feature分支中的所有更改压缩为提交J''。 此时,如果需要,您可以重置为F并以更精细的方式重新应用J''中的更改(即使使用git add --patch)。

另一种基本相同的方法是使用read-tree

中所述的git checkout master git read-tree -u -m feature
git diff master > feature.patch
git checkout master
patch -p1 < feature.patch

this other answer偷来的另一种做同样事情的方法是

configfile2 = open('Example.txt' + '_temp',"w")
    with open('Example.txt', 'r') as configfile:
      while 1:          
       line = configfile.readline()
       string = line
       if not line:
        break

       # remove line returns
       line = line.strip('\r\n')
       # make sure it has useful data
       if (not "=" in line) or (line[0] == '%'):  
         configfile2.write(string)
       else: 
         # split across equal sign
         line = line.split("=",1)
         this_param = line[0].strip()
         this_value = line[1].strip()

         #float values
         if this_param == "alpha1":
           stringalt = '% alpha1 = '+ this_value + '   \r\n'
           configfile2.write(stringalt)                            
         else:
           configfile2.write(string) 

    configfile.close()    
    configfile2.close()
    # the file is now replaced
    os.remove('Example.txt' )
    os.rename('Example.txt' + '_temp','Example.txt' )