用分支在Git中移动文件

时间:2013-08-17 01:01:27

标签: git branch

我开始了一个小项目,然后是Git。随着时间的推移,项目不断发展,现在主文件夹需要进行大规模的重组。

这是一个Android项目,所以目前我有这个结构:

/myProject/
   +-- AndroidManifest.xml
   +-- res/
   +-- src/
   +-- ServerPart/
   +-- [other folders and files]

现在,我想转向这样的结构:

/myProject/
   +-- android/
           +-- AndroidApplication/
                    +-- AndroidManifest.xml
                    +-- res/
                    +-- src/
           +-- AndroidApplicationTest/
   +-- server/
   +-- aFolderwithOtherFiles/

首先,如果您对更好的结构(最佳实践)有一些建议,请不要犹豫。

问题是我有几个分支。例如,如果我在master分支上执行此操作,当我在另一个分支上执行checkout时,我的结构将会爆炸(Eclipse可能不会欣赏它)。

是否有解决方案来进行重构并调整我的分支以“给”他们这个新结构?

2 个答案:

答案 0 :(得分:1)

您需要使用master分支中的git mv来移动内容。

当您准备将这些内容应用于分支机构时,您需要添加并提交更改。然后在每个分支上你需要签出,然后我可能会做git rebase master

这将在文件夹结构之上应用您的更改。

当然,任何依赖于当前结构的代码都需要更改。

有些命令可能如下所示:

 git mv AndroidManifest.xml android
 mkdir android/AndroidApplicationTest
 touch android/AndroidApplicationTest/.gitkeep
 git add .
 git mv ServerPart server
 git status
 git add .
 git commit -m'Restructured application'
 git checkout dev
 git rebase master
 First, rewinding head to replay your work on top of it...
 Fast-forwarded dev to master.

答案 1 :(得分:1)

如果在rebase期间必须应用太多更改,则会出现合并冲突。通常,您可以通过不直接重新绑定到master来帮助git,但是从提交到提交以较小的步骤执行rebase。

在最低级别,git不知道“文件移动”。它只知道删除和创建新文件。但是,如果两者都发生在同一次提交中,并且已删除且新创建的文件足够相似,则git会假定实际上发生了“文件移动”并且行为正常(例如,在rebase期间应用提交时)。

所以,请这样:

  • 将重组拆分为多个提交,每个提交不超过50-70个文件。这有助于git正确检测移动。

  • 不要执行任何其他更改,但文件会在这些提交中移动!如果源代码更改了Java包,则只允许更改为新包名称。

  • 在项目中应用两个标签:“preoves”到移动提交之前的最后一次提交,“postmoves”移动到移动提交的最后一个。我是用gitk做的。

现在,在使用“premoves”标记进行提交之前,您已拥有所有功能分支。通过三个步骤执行rebase:

1)将分支重新定位到“premoves”提交。由于以前没有文件移动,这是一个“正常”的变种,具有所有通常的花里胡哨。

2)现在执行“git rebase postmoves”。这会使你的分支机构重组。由于您的主分支只包含文件移动而您的功能分支包含对文件的实际内容更改,因此git应该能够在很大程度上自动处理该情况。但是,您将在功能分支中删除的文件上出现合并冲突。

通过说在重构的功能分支上也应该删除功能分支的已删除文件来手动解决这些合并冲突(记住,git不知道语义。它只是看到:“一方面,文件被移动了,另一方面被删除了。我不知道该怎么做。“)我在git gui做了这个,说”拿远程版本“(远程?本地?那个在差异窗口显示为” DELETED“)

在此rebase之后,您在功能分支上更改的所有文件都应处于重新构建的位置,并且仍会应用所有更改。删除了功能分支的已删除文件。仅剩下问题:功能分支上的新文件。

这些新文件,您必须手动移动到正确的新位置。请记住,git只看到文件,它不知道“移动目录结构”。因此,将功能分支的新文件移动到新的正确位置,并为它们应用git提交。

我建议单独为每个文件提交这些文件移动,然后在触及文件的功能分支的最后一次提交时使用“git rebase -i”和“fixup”文件移动提交。这可以防止太多的混乱。

3)完成所有这些后,执行最后的“git rebase master”(或其他)。现在这也是一个标准的变革,因为重组已经发生在功能分支上。