Commit 0f29d3536a for wordpress.org

commit 0f29d3536ad923a05989595dfa3be28be0352bf9
Author: SergeyBiryukov <sergeybiryukov@git.wordpress.org>
Date:   Wed Nov 4 19:03:58 2026 +0000

    Upgrade/Install: Detect a `.git` file when checking for a VCS checkout.

    `WP_Automatic_Updater::is_vcs_checkout()` looks for `.git` with `is_dir()`, but in a Git worktree or submodule `.git` is a plain file that points to the real repository. When there's no `.git` directory higher up, the site is treated as not under version control and automatic updates run. The Site Health VCS test has its own copy of the same check.

    **What changes**

    - `is_vcs_checkout()` and `WP_Site_Health_Auto_Updates::test_vcs_abspath()` use `file_exists()` instead of `is_dir()`, so a `.git` file counts as a checkout.
    - The `.git` file isn't read to see where it points. In case of a Docker site running from a worktree, the path may be on the host and may not exist inside the container.
    - The `automatic_updates_is_vcs_checkout` filter still decides the result.

    Follow-up to r47835, r64586.

    Props dlocc.
    Fixes #66460.
    Built from https://develop.svn.wordpress.org/trunk@65259


    git-svn-id: http://core.svn.wordpress.org/trunk@64408 1a063a9b-81f0-0310-95a4-ce76da25c4cd

diff --git a/wp-admin/includes/class-wp-automatic-updater.php b/wp-admin/includes/class-wp-automatic-updater.php
index 65733ded88..d60507cd3c 100644
--- a/wp-admin/includes/class-wp-automatic-updater.php
+++ b/wp-admin/includes/class-wp-automatic-updater.php
@@ -192,6 +192,7 @@ class WP_Automatic_Updater {
 	 * how things get updated.
 	 *
 	 * @since 3.7.0
+	 * @since 7.2.0 Detects a `.git` file, as used by Git worktrees and submodules.
 	 *
 	 * @param string $context The filesystem path to check, in addition to ABSPATH.
 	 * @return bool True if a VCS checkout was discovered at `$context` or ABSPATH,
@@ -230,7 +231,8 @@ class WP_Automatic_Updater {
 					continue;
 				}

-				$checkout = is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" );
+				// In a Git worktree or submodule, `.git` is a file rather than a directory.
+				$checkout = file_exists( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" );
 				if ( $checkout ) {
 					break 2;
 				}
diff --git a/wp-admin/includes/class-wp-site-health-auto-updates.php b/wp-admin/includes/class-wp-site-health-auto-updates.php
index 3c0c8b3844..aeac6d1312 100644
--- a/wp-admin/includes/class-wp-site-health-auto-updates.php
+++ b/wp-admin/includes/class-wp-site-health-auto-updates.php
@@ -210,6 +210,7 @@ class WP_Site_Health_Auto_Updates {
 	 * Checks if WordPress is controlled by a VCS (Git, Subversion etc).
 	 *
 	 * @since 5.2.0
+	 * @since 7.2.0 Detects a `.git` file, as used by Git worktrees and submodules.
 	 *
 	 * @return array The test results.
 	 */
@@ -243,7 +244,8 @@ class WP_Site_Health_Auto_Updates {
 					continue;
 				}

-				$checkout = is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" );
+				// In a Git worktree or submodule, `.git` is a file rather than a directory.
+				$checkout = file_exists( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" );
 				if ( $checkout ) {
 					break 2;
 				}
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 75bfdd7c7e..927f30f21f 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.2-beta4-65258';
+$wp_version = '7.2-beta4-65259';

 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.