Git 重命名发散的文件夹,并合并回主文件夹

Git 重命名发散的文件夹,并合并回主文件夹,git,Git,在我正在开发的代码库中,我们有一个遗留应用程序(“OldApp”),它最近在自己的分支中得到了极大的提升和升级(“NewApp”) 现在,我们已经决定不能立即将OldApp替换为NewApp,因此我们需要继续支持OldApp一段时间,直到我们能够让足够多的客户迁移到NewApp 由于两者都共享相同的后端服务器代码,因此从长远来看,将内容保存在两个单独的分支中并不太容易维护(而且当代码库出现分歧时,我们不一定要将OldApp中的更改合并到NewApp之上)因此,我们希望在NewApp发布后将所有内

在我正在开发的代码库中,我们有一个遗留应用程序(“
OldApp
”),它最近在自己的分支中得到了极大的提升和升级(“
NewApp
”)

现在,我们已经决定不能立即将
OldApp
替换为
NewApp
,因此我们需要继续支持
OldApp
一段时间,直到我们能够让足够多的客户迁移到
NewApp

由于两者都共享相同的后端服务器代码,因此从长远来看,将内容保存在两个单独的分支中并不太容易维护(而且当代码库出现分歧时,我们不一定要将
OldApp
中的更改合并到
NewApp
之上)因此,我们希望在
NewApp
发布后将所有内容合并回主分支

因此,在
Master

ClientApps\ClientApplication
-其中包含旧代码

在纽伯兰我们有

ClientApps\ClientApplication
-包含新代码(基于旧代码)

我们想要得到的是一个包含

ClientApps\OldApp
-包含来自master的ClientApplication的文件和历史记录

ClientApps\NewApp
-包含来自新分支的文件和历史记录


如何使用git实现这一点?我基本上不希望最终意外地将新代码合并到旧代码库中。虽然我可以复制整个newapp文件夹并将其粘贴回master,但这会丢失所有历史记录,这是我不必做的。

假设OldApp是在
master
分支中开发的,而newapp是在
newapp
分支中开发的,如果希望在
master
中同时使用OldApp和NewApp,则以下命令序列将满足您的要求:

git checkout newapp
git mv ClientApps/ClientApplication ClientApps/NewApp
git commit -m "ClientApplication -> NewApp"
git checkout master
git mv ClientApps/ClientApplication ClientApps/OldApp
git commit -m "ClientApplication -> OldApp"
mkdir ClientApps/NewApp
git checkout newapp ClientApps/NewApp
git commit -m "Imported ClientApps/NewApp from the newapp branch"
但是请注意,ClientApps/NewApp在主分支上没有任何以前的历史记录(尽管它的初始提交消息清楚地指出了它的来源)

编辑1:要将
分支上的新应用的历史记录连接到
新应用
分支上的历史记录,请执行以下操作:

parent1=$(git rev-parse master^)
parent2=$(git rev-parse newapp)
git filter-branch --parent-filter "echo '-p $parent1 -p $parent2'" -- master^..master

假设OldApp正在
分支中开发,NewApp在
新应用
分支中开发,并且您希望OldApp和NewApp都在
中开发,以下命令序列将满足您的需要:

git checkout newapp
git mv ClientApps/ClientApplication ClientApps/NewApp
git commit -m "ClientApplication -> NewApp"
git checkout master
git mv ClientApps/ClientApplication ClientApps/OldApp
git commit -m "ClientApplication -> OldApp"
mkdir ClientApps/NewApp
git checkout newapp ClientApps/NewApp
git commit -m "Imported ClientApps/NewApp from the newapp branch"
但是请注意,ClientApps/NewApp在主分支上没有任何以前的历史记录(尽管它的初始提交消息清楚地指出了它的来源)

编辑1:要将
分支上的新应用的历史记录连接到
新应用
分支上的历史记录,请执行以下操作:

parent1=$(git rev-parse master^)
parent2=$(git rev-parse newapp)
git filter-branch --parent-filter "echo '-p $parent1 -p $parent2'" -- master^..master

我试着测试一下,得到了预期的结果

$ git checkout master
$ git mv ClientApplication/ oldApp
$ git commit -m "move old"
$ git checkout NewBranch
$ git mv ClientApplication/ newApp
$ git commit -m "move new"
$ git checkout master
$ git merge NewBranch
Merge made by the 'recursive' strategy.
 newApp/test.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 newApp/test.txt
$ ls
newApp/  oldApp/
$ git log --graph --oneline
*   e5c6b12 Merge branch 'NewBranch'
|\
| * 51e4806 move new
| * 1a5703d new-changes
* | 70544c7 move old
* | d55002d old-changes
|/
* dbea2e7 old

我试着测试一下,得到了预期的结果

$ git checkout master
$ git mv ClientApplication/ oldApp
$ git commit -m "move old"
$ git checkout NewBranch
$ git mv ClientApplication/ newApp
$ git commit -m "move new"
$ git checkout master
$ git merge NewBranch
Merge made by the 'recursive' strategy.
 newApp/test.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 newApp/test.txt
$ ls
newApp/  oldApp/
$ git log --graph --oneline
*   e5c6b12 Merge branch 'NewBranch'
|\
| * 51e4806 move new
| * 1a5703d new-changes
* | 70544c7 move old
* | d55002d old-changes
|/
* dbea2e7 old


您是否尝试过在每个分支中重命名它们,然后合并?当名称不同时,应该没有冲突。我担心它会看到重命名,并且只考虑合并的这一部分(即<代码> OLDApp文件夹将被重新命名并合并为合并的一部分),所以您真的尝试过了吗?在(不太可能)失败的情况下,您可以随时返回到任何现有的提交。是的,我刚刚做了。最后,OldApp包含了代码和历史记录,而NewApp却被抛在了后面。在讨论的目录之外,
NewBranch
中是否有任何冲突的更改?您是否尝试过在每个分支中重命名它们,然后合并?当名称不同时,应该没有冲突。我担心它会看到重命名,并且只考虑合并的这一部分(即<代码> OLDApp文件夹将被重新命名并合并为合并的一部分),所以您真的尝试过了吗?在(不太可能)失败的情况下,您可以随时返回到任何现有的提交。是的,我刚刚做了。最后,OldApp包含代码和历史记录,而NewApp却被抛在了后面。在讨论的目录之外,
NewBranch
中是否有任何冲突的更改?这基本上与手动复制/粘贴代码相同,虽然-我真的很想找到一种方法来维护这两个版本的历史,但我尝试了一下,结果似乎只是主控中的所有文件都绑定到新分支的最后一次提交(文件夹重命名)。诚然,我是在windows上这样做的,所以不得不稍微更改一下命令,但我认为这在其他方面是正确的。(~1s而不是^s)我现在意识到这在技术上是正确的,因为我忘了在重命名文件夹时git不会保留历史,所以我想我也需要这样做@benjymous那么我的回答是否解决了你的问题?如果现在,您的确切要求是什么?它解决了我提出的问题,但并没有真正解决我需要的问题-因为重命名文件夹的行为会抹去历史记录,我们只会得到“重命名”条目(因此需要在重命名之前拉过历史记录),这与手动复制/粘贴代码基本相同,虽然-我真的很想找到一种方法来维护这两个版本的历史,但我尝试了一下,结果似乎只是主控中的所有文件都绑定到新分支的最后一次提交(文件夹重命名)。诚然,我是在windows上这样做的,所以不得不稍微更改一下命令,但我认为这在其他方面是正确的。(~1s而不是^s)我现在意识到这在技术上是正确的,因为我忘了在重命名文件夹时git不会保留历史,所以我想我也需要这样做@benjymous那么我的回答是否解决了你的问题?如果现在,您的确切要求是什么?它解决了我提出的问题,但并没有真正解决我需要的问题-因为重命名文件夹的行为会清除历史记录,所以我们只需要