我有一个包含两个主要分支的 Git 存储库:master 和 dev。它目前看起来像这样:
master ( )----( )----(A)----(B)----(C)
\
\
dev ( )----( )----( )----( )----(~ 30 additional commits...)
Run Code Online (Sandbox Code Playgroud)
非常简单,除了master上的 commit A包含对文件和文件夹结构的重大更改(基本上,我使用此处显示的步骤将存储库在层次结构中向上移动了一层)。
我想继续在 dev 分支上工作,但是当我尝试将 dev 变基到 master 以将新的文件结构引入 dev 时,Git 出现了大量错误。我git reset回到了一个理智的状态,但在我(有些有限)的 Git 经验中,许多错误通常意味着我采取了错误的方法。
有没有更好的方法将重新组织的文件夹结构转移到 dev 分支?如果有帮助,主(B和C)上的其他提交中的更改非常小,如果丢失它们会使事情变得更容易,我可以接受。
Ano*_*noE 12
是的,有一种理智的方法可以做到这一点。
master 现在是(如果我理解正确的话):
project
src
file.c
Run Code Online (Sandbox Code Playgroud)
dev是,因为它不包含 commit A:
src
file.c # with some changes
Run Code Online (Sandbox Code Playgroud)
你的分支是这样的:
master ( )----(A0)----(A)----(B)----(C)
\
\
dev (D1)----(D2)----(D3)----( )----(~ 30 additional commits...)
Run Code Online (Sandbox Code Playgroud)
我还假设除了被插入到所有文件路径中(根据您链接的问题,“将您的树向上移动”到新的根目录中)之外,没有任何A区别。A0project/project
我们在每一步都做我们git rebase内部会做的事情,同时git有点愚弄,通过做我们自己的“挑选”步骤而不是自己git做的事情。
我们使用第二个工作目录。$WD1是原始工作目录的绝对路径,$WD2是其他一些绝对路径(除此之外)。
首先,创建您的助手目录作为原始目录的克隆:
cd $WD2
git clone $WD1 dev .
Run Code Online (Sandbox Code Playgroud)
然后,启动一个newdev最终将dev基于A.
cd $WD1
git checkout A
git checkout -b newdev
Run Code Online (Sandbox Code Playgroud)
我们在不给任何机会把它搞砸的情况下D1提交:newdevgit
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`"
Run Code Online (Sandbox Code Playgroud)
现在的情况是:
newdev (D1')
/
/
master ( )----(A0)----(A)----(B)----(C)
\
\
dev (D1)----(D2)----(D3)----( )----(~ 30 additional commits...)
Run Code Online (Sandbox Code Playgroud)
现在,重复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`"
Run Code Online (Sandbox Code Playgroud)
现在的情况是:
newdev (D1')----(D2')
/
/
master ( )----(A0)----(A)----(B)----(C)
\
\
dev (D1)----(D2)----(D3)----( )----(~ 30 additional commits...)
Run Code Online (Sandbox Code Playgroud)
重复直到完成。
当然,您需要为这些命令创建一个小的 shell 脚本,它会遍历所有提交D1 ... D30。
之后,一个简单的git rebase master将像往常一样执行从A到的变基C。然后,newdev通过更改名称来摆脱:
git checkout newdev
git branch olddev dev # just in case...
git branch -D dev
git checkout -b dev
Run Code Online (Sandbox Code Playgroud)
为什么是第二个工作目录?
请注意,在这种特殊情况下,可能有一些方法可以通过rm -r project/src ; git checkout D1 src ; mv src project/直接使用来避免二级工作目录。我更喜欢像上面那样做,只是为了 100% 确保一切都非常干净并且始终“可见”。通过这种方式,结帐操作与我们自己应用的修改完全分开。
从字面上看,这种方式不会出错,而且这种方法也适用于所有其他类型的更改。对于重要的更改,假设有人更改了A. 这种方法使得将其他分支变基到此变得微不足道(如果您也可以将该空白更改放入脚本中)。