4

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

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

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

现在,我想搬到这样的结构:

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

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

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

是否有解决方案来进行这种重构并调整我的分支以“赋予”它们这种新结构?

4

2 回答 2

1

你会想要使用git mvin master 分支来移动东西。

当您准备好将这些东西应用到您的分支时,您需要添加并提交您的更改。然后在每个分支上你都需要签出,然后我可能会做一个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.
于 2013-08-17T12:57:50.357 回答
1

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

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

所以,像这样去:

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

  • 请勿进行任何其他更改,而在这些提交中移动文件!如果源代码更改 Java 包,则只允许更改新包名称。

  • 将两个标签应用于您的项目:“premoves”到移动提交之前的最后一个提交,“postmoves”到最后一个移动提交。我在 gitk 中做到了这一点。

现在,在带有“premoves”标签的提交之前,您已经拥有了所有功能分支。分三个步骤执行变基:

1) 将分支变基为“premoves”提交。由于之前没有文件移动,这是一个“正常”的变基,具有所有通常的花里胡哨。

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

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

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

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

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

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

于 2013-11-15T07:10:33.363 回答