背景:我正在研究Drupal核心(PHP)的补丁,其中当前使用PSR-0的模块类文件将被移动两个目录,因此它们将使用PSR-4。这会让很多人生气,因为很多未决的补丁/本地功能分支都需要重新滚动。我想找到一种尽可能无痛的方法。
有一个包含公共主分支的大项目,并且有许多人拥有自己的本地功能分支。
在主分支上,我们添加了a script,它将移动一堆文件。以前的每个文件都在core/modules/$module/lib/Drupal/$module/Foo/Bar.php
will be moved two directories up中,因此它变为core/modules/$module/lib/Foo/Bar.php
。每个模块都会发生这种情况,因此$ module可以采用多个值。
本地功能分支可以修改现有文件,但也可以添加新文件或删除现有文件。他们甚至可以重命名文件。所有这些都在“旧”目录结构上 实际上,合并或重组确实会将大量或全部修改保存到重命名的文件中 - 尽管我不确定它是否可以100%受信任。 但是创建的新文件将保留在旧位置,需要手动移动。
更可靠的方法是在本地分支上执行脚本,对于不在master上的每个本地提交,然后以某种方式重新绑定本地分支。
目标是创建一个历史记录,其中所有本地提交看起来就像在新文件结构上完成一样。
例如。如果文件是在core/modules/views_ui/lib/Drupal/views_ui/NewClass.php
中创建的,那么它应该看起来像是直接在core/modules/views_ui/lib/NewClass.php
中创建的
自动化所有这些的最佳方法是什么?
理想情况下,我会为其他开发人员提供一个脚本,他们可以在不需要太多手动工作的情况下使用它。
git filter-branch似乎很有希望,但我需要以非常具体的方式使用它。
编辑:图表澄清
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
编辑II:以下手动命令可以解决这个问题: (所有本地更改都在“核心”子目录中)
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"
答案 0 :(得分:0)
是的,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
如果我理解正确,这就是你想要的。
答案 1 :(得分:0)
普通的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加强,使其看起来好像已经在新位置直接创建了本地添加的文件。