Skip to content

Conversation

adamziel
Copy link
Collaborator

@adamziel adamziel commented Oct 15, 2025

Description

Adds a new feature to the git:directory Blueprint resource: the ability to create a functional, local .git directory alongside the checked-out files.

Rationale

Currently, the git:directory resource downloads the contents of a repository path, but it doesn't bring any of the Git metadata with it. This means that Git-aware tools (like the command line git, editor integrations, etc.) don't recognize the directory as a Git repository.

What's New?

A new boolean flag, ".git", has been added to the git:directory resource definition.

When you set ".git": true, the resource will create a .git directory containing:

  • A valid HEAD reference, pointing to the correct branch or commit.
  • A .git/config file configured with the remote origin and settings for a partial clone (promisor remote).
  • The necessary commit, tree, and blob objects stored as "loose" objects in .git/objects.
  • A complete .git/index file, ensuring the repository starts with a clean working tree.
  • Relevant refs in .git/refs/ for the checked-out branch and remote.
  • A .git/shallow file indicating the shallow clone depth.

Usage Examples

Before (Standard Behavior):

This blueprint downloads only the specified directory's files.

{
  "steps": [
    {
      "step": "writeFiles",
      "writeToPath": "/wordpress/wp-content/plugins/gutenberg",
      "filesTree": {
        "resource": "git:directory",
        "url": "https://github.com/WordPress/gutenberg.git",
        "ref": "trunk",
        "path": "packages/block-library/src/archives"
      }
    }
  ]
}

Resulting Files:

/wordpress/wp-content/plugins/gutenberg
├── block.json
├── editor.scss
└── index.php
...etc

After (With .git: true):

By adding the ".git": true flag, the blueprint now also creates the hidden .git directory, turning the destination into a working Git repository.

{
  "steps": [
    {
      "step": "writeFiles",
      "writeToPath": "/wordpress/wp-content/plugins/gutenberg",
      "filesTree": {
        "resource": "git:directory",
        "url": "https://github.com/WordPress/gutenberg.git",
        "ref": "trunk",
        "path": "packages/block-library/src/archives",
        ".git": true
      }
    }
  ]
}

Resulting Files:

/wordpress/wp-content/plugins/gutenberg
├── .git/
│   ├── HEAD
│   ├── config
│   ├── index
│   ├── objects/
│   └── refs/
├── block.json
├── editor.scss
└── index.php
...etc

With this new structure, you can now run git status inside the gutenberg directory and get a correct reading of the repository state.

Implementation Details

  • The underlying sparseCheckout function in @wp-playground/storage now returns not only the file contents (blobs) but also the raw Git objects (commits, trees) required to construct the repository history.
  • The created repository is a shallow, partial clone (git clone --depth=1 --filter=blob:none). It only downloads the objects necessary for the initial checkout, with the configuration to fetch more from the remote origin as needed.
  • The isomorphic-git library is used to programmatically build the .git/index file from the list of checked-out files and their corresponding object hashes.

Testing instructions

Create the following: blueprint.json file in your local Playground repository.

{
	"steps": [
		{
			"step": "installPlugin",
			"options": {
				"activate": true,
				"targetFolderName": "blocky-formats"
			},
			"pluginData": {
				"resource": "git:directory",
				"url": "https://github.com/dmsnell/blocky-formats.git",
				"ref": "trunk",
				"path": "",
				".git": true
			}
		}
	]
}

Then, run the Blueprint from the usage examples in local CI:

mkdir plugins
node --no-warnings=ExperimentalWarning  --experimental-strip-types --experimental-transform-types --import ./packages/meta/src/node-es-module-loader/register.mts ./packages/playground/cli/src/cli.ts server --xdebug --mount=
(pwd)/plugins:/wordpress/wp-content/plugins --blueprint=blueprint.json

Finally, confirm the repository was created as expected:

$ cd plugins/blocky-formats
$ git status
Twoja gałąź jest na bieżąco z „origin/trunk”.

$ rm blocky-formats.php
$ git status
Na gałęzi trunk
Twoja gałąź jest na bieżąco z „origin/trunk”.

Zmiany nie przygotowane do złożenia:
  (użyj „git add/rm <plik>...”, żeby zmienić, co zostanie złożone)
  (użyj „git restore <plik>...”, aby odrzucić zmiany w katalogu roboczym)
        usunięto:        blocky-formats.php

You should see status messages similar to those above.

@adamziel adamziel marked this pull request as ready for review October 16, 2025 20:28
@adamziel adamziel requested a review from a team as a code owner October 16, 2025 20:28
@adamziel adamziel merged commit a253fdd into trunk Oct 16, 2025
28 checks passed
@adamziel adamziel deleted the blueprint-.git-directory branch October 16, 2025 22:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants