背景:我正在为Drupal core(PHP)开发一个补丁,其中当前使用PSR-0的模块类文件将向上移动两个目录,因此它们将使用PSR-4。这会让很多人感到愤怒,因为许多悬而未决的补丁/本地功能分支将需要重新滚动。我想找到一种方法,使这尽可能无痛
有一个大型项目,有一个公共的master分支,许多人都有自己的本地特色分支。
在master分支上,我们添加了一个脚本,该脚本将移动一堆文件。以前在core/modules/$module/lib/Drupal/$module/Foo/Bar.php
中的每个文件都将向上移动两个目录,因此它变为core/modules/$module/lib/Foo/Bar.php
。每个模块都会发生这种情况,因此$module可以取多个值。
局部要素分支可以修改现有文件,但也可以添加新文件或删除现有文件。他们甚至可以重命名文件。所有这些都在"旧"目录结构上
事实上,Merge或rebase确实可以将大量或所有修改保存到重命名的文件中——尽管我不确定它是否可以100%可信
但创建的新文件将保留在旧位置,需要手动移动。
更可靠的方法是在本地分支上执行脚本,对于不在master上的每个本地提交,然后以某种方式重新建立本地分支的基础。
目标是拥有一个历史记录,所有本地提交看起来都是在新的文件结构上完成的
例如,如果一个文件是在core/modules/views_ui/lib/Drupal/views_ui/NewClass.php
中创建的,那么它应该看起来像是直接在core/modules/views_ui/lib/NewClass.php
中创建的
实现这一切自动化的最佳方法是什么
理想情况下,我会为其他开发人员提供一个脚本,他们可以在没有太多手动工作的情况下使用。
gitfilter分支看起来很有前途,但我需要以一种非常具体的方式使用它。
编辑:阐明的图表
master
m5
^
|
|
+
m4
^
|
|
+ local dev
master rewritten local history moved
moved +--------> new1 +-------> new2 +--------> new3
m3 ^ ^ ^
^ | | |
|move |move |move |move
|script |script |script |script
| | | |
+ | | +
before + + local dev
move +---------> old1 +-------> old2 +--------> old3
m2 old local history
^
|
|
+
m1
第二版:以下手动命令可以完成任务:(所有本地更改都在"核心"子目录中)
git checkout m3
git branch dev-new; git checkout dev-new
rm -r core
git checkout old1 .
php core/scripts/switch-psr4.php
git add -A .; git commit -m"transformed old1"
rm -r core
git checkout old2 .
php core/scripts/switch-psr4.php
git add -A .; git commit -m"transformed old2"
rm -r core
git checkout old3 .
php core/scripts/switch-psr4.php
git add -A .; git commit -m"transformed old3"
是的,git filter-branch
可能是您想要的工具。
你可能想使用这样的东西:
git filter-branch --tree-filter
'git mv core/modules/views_ui/lib/{Drupal/views_ui/,}NewClass.php'
-- origin/master..master
使用git存储库的示例:
$ git co -b foo 1f6fb7ffc344e59589ac794ce7ae47ae7c2cff42
$ git log --name-status -n 3
commit 1f6fb7ffc344e59589ac794ce7ae47ae7c2cff42
Author: Ralf Thielow <ralf.thielow@gmail.com>
Date: Fri Nov 8 20:34:35 2013 +0100
l10n: de.po: improve error message when pushing to unknown upstream
Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
Acked-by: Thomas Rast <tr@thomasrast.ch>
M po/de.po
commit 1d38363d86d16dee58df15a047d448baee6435ba
Author: Ralf Thielow <ralf.thielow@gmail.com>
Date: Sat Nov 2 18:58:52 2013 +0100
l10n: de.po: translate 68 new messages
Translate 68 new messages came from git.pot update in 727b957
(l10n: git.pot: v1.8.5 round 1 (68 new, 9 removed)).
Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
Acked-by: Thomas Rast <tr@thomasrast.ch>
M po/de.po
commit 1b12df5262aae78b5fbcdb94e718d19710ce12a5
Author: Ralf Thielow <ralf.thielow@gmail.com>
Date: Sat Nov 2 18:56:14 2013 +0100
po/TEAMS: update Thomas Rast's email address
Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
Acked-by: Thomas Rast <tr@thomasrast.ch>
M po/TEAMS
$ git filter-branch --tree-filter 'git mv po/de.po de.po' -- foo^^^..foo
Rewrite 1f6fb7ffc344e59589ac794ce7ae47ae7c2cff42 (3/3)
Ref 'refs/heads/foo' was rewritten
$ git log --name-status -n 3
commit 4c2629a746d42a0eed79fb7be5fc4f66258c0f3f
Author: Ralf Thielow <ralf.thielow@gmail.com>
Date: Fri Nov 8 20:34:35 2013 +0100
l10n: de.po: improve error message when pushing to unknown upstream
Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
Acked-by: Thomas Rast <tr@thomasrast.ch>
M de.po
commit 67aab1af4cf200998c565e31a75a107469f3da78
Author: Ralf Thielow <ralf.thielow@gmail.com>
Date: Sat Nov 2 18:58:52 2013 +0100
l10n: de.po: translate 68 new messages
Translate 68 new messages came from git.pot update in 727b957
(l10n: git.pot: v1.8.5 round 1 (68 new, 9 removed)).
Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
Acked-by: Thomas Rast <tr@thomasrast.ch>
M de.po
commit 31161ea7d16d531dd49f13ac8675b2f9c46ab0eb
Author: Ralf Thielow <ralf.thielow@gmail.com>
Date: Sat Nov 2 18:56:14 2013 +0100
po/TEAMS: update Thomas Rast's email address
Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
Acked-by: Thomas Rast <tr@thomasrast.ch>
A de.po
M po/TEAMS
D po/de.po
如果我理解正确的话,这就是你想要的。
看起来一个普通的git rebase
实际上并没有那么糟糕!
在上图中的场景中,这将是
git checkout dev-local
git rebase origin/master
php move-files-around.php
git add -A .
git commit -m"Move locally added files to their new location"
这可以通过一些交互式的rebase来增加趣味性,使其看起来像是在新位置直接创建了本地添加的文件。