Skip to content

Build: restore deleted files preserving history#11064

Open
dmsnell wants to merge 28 commits intoWordPress:trunkfrom
dmsnell:build/restore-deleted-files-preserving-history
Open

Build: restore deleted files preserving history#11064
dmsnell wants to merge 28 commits intoWordPress:trunkfrom
dmsnell:build/restore-deleted-files-preserving-history

Conversation

@dmsnell
Copy link
Member

@dmsnell dmsnell commented Feb 26, 2026

The build change in #10638 removed many required files and added them to .gitignore. This led to WordPress crashing when loading wp-load.php until the npm run build:dev command was run.

Deleting these files had a number of deleterious side-effects:

  • They no longer appear in wordpress-develop, making it hard to see what code is going to run and hard to reference the files in places like Github where git CLI tools and the Gutenberg repo are not colocated and handy.
  • Any version-history for the files is lost, making it particularly difficult to examine how those files changed with the Gutenberg sync and update cycle, or how to track what ran at what version of WordPress.
  • Because of the missing history, this severely impacts the ability to debug issues or git bisect to find root cause and changes containing the root cause.
  • Any changes which are made to these files is untracked, making edits at high risk for being lost without any way to undo or revert. Previously, changes might be missed because they need to sync to Gutenberg, but after the build change, those edits never appear to warn someone that they edited the file in the wrong repo.
  • Benchmarking, debugging, and analysis flows which scan through the source control revisions now take 10x, 100x, 1000x longer to run because npm ci has to run, download more than 1 GB of npm packages, and rebuild all of the files on every git checkout. this practically eliminates the practicality of running workflows which assess the project over time.

This PR brings back those files and connects them to their pre-build-change version history by branching from a point in trunk immediately before the build change.

Although they were deleted in trunk, this patch, when applied as a merge commit will provide two parents which will allow any and all git tooling to reconstruct the history of the files without any special options or flags.

Status

This is ready for a full review.

As of the time of posting this, running npm run grunt gutenberg:download -- --force with this branch checked out leaves no changes or ignored changes in git, which suggests that every file which was changed has been accounted for.

dmsnell@Maximo ~/c/fix-the-build (build/restore-deleted-files-preserving-history)> git status --ignored
On branch build/restore-deleted-files-preserving-history
Your branch is up to date with 'origin/build/restore-deleted-files-preserving-history'.

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
	gutenberg/
	node_modules/
	packagehash.txt
restored-file-history.mp4

Note:

  • This must merge as a non-squashed commit, because the commit parent must be accessible to preserve history.
  • This needs to also come through in the svn-to-git conversion. If the merge is lost in that process then it won’t matter if this PR restores the history, because it will be lost when back-writing from the Subversion source.

Testing

Here is a sequence of events that simulates this operation. The script creates an SVN repo, adds some files and makes a few meaningless commits, then deletes a test.txt file.

There is a git svn mirror tracking the SVN repo.

From the SVN side, a new branch is created to restore the files. It is forked from before they were deleted and then the test.txt file is modified in a neutral way so that it will create a merge conflict. This is important because otherwise svn and git will automatically accept the deleted files as the truth.

That branch is merged in which tracks the version history for the files, because it maintains metadata pointing to the commits before they were deleted.

On the git svn side though it’s critical to first git svn fetch --all to retrieve the new branch (otherwise it will not have the metadata and therefore linearize the merge), and then to run git rebase --merge --rebase-merges so that it avoid linearizing the merge.

This has been confirmed and the svn branch fixes-64393-restore-version-history has already come over from svn into the git mirror — this should work as expected.

simulating-restore.mp4
#!/usr/bin/env bash

ROOT=$(pwd)
REPO=file://${ROOT}/svn-repo

printf "\e[90mStep \e[33m1\e[90m — create SVN repo\e[m\n"
svnadmin create svn-repo
svn mkdir ${REPO}/trunk -m "Create trunk"
svn mkdir ${REPO}/branches -m "Create branches"

printf "\e[90mStep \e[33m2\e[90m — load content into SVN checkout\e[m\n"
svn co ${REPO} svn-checkout
pushd svn-checkout/trunk
svn up ..
echo "Testing instructions" > test.txt
echo "1 2 3 4" > data.dat
echo "" > .gitignore
svn add test.txt data.dat .gitignore
svn commit -m "Initial commit"
popd

printf "\e[90mStep \e[33m3\e[90m — establish \e[2mgit\e[0;90m mirror\e[m\n"
git svn clone -T trunk -b branches ${REPO} git-repo

printf "\e[90mStep \e[33m4\e[90m — make noisy change\e[m\n"
pushd svn-checkout/trunk
echo "\n\n1. look at it" >> test.txt
echo " 5" >> data.dat
svn commit -m 'Expand testing'

echo "<?php\n\ndie();" > feature.php
svn add feature.php
svn commit -m 'Add feature skeleton'
svn up
popd

pushd git-repo
git svn rebase 
popd

printf "\e[90mStep \e[33m5\e[90m — remove test.txt\e[m\n"
pushd svn-checkout/trunk
svn rm test.txt
echo "/test.txt" > .gitignore
svn add .gitignore
svn propset svn:ignore -F .gitignore .
svn commit -m 'Remote tests'
popd

printf "\e[90mStep \e[33m6\e[90m — make more noisy commits\e[m\n"
pushd svn-checkout/trunk
echo "<?php\n\ndie(1);" > feature.php
svn commit -m 'Die abnormally'

echo "Are you lost?" > directions.html
svn add directions.html
svn commit -m 'Add directions'
svn up
popd

pushd git-repo
git svn rebase 
printf "\n\n\e[90mState of the git repo after deleting the tests\e[m\n"
git log --graph --topo-order --oneline
popd

printf "\n\e[90mPausing for review of the post-delete repo states.\e[m\n"
read

printf "\e[90mStep \e[33m7\e[90m — Branch before removal to restore\e[m\n"
pushd svn-checkout/trunk
svn copy -r5 ${REPO}/trunk ${REPO}/branches/restore-tests -m 'Restore tests (branch from f5 before removal)'
svn up ../
popd

pushd svn-checkout/branches/restore-tests
echo "\n" >> test.txt
echo "" > .gitignore
svn propset svn:ignore -F .gitignore .
svn commit -m 'Introduce merge conflict to force restoration'
svn up ../
popd

pushd git-repo
git svn rebase 
popd

printf "\e[90mStep \e[33m8\e[90m — Noisy commit\e[m\n"
pushd svn-checkout/trunk
echo "<?php\n\ndie(0);" > feature.php
svn commit -m 'Die normally'
svn up
popd

pushd git-repo
git svn rebase 
printf "\n\n\e[90mState of the git repo after noisy commits\e[m\n"
git log --graph --topo-order --oneline
popd

printf "\e[90mStep \e[33m9\e[90m — Merge branch and restore tests\e[m\n"
pushd svn-checkout/trunk
svn merge ${REPO}/branches/restore-tests --accept postpone
svn propdel svn:ignore test.txt
ls ../branches/restore-tests
cp ../branches/restore-tests/test.txt .
svn resolve --accept working test.txt
svn add test.txt
svn commit -m 'Merge and restore tests'
svn up ../
popd

pushd git-repo
git svn fetch --all
git svn rebase
printf "\n\n\e[90mState of the git repo after the merge\e[m\n"
git log --graph --topo-order --oneline --pretty='format:%h %cs %s'
popd

pushd git-repo
git svn fetch --all
git svn rebase
printf "\n\n\e[90m  ...and after calling propset to adjust the date\e[m\n"
git log --graph --topo-order --oneline --pretty='format:%h %cs %s'
popd

@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch from 04cdca9 to efc89d8 Compare March 10, 2026 01:33
@dmsnell
Copy link
Member Author

dmsnell commented Mar 10, 2026

I have force-pushed from 04cdca9 to efc89d8, which is a big change:

  • this branch is now based on the svn branch forked from before the build change
  • for every commit in trunk which updated the gutenberg.ref inside package.json (for every such one that also led to additions or modifications of PHP files that were otherwise excluded), a new commit restores those files as if they had never been added to .gitignore

@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch from 5cfaf68 to 29b508c Compare March 11, 2026 00:13
@dmsnell dmsnell marked this pull request as ready for review March 11, 2026 00:44
@github-actions
Copy link

github-actions bot commented Mar 11, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props dmsnell, youknowriad, ellatrix, adamsilverstein, desrosj, jonsurrell.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch from ef9bcb2 to 4220ecc Compare March 13, 2026 20:50
@dmsnell
Copy link
Member Author

dmsnell commented Mar 13, 2026

Changed branch HEAD from 29b508c to 4220ecc

This is to explore a new process to rebuild the branch. Details to come later, but I’m going to try and merge trunk into the branch at each sync-commit along the way.

@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch from 59e0a27 to 49093f1 Compare March 18, 2026 16:28
@dmsnell
Copy link
Member Author

dmsnell commented Mar 18, 2026

Recreated branch from previous 59e0a27 to new 49093f1

This time the creation was automated with the following script:

https://gist.github.com/dmsnell/c6f068e7f6028bacbfcb810d2fe726c2

@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch 3 times, most recently from b30d403 to 1c1cf17 Compare March 19, 2026 05:20
@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch from 1c1cf17 to 45aafcc Compare March 19, 2026 13:46
@sirreal
Copy link
Member

sirreal commented Mar 20, 2026

I picked a file that I expected to have a long history. The paragraph block.json. If I start at the HEAD of this branch and navigate to its earliest history, I reach dmsnell@f7d617c. If I start at an arbitrary place in Trac before the break in history (6.0) and navigate back, it traverses merges and ultimately arrives at the corresponding commit: https://core.trac.wordpress.org/browser/trunk/src/wp-includes/blocks/paragraph/block.json?rev=48262

That file doesn't exist at all in trunk right now.

It's a good indicator that this branch is an adequate solution to fixing history. 👍


I'm certainly missing some background, but I'd like to understand how this will work in practice.

Although they were deleted in trunk, this patch, when applied as a merge commit will provide two parents which will allow any and all git tooling to reconstruct the history of the files without any special options or flags.

Ultimately, things need to happen in subversion and then propagate to git mirrors from there. Work is committed with svn commit. Will this rely on git svn dcommit or something along those lines? Will a branch need to live on subversion permanently to hold these commits as a bridge from the current trunk revision back to the history-restoring point?

@dmsnell
Copy link
Member Author

dmsnell commented Mar 22, 2026

Ultimately, things need to happen in subversion and then propagate to git mirrors from there. Work is committed with svn commit. Will this rely on git svn dcommit or something along those lines? Will a branch need to live on subversion permanently to hold these commits as a bridge from the current trunk revision back to the history-restoring point?

Thanks @sirreal for your review and the question. This is something I wanted to ensure was simulated before merging, which you can see if you use the attached simulator script.

To the best of my knowledge, when subversion creates the merge with svn merge, then git svn rebase will create a merge commit, as long as the commits from the branch have been previously fetched with git svn fetch. We already have the branch created on the git side, so I am confident that as we commit the changes into the svn branch, they will carry over into git as well.

The final commit will be the merge commit itself, and since both of its parent’s will already by synced, we should have no problem seeing it created in git

My plan was to recreate the commits in svn first rather than using git svn dcommit but I believe we could use that approach too.

@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch from 865350f to e51421b Compare March 23, 2026 22:31
@dmsnell
Copy link
Member Author

dmsnell commented Mar 23, 2026

Recreated branch from 45aafcc to af434d6

@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch 5 times, most recently from a4d2abe to 20909b5 Compare March 24, 2026 02:06
dmsnell and others added 5 commits March 23, 2026 21:38
See changelog in 22294af

> Build: Update Gutenberg integration to checkout-and-build approach.
> This changes WordPress Core's Gutenberg integration from npm packages to checking out and building Gutenberg directly. Instead of syncing individual npm packages, Core now checks out the Gutenberg repository, builds it, and copies the build artifacts.
>
> This enables Core to use Gutenberg's advanced features like route-based navigation, full-page rendering, and the Font Library, while also streamlining future updates.
See changelog in 35313fa

> Build/Test Tools: Update Gutenberg hash to fix CSS minification.
> Updates the Gutenberg ref to include changes that generate both minified and non-minified CSS files during build. Previously, the build only produced a single CSS file (e.g., `style.css`), causing missing asset errors when `SCRIPT_DEBUG` is set to `false`, as Core expects `.min.css` files.
>
> Props peterwilsoncc, dd32, tyxla, jsnajdr, mcsf.
See changelog in 425bc36

> Build/Test Tools: Use --fast flag for Gutenberg builds.
> Adds the `--fast` flag to Gutenberg build commands, which skips TypeScript-related steps (version validation, `tsc --build`, and type declaration file checks) that aren't needed when building for WordPress Core. These steps only produce `.d.ts` files which aren't shipped with Core. Also updates the Gutenberg ref to include the commit that adds `--fast` flag support.
>
> The build times are now comparable to the build times we had using the npm packages.
youknowriad and others added 23 commits March 23, 2026 21:39
See changelog in e626725

> Build: Improve Gutenberg integration workflow.
> This changeset improves the Gutenberg build integration to simplify the developer workflow and reinstore a flow similar to how package dependencies worked before the Gutenberg checkout-and-build approach was introduced.
>
> Key improvements:
See changelog in f8b2285

> Gutenberg ref update.
> Updates unit tests to account for:
> - "Dynamically add CSS class to Paragraph block" (WordPress/gutenberg#71207)
> - New block server-side block registrations.
See changelog in b63a84b

> Gutenberg ref update.
> Developed in WordPress#10968.
>
> Props ellatrix, adamsilverstein, youknowriad.
See changelog in 0544d56

> Editor: backport client side media PHP changes to core.
> Bring over the changes required to implement client side media in core. This feature recently graduated from experiments and is ready for testing in beta.
>
> Props adamsilverstein, westonruter, mamaduka, mukesh27, swissspidy, andrewserong, ellatrix, ramonjd.
See changelog in f6927c8

> Gutenberg ref update.
> CI run: WordPress#10988.
>
> See #64595.
See changelog in f328908

> Gutenberg ref update.
> CI run: WordPress#11059.
>
> See #64595.
See changelog in e7d40e7

> Gutenberg ref update.
> CI run: WordPress#11167.
>
> See #64595.
See changelog in aaafdc0

> Gutenberg ref update.
> Only includes the following commit: WordPress/gutenberg@e7b8c0c.
>
> "Media: Use Document-Isolation-Policy for cross-origin isolation on Chromium 137+" (WordPress/gutenberg#75991)
See changelog in 8a7d2ce

> Gutenberg ref update.
> Only includes the following commit: WordPress/gutenberg@f4d8a58.
>
> "DataForm datetime control: fix date handling" (WordPress/gutenberg#76193)
See changelog in 63240d9

> Editor: Bump pinned hash for the Gutenberg repository.
> This updates the pinned hash from the `gutenberg` from `f4d8a5803aa2fbe26e7d9af4d17e80a622b7bab8` to `7b7fa2bc97a8029a302bd6511cf0d206b5953172`.
>
> The following changes are included:
See changelog in b80140a

> Editor: Bump pinned hash for the Gutenberg repository.
> This updates the pinned hash from the `gutenberg` from `7b7fa2bc97a8029a302bd6511cf0d206b5953172` to `9b8144036fa5faf75de43d4502ff9809fcf689ad`.
>
> The following changes are included:
See changelog in 49d8c11

> Build/Test Tools: Remove the requirement to clone/build Gutenberg.
> This iterates on the changes from [61438] by removing the need to:
> - Check out the WordPress/gutenberg repository at the pinned hash.
> - Run `npm install` within that checkout.
See changelog in 21d3c57

> Editor: Bump pinned hash for the Gutenberg repository.
> This updates the pinned hash from the `gutenberg` from `9b8144036fa5faf75de43d4502ff9809fcf689ad` to `8c78d87453509661a9f28f978ba2c242d515563b`.
>
> The following changes are included:
See changelog in 3678df3

> Editor: Bump pinned hash for the Gutenberg repository. This updates the pinned hash from the `gutenberg` from `8c78d87453509661a9f28f978ba2c242d515563b` to `487a096a9782ba6110a7686d7b4b2d0c55ed1b06`.
> The following changes are included:
>
> - Disables anchor support for the Page Break block. (WordPress/gutenberg#76434)
See changelog in 7ac6151

> Build/Test Tools: Stop generating unminified `.min` file.
> The generated `wp-includes/assets/script-loader-packages.min.php` and `wp-includes/assets/script-modules-packages.min.php` files are not actually minified. Additionally, the only purpose they serve is to pass a different script handle to the script loader (`.min.js` vs. `.js`).
>
> This eliminates the need for those files entirely since the difference in file size is negligible, and a human-readable version is more useful.
See changelog in 0af3431

> Editor: Bump pinned hash for the Gutenberg repository. This updates the pinned hash from the `gutenberg` from `487a096a9782ba6110a7686d7b4b2d0c55ed1b06` to `2ee7ede6be6d4e55d5c7047394c5c4e0ea8d521d`.
> The following changes are included:
>
> - RTC: Backport race condition fix (WordPress/gutenberg#76649)
See changelog in 19bef0e

> Build/Test Tools: Move icon library SVG files to `wp-includes/images`.
> This makes several changes to the build script to place the icon library files into more appropriate locations.
> - The icon library SVG files are now copied into the `wp-includes/images/icon-library` directory instead of `wp-includes/icons`.
> - The name of the `manifest.php` file has changed to `icon-library-manifest.php` and is now copied to `wp-includes/assets`.
See changelog in b00a9eb

> Build/Test Tools: Only include active, stable routes in build.
> The `registry.php` file within the built assets from the `gutenberg` repository contains an accurate list of active, stable routes. However, the `build/routes/` directory has the JavaScript and PHP files for all routes, regardless of their status.
>
> This makes adjustments to the `grunt copy` tasks responsible for copying these files into the appropriate locations to extract the list of routes specified in the `registry.php` file so that only the required files are copied.
@dmsnell dmsnell force-pushed the build/restore-deleted-files-preserving-history branch from c08fb34 to 618b73c Compare March 24, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants