【问题标题】:git merge/rebase feature branch after master rename script主重命名脚本后的 git merge/rebase 功能分支
【发布时间】:2014-01-03 08:48:32
【问题描述】:

背景:我正在开发 Drupal 核心 (PHP) 的补丁,其中当前使用 PSR-0 的模块类文件将向上移动两个目录,因此它们将使用 PSR-4。这会让很多人生气,因为很多待处理的补丁/本地功能分支需要重新发布。我想找到一种方法让这个过程尽可能轻松。

有一个大项目有一个公共的 master 分支,还有很多人有自己的本地特性分支。

在 master 分支上,我们添加a script,它将移动一堆文件。以前在core/modules/$module/lib/Drupal/$module/Foo/Bar.phpwill 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

EDIT II:以下 manual 命令可以解决问题: (所有本地更改都在“核心”子目录中)

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 rename git-filter-branch


【解决方案1】:

是的,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 mv ...”需要移动一切。我们有一个脚本,“php core/scripts/switch-psr4.php”,它将移动所有文件。所以如果我们把它放到filter-branch中,那么我们需要添加“php ...; git add -A .”,对吧?
  • 示例从何而来?那是哪个仓库?
  • 据我了解,在执行自定义命令之前,filter-branch 将始终“选择”下一个提交?这可能是错误的做法。它应该做的是“结帐”。提交,然后运行脚本。我希望我添加的图表有所帮助。
  • 示例存储库是 git 本身的存储库。除了git mv,您也可以只运行自己的脚本。 git help filter-branch 说:--tree-filter &lt;command&gt; This is the filter for rewriting the tree and its contents. The argument is evaluated in shell with the working directory set to the root of the checked out tree. The new tree is then used as-is (new files are auto-added, disappeared files are auto-removed.
【解决方案2】:

看来一个普通的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"

这可以通过一些交互式变基来增加趣味性,使其看起来好像本地添加的文件是直接在新位置创建的。

【讨论】:

    猜你喜欢
    • 2016-03-25
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 2020-04-04
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多