主重命名脚本后的git merge / rebase功能分支

时间:2013-12-16 03:11:00

标签: git rename git-filter-branch

背景:我正在研究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"

2 个答案:

答案 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加强,使其看起来好像已经在新位置直接创建了本地添加的文件。