Git rebase / merge分支包含许多已移动的文件和文件夹

时间:2016-12-30 23:00:30

标签: git

我有一个包含两个主要分支的Git存储库:master和dev。它目前看起来像这样:

master  ( )----( )----(A)----(B)----(C)
                \
                 \
dev              ( )----( )----( )----( )----(~ 30 additional commits...)

非常简单,除了在master上提交 A 包含对文件和文件夹结构的重大更改(基本上,我使用the steps shown here将存储库移动到层次结构中的一个级别)

我想恢复dev分支上的工作,但是当我尝试将dev重新绑定到master以将新文件结构带入dev时,Git会发出大量错误。我git reset回到理智的状态,但在我对Git的(有限的)经历中,许多错误通常意味着我采取了错误的方法。

有没有更好的方法将重组的文件夹结构转移到dev分支?如果它有帮助,那么主人( B C )中其他提交的更改非常小,如果它会让事情变得更容易,我会失去它们。 / p>

1 个答案:

答案 0 :(得分:1)

是的,有一种理智的方法可以做到这一点。

前言

master现在(如果我理解正确的话):

project
   src
     file.c

dev,因为它不包含提交A

src
  file.c         # with some changes

你的分支是这样的:

master  ( )----(A0)----(A)----(B)----(C)
                \
                 \
dev              (D1)----(D2)----(D3)----( )----(~ 30 additional commits...)

我还假设AA0完全不同,除了project/被插入到所有文件路径中之外("将树移动到#34}进入新的project根,根据您的关联问题)。

让我们这样做......

我们正在做git rebase内部会做的事情,同时在每一步都愚弄git,做我们自己的"樱桃挑选"而不是git会做什么。

我们使用第二个工作目录。 $WD1是原始工作目录的绝对路径,$WD2是其他绝对路径(在此之外)。

首先,将您的帮助程序目录创建为原始文件的克隆:

cd $WD2
git clone $WD1 dev .

然后,启动一个分支newdev,最终devA重新定位cd $WD1 git checkout A git checkout -b newdev

D1

我们将newdev提交到git但未给cd $WD2 git checkout D1 cd $WD1 rm -r project/src cp -r $WD2/src project/ git add -A git commit -m "`cd $WD2 ; git log -1 --format=%s`" 任何机会搞砸了:

newdev                       (D1')     
                           /
                         /
master  ( )----(A0)----(A)----(B)----(C)
                \
                 \
dev              (D1)----(D2)----(D3)----( )----(~ 30 additional commits...)

现在的情况是:

D2

现在,重复cd $WD2 git checkout D2 cd $WD1 rm -r project/src cp -r $WD2/src project/ git add -A git commit -m "`cd $WD2 ; git log -1 --format=%s`"

newdev                       (D1')----(D2')     
                           /
                         /
master  ( )----(A0)----(A)----(B)----(C)
                \
                 \
dev              (D1)----(D2)----(D3)----( )----(~ 30 additional commits...)

现在的情况是:

D1 ... D30

重复直到完成。

当然,您需要为这些命令创建一个小的shell脚本,它会遍历所有提交git rebase master

之后,一个简单的A会像往常一样从Cnewdev进行变基。然后,通过更改名称来删除git checkout newdev git branch olddev dev # just in case... git branch -D dev git checkout -b dev

rm -r project/src ; git checkout D1 src ; mv src project/

一般说明

为什么是第二个工作目录?

请注意,在这种特殊情况下,可能有办法直接使用A来避免辅助工作目录。我更喜欢如上所示,只是为了100%确定一切都很干净,并且可见"每时每刻。这样,结账操作与我们自己应用的修改完全分开。

没有什么可以通过这种方式出错,而且该方法也适用于所有其他类型的更改。对于非平凡的更改,假设有人更改了ci中每个源文件中的每个空格。这种方法使得将其他分支重新定义到这一点上变得微不足道(如果你可以将这个空格更改放到脚本中)。