Background: I am working on a patch for Drupal core (PHP) where module class files that currently use PSR-0 will be moved two directories up, so they will use PSR-4 instead. This will make many people angry, because a lot of pending patches / local feature branches will need a re-roll. I would like to find a way to make this as painless as possible.
There is a big project with a public master branch, and a number of people having their own local feature branches.
On the master branch, we add a script that will move a bunch of files around. Every file that used to be in core/modules/$module/lib/Drupal/$module/Foo/Bar.php
will be moved two directories up, so it becomes core/modules/$module/lib/Foo/Bar.php
. This happens for every module, so $module can take a number of values.
The local feature branches can modify existing files, but they can also add new files or delete existing ones. They could even rename files. And all of this on the "old" directory structure.
Merge or rebase does in fact save a lot or all of the modifications over to the renamed file - although I am not sure it can be trusted 100%.
But the new files created will stay in the old location, and need to be moved manually.
A more reliable way would be to execute the script on the local branch, for every local commit that is not on master, and then somehow rebase the local branch.
The goal is to have a history where all the local commits look as if they had been done on the new file structure.
E.g. if a file was created in core/modules/views_ui/lib/Drupal/views_ui/NewClass.php
, then it should look like it had been created directly in core/modules/views_ui/lib/NewClass.php
What is the best way to automate all this?
Ideally I would provide a script for other developers that they can use without too much manual work.
git filter-branch seems promising, but I would need to use it in a very specific way.
EDIT: diagram to clarify
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: The following manual commands would do the trick: (all local changes are in a "core" subdirectory)
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"
It seems that a plain
git rebase
is actually not so bad!In the scenario in the diagram above, this would be
This can be spiced up with some interactive rebase, to make it appear as if locally added files had been created directly in their new location.