{"id":118090,"date":"2020-03-05T03:54:45","date_gmt":"2020-03-05T03:54:45","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/wp-branches-for-post\/"},"modified":"2026-09-19T06:17:32","modified_gmt":"2026-09-19T06:17:32","slug":"wp-branches-for-post","status":"publish","type":"plugin","link":"https:\/\/es-do.wordpress.org\/plugins\/wp-branches-for-post\/","author":17173373,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.0.0","stable_tag":"2.0.0","tested":"7.1.1","requires":"6.4","requires_php":"8.2","requires_plugins":null,"header_name":"WP Branches For Post","header_author":"Hao Kexin","header_description":"Creating branches of publishing post to modify and publish them without affecting them in Public","assets_banners_color":"0158b9","last_updated":"2026-09-19 06:17:32","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/hsxk\/WP-Branches-For-Post\/","header_author_uri":"https:\/\/time2log.com\/about\/","rating":0,"author_block_rating":0,"active_installs":50,"downloads":1903,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"2.0.0":{"tag":"2.0.0","author":"haokexin","date":"2026-09-19 06:17:32","revision":3702998}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3703142,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3703142,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3703142,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3703142,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["2.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3702998,"resolution":"1","location":"assets","locale":"","width":1440,"height":900},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3702998,"resolution":"2","location":"assets","locale":"","width":1440,"height":900},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3702998,"resolution":"3","location":"assets","locale":"","width":1440,"height":900},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3702998,"resolution":"4","location":"assets","locale":"","width":1440,"height":900}},"screenshots":{"1":"Block Editor panel on an original post, with a safe Create branch action.","2":"Editing an isolated branch with explicit Merge into original and Discard branch actions.","3":"Conflict protection when the original post changes after branch creation.","4":"Post list integration showing Create branch, Merge branch, and branch state."}},"plugin_section":[],"plugin_tags":[96456,148076,182664,3937,19979],"plugin_category":[],"plugin_contributors":[182665],"plugin_business_model":[],"class_list":["post-118090","plugin","type-plugin","status-publish","hentry","plugin_tags-editorial-workflow","plugin_tags-gutenberg","plugin_tags-post-branch","plugin_tags-revision","plugin_tags-staging","plugin_contributors-haokexin","plugin_committers-haokexin"],"banners":{"banner":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/banner-772x250.png?rev=3703142","banner_2x":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/banner-1544x500.png?rev=3703142","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/icon-128x128.png?rev=3703142","icon_2x":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/icon-256x256.png?rev=3703142","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/screenshot-1.png?rev=3702998","caption":"Block Editor panel on an original post, with a safe Create branch action."},{"src":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/screenshot-2.png?rev=3702998","caption":"Editing an isolated branch with explicit Merge into original and Discard branch actions."},{"src":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/screenshot-3.png?rev=3702998","caption":"Conflict protection when the original post changes after branch creation."},{"src":"https:\/\/ps.w.org\/wp-branches-for-post\/assets\/screenshot-4.png?rev=3702998","caption":"Post list integration showing Create branch, Merge branch, and branch state."}],"raw_content":"<!--section=description-->\n<p>WP Branches For Post provides a Git-like editorial workflow for WordPress content.<\/p>\n\n<p>Instead of editing a published post in place, create a draft branch. The public original remains unchanged while the branch is edited. When the work is ready, explicitly merge the branch back into the same original post ID.<\/p>\n\n<p>Version 2.0 modernizes the original 2020 plugin for the current WordPress block editor and REST API.<\/p>\n\n<h4>Core workflow<\/h4>\n\n<ol>\n<li>Open a published, private, or scheduled post\/page\/custom post type.<\/li>\n<li>Choose \"Create branch\".<\/li>\n<li>Edit the isolated draft branch.<\/li>\n<li>Review the branch status in the Post Branch panel.<\/li>\n<li>Merge into the original when ready.<\/li>\n<li>The original keeps its URL, ID, publication status, author, date, comments, and external identity.<\/li>\n<li>The merged branch is moved to Trash instead of being permanently deleted.<\/li>\n<\/ol>\n\n<h4>Safety<\/h4>\n\n<ul>\n<li>Branches are kept non-public and cannot accidentally replace the original by pressing WordPress Publish.<\/li>\n<li>Every new branch stores a snapshot of the original state.<\/li>\n<li>If the original changes after the branch was created, a normal merge is blocked.<\/li>\n<li>A force merge is available only as an explicit action after review.<\/li>\n<li>REST endpoints use WordPress capability checks in permission callbacks.<\/li>\n<li>The plugin no longer updates revisions or attachment parents with direct SQL.<\/li>\n<li>WordPress creates the normal revision history when the original post is updated.<\/li>\n<\/ul>\n\n<h4>What is synchronized<\/h4>\n\n<p>During merge, the plugin synchronizes editable post content, post meta, and all taxonomies while preserving the original post identity and publication state.<\/p>\n\n<p>Media IDs referenced by post content and featured-image meta remain the same. Attachments are not re-parented.<\/p>\n\n<h4>Block Editor<\/h4>\n\n<p>The Post Branch document panel shows:<\/p>\n\n<ul>\n<li>Create Branch on an original post.<\/li>\n<li>Existing active branches.<\/li>\n<li>Original post link from a branch.<\/li>\n<li>Conflict status.<\/li>\n<li>Merge into original.<\/li>\n<li>Force merge after review when a conflict exists.<\/li>\n<li>Discard branch.<\/li>\n<\/ul>\n\n<p>Classic Editor, post-list row actions, and the admin bar retain lightweight compatibility controls.<\/p>\n\n<h4>Compatibility with 1.x<\/h4>\n\n<p>Version 2.0 recognizes branches created by the 1.x metadata format.<\/p>\n\n<p>Legacy branches do not contain a baseline snapshot, so they are reported as \"unknown\" conflict state and require an explicit force merge after the original has been reviewed.<\/p>\n\n<p>The old automatic \"publish branch to overwrite original\" behavior has intentionally been removed.<\/p>\n\n<h3>About the Author<\/h3>\n\n<p>WP Branches For Post is maintained by Hao Kexin, a full-stack engineer and product builder based in Japan. Since 2018, his work has spanned requirements, system design, application development, data systems, deployment, observability, and long-term production operations.<\/p>\n\n<p>His current work focuses on public data, financial analysis, AI, and end-to-end product engineering. He builds and maintains projects including Time2Analyze, a production system for public-company disclosures, structured financial data, analysis, Excel, MCP, and AI workflows.<\/p>\n\n<p>More about the author and current projects: https:\/\/time2log.com\/about\/<\/p>\n\n<h3>Developer Notes<\/h3>\n\n<p>Useful filters and actions include:<\/p>\n\n<ul>\n<li><code>wbfp_branchable_post_statuses<\/code><\/li>\n<li><code>wbfp_create_branch_post_data<\/code><\/li>\n<li><code>wbfp_excluded_meta_keys<\/code><\/li>\n<li><code>wbfp_mergeable_post_fields<\/code><\/li>\n<li><code>wbfp_branch_created<\/code><\/li>\n<li><code>wbfp_before_merge<\/code><\/li>\n<li><code>wbfp_after_merge<\/code><\/li>\n<\/ul>\n\n<p>Security-critical invariants remain enforced after extension filters run: a new branch stays a draft of the same post type, required runtime meta stays excluded, and mergeable core fields are limited to the plugin's editorial allowlist.<\/p>\n\n<p>See <code>ARCHITECTURE.md<\/code> for the create\/merge data flow and <code>SECURITY.md<\/code> for authorization, CSRF, REST, conflict, and data-synchronization boundaries.<\/p>\n\n<p>CI is intentionally not triggered for every feature-branch commit. Full PHP\/build\/Plugin Check validation runs on <code>master<\/code>, release tags, or manual workflow dispatch.<\/p>\n\n<p>The Block Editor source is in <code>src\/index.js<\/code> and is built with <code>@wordpress\/scripts<\/code>.<\/p>\n\n<p>Human-readable source code and build tooling are maintained at https:\/\/github.com\/hsxk\/WP-Branches-For-Post\/.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>\/wp-content\/plugins\/wp-branches-for-post<\/code>, or install it through the WordPress Plugins screen.<\/li>\n<li>Activate WP Branches For Post.<\/li>\n<li>Open an existing published post and use the Post Branch panel or Create Branch action.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20a%20branch%20get%20a%20public%20url%3F\"><h3>Does a branch get a public URL?<\/h3><\/dt>\n<dd><p>No. A branch is an isolated working draft. Publishing a branch through the normal editor is prevented; use Merge into original instead.<\/p><\/dd>\n<dt id=\"does%20merging%20change%20the%20original%20url%20or%20post%20id%3F\"><h3>Does merging change the original URL or post ID?<\/h3><\/dt>\n<dd><p>No. The merge updates the existing original post record and preserves its identity, slug, publication state, author, and original dates.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20someone%20edits%20the%20original%20while%20i%20am%20working%20on%20a%20branch%3F\"><h3>What happens if someone edits the original while I am working on a branch?<\/h3><\/dt>\n<dd><p>The stored baseline snapshot no longer matches. The plugin marks the branch as conflicted and blocks the normal merge so newer work is not silently overwritten.<\/p><\/dd>\n<dt id=\"can%20i%20still%20merge%20an%20old%201.x%20branch%3F\"><h3>Can I still merge an old 1.x branch?<\/h3><\/dt>\n<dd><p>Yes, but because 1.x did not store a baseline snapshot, the plugin requires an explicit force merge after review.<\/p><\/dd>\n<dt id=\"does%20it%20support%20custom%20post%20types%3F\"><h3>Does it support custom post types?<\/h3><\/dt>\n<dd><p>Yes, when the user can edit the post and the post type uses the normal WordPress editing APIs. Taxonomies and post meta are synchronized with the branch.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Rebuilt the branch workflow for modern WordPress.<\/li>\n<li>Added Block Editor document sidebar integration.<\/li>\n<li>Added REST endpoints with capability-based permission callbacks.<\/li>\n<li>Added baseline snapshot conflict detection.<\/li>\n<li>Replaced publish-triggered merge with explicit merge actions.<\/li>\n<li>Prevented branch posts from becoming public.<\/li>\n<li>Reworked post meta synchronization to preserve multi-value keys and removals.<\/li>\n<li>Reworked taxonomy synchronization so cleared taxonomies are also propagated.<\/li>\n<li>Removed direct SQL revision and attachment-parent manipulation.<\/li>\n<li>Preserve original post ID, URL, status, author, slug, and publication dates during merge.<\/li>\n<li>Move merged\/discarded branches to Trash instead of permanently deleting them.<\/li>\n<li>Added compatibility handling for branches created by version 1.x.<\/li>\n<li>Added modern development tooling and CI syntax\/build checks.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Added developer filters and code cleanup.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Added zh_CN, zh_TW, and ja translations.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Added admin-bar\/list actions and initial block-editor support.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Create an isolated working branch for a published post, edit it safely, then explicitly merge it back into the original post.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/118090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=118090"}],"author":[{"embeddable":true,"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/haokexin"}],"wp:attachment":[{"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=118090"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=118090"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=118090"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=118090"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=118090"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/es-do.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=118090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}