Repository: ryangjchandler/orbit (php)

Issue:
::create() ignores default values of Blueprint.
If my Model has a column with a default value and I create a new Instance, it doesn't get saved in file. 

My Blueprint inside the Model:

```php
public static function schema(Blueprint $table)
{
    $table->string('title');
    $table->string('link');
    $table->string('author')->default('Max Mustermann');
}
```

The create Method:

```php
Article::create([
    'title' => 'Test',
    'link' => 'test-link'
]);
```

The generated file:

```yml
---
title: Test
link: test-link
---
```

What I expect: 

```yml
---
title: Test
link: test-link
author: Max Mustermann
---
```

It's weird because the sqlite cache actually works like expected and fills the author column with the default value. But the next time it's refreshed, I get a `Integrity constraint violation: 19 NOT NULL constraint failed. articles.author`

Feature request related to this issue: If a NOT NULL field has a default, don't make it mandatory to have it set in the file. Just return the default if it's missing.

Good package though, big fan of it.

Pull request:
feature: Laravel 9.x support
Updating to add support for Laravel 9.x.

Going to fix some bugs in this release too and tag v1.0.0.

Closes #82.

Patch:
diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml
index 282a520..4039659 100644
--- a/.github/workflows/php-cs-fixer.yml
+++ b/.github/workflows/php-cs-fixer.yml
@@ -1,29 +1,24 @@
-name: php-cs-fixer
+name: Check & fix styling
 
-on:
-    pull_request:
-        branches:
-            - master
-        types: [closed]
+on: [push]
 
 jobs:
-    php-cs-fixer:
-        runs-on: ubuntu-latest
-        if: github.event.pull_request.merged == true
-        steps:
-            - name: Checkout code
-              uses: actions/checkout@v2
-              with:
-                  ref: master
+  php-cs-fixer:
+    runs-on: ubuntu-latest
 
-            - name: Run PHP CS Fixer
-              uses: docker://oskarstark/php-cs-fixer-ga
-              with:
-                  args: --config=.php_cs.dist --allow-risky=yes
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v2
+        with:
+          ref: ${{ github.head_ref }}
 
-            - name: Commit changes
-              uses: stefanzweifel/git-auto-commit-action@v4
-              with:
-                  branch: master
-                  commit_message: >
-                      chore: styling
+      - name: Run PHP CS Fixer
+        uses: docker://oskarstark/php-cs-fixer-ga
+        with:
+          args: --config=.php_cs.dist.php --allow-risky=yes
+
+      - name: Commit changes
+        uses: stefanzweifel/git-auto-commit-action@v4
+        with:
+          commit_message: |
+            chore: styling
diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
new file mode 100644
index 0000000..19d6402
--- /dev/null
+++ b/.github/workflows/phpstan.yml
@@ -0,0 +1,26 @@
+name: PHPStan
+
+on:
+  push:
+    paths:
+      - '**.php'
+      - 'phpstan.neon.dist'
+
+jobs:
+  phpstan:
+    name: phpstan
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Setup PHP
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: '8.0'
+          coverage: none
+
+      - name: Install composer dependencies
+        uses: ramsey/composer-install@v1
+
+      - name: Run PHPStan
+        run: ./vendor/bin/phpstan --error-format=github
diff --git a/.gitignore b/.gitignore
index 4e963d4..a519338 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 composer.lock
 build
 .phpunit.result.cache
+*.cache
diff --git a/.php_cs.dist b/.php_cs.dist.php
similarity index 76%
rename from .php_cs.dist
rename to .php_cs.dist.php
index af24c29..8d8a790 100644
--- a/.php_cs.dist
+++ b/.php_cs.dist.php
@@ -2,9 +2,6 @@
 
 $finder = Symfony\Component\Finder\Finder::create()
     ->in([
-        __DIR__ . '/config',
-        __DIR__ . '/packages',
-        __DIR__ . '/routes',
         __DIR__ . '/src',
         __DIR__ . '/tests',
     ])
@@ -13,17 +10,14 @@ $finder = Symfony\Component\Finder\Finder::create()
     ->ignoreDotFiles(true)
     ->ignoreVCS(true);
 
-return PhpCsFixer\Config::create()
+return (new PhpCsFixer\Config())
     ->setRules([
-        '@PSR2' => true,
+        '@PSR12' => true,
         'array_syntax' => ['syntax' => 'short'],
         'ordered_imports' => ['sort_algorithm' => 'alpha'],
-        'ordered_class_elements' => [
-            'sort_algorithm' => 'alpha',
-        ],
         'no_unused_imports' => true,
         'not_operator_with_successor_space' => true,
-        'trailing_comma_in_multiline_array' => true,
+        'trailing_comma_in_multiline' => true,
         'phpdoc_scalar' => true,
         'unary_operator_spaces' => true,
         'binary_operator_spaces' => true,
@@ -34,9 +28,7 @@ return PhpCsFixer\Config::create()
         'phpdoc_var_without_name' => true,
         'class_attributes_separation' => [
             'elements' => [
-                'const' => 'one',
                 'method' => 'one',
-                'property' => 'one',
             ],
         ],
         'method_argument_space' => [
diff --git a/README.md b/README.md
index 34d1df3..67925a2 100644
--- a/README.md
+++ b/README.md
@@ -145,7 +145,6 @@ Out of the box, Orbit provides the following drivers:
 * `md` -> `Orbit\Drivers\Markdown`
 * `json` => `Orbit\Drivers\Json`
 * `yaml` => `Orbit\Drivers\Yaml`
-* `md_json` => `Orbit\Drivers\MarkdownJson`
 
 ### `md`
 
@@ -165,12 +164,6 @@ This is a JSON driver that is capable of parsing `.json` files. Each key in the
 
 This is a YAML driver that is capable of parsing `.yml` files. Each key in the file is mapped to a column in your schema.
 
-### `md_json`
-
-This driver is very similar to the `Markdown` / `md` driver, but it supports JSON-based front-matter as opposed to the default YAML format.
-
-> 💡 If you wish to customise the name of the `content` column, you can use the `MarkdownJson::contentColumn()` method and provide a new column name. This is applied to all models that use the `MarkdownJson` driver.
-
 ### Registering drivers
 
 You can register custom Orbit drivers by using the `Orbit::extend` method. You should call this method from the `boot` method in a `ServiceProvider`.
@@ -225,42 +218,3 @@ class Post extends Model
 ```
 
 > Driver names are determined when they are registered with Orbit. You should always use the string name of the driver instead of the fully-qualified class name.
-
-## Git Integration (experimental)
-
-Orbit comes with convenient Git integration out of the box. This means that any changes made to your content can be automatically persisted back to your Git repository, keeping everything up-to-date.
-
-To enable Git integration, define a new `ORBIT_GIT_ENABLED` environment variable in your `.env` file and set the value to `true`.
-
-### Events
-
-When Git integration is enabled, Orbit will add event listeners to the `OrbitalCreated`, `OrbitalUpdated` and `OrbitalDeleted` events and commit any changed files back to your repository.
-
-This is extremely powerful and can greatly improve your local - production workflows.
-
-### Customising the repository root
-
-By default, Orbit uses the `base_path` as your repositories root directory. If this is not applicable to your application, you can change the path by defining an `ORBIT_GIT_ROOT` environment variable and setting it's value to the root of your Git repository.
-
-### Customising the author name and email
-
-By default, Orbit will use the system's name and email address when making commits to your repository. If you wish to change the name, use the `ORBIT_GIT_NAME` and `ORBIT_GIT_EMAIL` environment variables.
-
-If you would like to use a more dynamic name and email address, you can use the `Orbit::resolveGitNameUsing` and `Orbit::resolveGitEmailUsing` methods instead:
-
-```php
-public function boot()
-{
-    Orbit::resolveGitNameUsing(function () {
-        return Auth::user()->name;
-    });
-
-    Orbit::resolveGitEmailUsing(function () {
-        return Auth::user()->email;
-    });
-}
-```
-
-### Customising the Git binary
-
-If your Git binary is not found in the usual place (`/usr/bin/git` on most UNIX machines), you can customise the location using the `ORBIT_GIT_BINARY` environment variable.
diff --git a/composer.json b/composer.json
index 8eb75fa..033f6cb 100644
--- a/composer.json
+++ b/composer.json
@@ -11,20 +11,22 @@
         }
     ],
     "require": {
-        "php": "^7.4 || ^8.0",
+        "php": "^8.0",
         "ext-json": "*",
-        "illuminate/console": "^8.0",
-        "illuminate/database": "^8.0",
-        "illuminate/events": "^8.0",
-        "illuminate/support": "^8.0",
-        "ryangjchandler/git": "^0.0.4",
+        "illuminate/console": "^9.0",
+        "illuminate/database": "^9.0",
+        "illuminate/events": "^9.0",
+        "illuminate/support": "^9.0",
+        "nunomaduro/larastan": "^1.0",
+        "phpstan/extension-installer": "^1.1",
+        "phpstan/phpstan-deprecation-rules": "^1.0",
+        "phpstan/phpstan-phpunit": "^1.0",
         "spatie/yaml-front-matter": "^2.0",
-        "symfony/yaml": "^3.0 || ^4.0 || ^5.0"
+        "symfony/yaml": "^6.0"
     },
     "require-dev": {
-        "orchestra/testbench": "^6.15",
-        "phpunit/phpunit": "9.4.*",
-        "vimeo/psalm": "^4.6"
+        "orchestra/testbench": "^7.0",
+        "phpunit/phpunit": "^9.0"
     },
     "extra": {
         "laravel": {
@@ -46,7 +48,7 @@
     "minimum-stability": "dev",
     "prefer-stable": true,
     "scripts": {
-        "psalm": "vendor/bin/psalm",
+        "lint": "vendor/bin/phpstan analyse",
         "test": "vendor/bin/phpunit --colors=always"
     },
     "config": {
diff --git a/config/orbit.php b/config/orbit.php
index ca793ca..82c7fe7 100644
--- a/config/orbit.php
+++ b/config/orbit.php
@@ -8,7 +8,6 @@ return [
         'md' => \Orbit\Drivers\Markdown::class,
         'json' => \Orbit\Drivers\Json::class,
         'yaml' => \Orbit\Drivers\Yaml::class,
-        'md_json' => \Orbit\Drivers\MarkdownJson::class,
     ],
 
     'paths' => [
@@ -16,13 +15,4 @@ return [
         'cache' => storage_path('framework/cache/orbit'),
     ],
 
-    'git' => [
-        'enabled' => env('ORBIT_GIT_ENABLED', false),
-        'name' => env('ORBIT_GIT_NAME'),
-        'email' => env('ORBIT_GIT_EMAIL'),
-        'root' => env('ORBIT_GIT_ROOT', base_path()),
-        'binary' => env('ORBIT_GIT_BINARY', '/usr/bin/git'),
-        'message_template' => 'orbit: {event} {model} {primary_key}'
-    ],
-
 ];
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
new file mode 100644
index 0000000..e69de29
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..90a0254
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,12 @@
+includes:
+    - phpstan-baseline.neon
+
+parameters:
+    level: 5
+    paths:
+        - src
+        - config
+    tmpDir: build/phpstan
+    checkOctaneCompatibility: true
+    checkModelProperties: true
+    checkMissingIterableValueType: false
diff --git a/psalm.xml.dist b/psalm.xml.dist
deleted file mode 100644
index c6df33e..0000000
--- a/psalm.xml.dist
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<psalm
-    errorLevel="4"
-    findUnusedVariablesAndParams="true"
-    resolveFromConfigFile="true"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xmlns="https://getpsalm.org/schema/config"
-    xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
->
-    <projectFiles>
-        <directory name="src"/>
-        <ignoreFiles>
-            <directory name="vendor"/>
-        </ignoreFiles>
-    </projectFiles>
-</psalm>
diff --git a/src/Actions/ClearCache.php b/src/Actions/ClearCache.php
new file mode 100644
index 0000000..1682a3c
--- /dev/null
+++ b/src/Actions/ClearCache.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Orbit\Actions;
+
+use Orbit\Facades\Orbit;
+
+/** @internal */
+class ClearCache
+{
+    public function __invoke(): void
+    {
+        $path = Orbit::getDatabasePath();
+
+        if (! file_exists($path)) {
+            return;
+        }
+
+        unlink($path);
+    }
+}
diff --git a/src/Commands/ClearCommand.php b/src/Commands/ClearCommand.php
index 70fa34f..d692a36 100644
--- a/src/Commands/ClearCommand.php
+++ b/src/Commands/ClearCommand.php
@@ -3,6 +3,7 @@
 namespace Orbit\Commands;
 
 use Illuminate\Console\Command;
+use Orbit\Actions\ClearCache;
 use Orbit\Facades\Orbit;
 
 class ClearCommand extends Command
@@ -17,13 +18,15 @@ class ClearCommand extends Command
             return 0;
         }
 
-        $path = Orbit::getDatabasePath();
+        $confirm = $this->confirm('Are you sure you want to delete Orbit\'s cache file?');
+
+        if (! $confirm) {
+            $this->warn('Cancelling...');
 
-        if (! file_exists($path)) {
             return 0;
         }
 
-        unlink($path);
+        (new ClearCache())();
 
         $this->info('Succesfully cleared the Orbit cache.');
 
diff --git a/src/Commands/CommitCommand.php b/src/Commands/CommitCommand.php
deleted file mode 100644
index ffb1795..0000000
--- a/src/Commands/CommitCommand.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-namespace Orbit\Commands;
-
-use Error;
-use Orbit\Facades\Orbit;
-use RyanChandler\Git\Git;
-use Illuminate\Console\Command;
-use Symfony\Component\Process\Exception\ProcessFailedException;
-
-class CommitCommand extends Command
-{
-    protected $signature = 'orbit:commit {message?}';
-
-    protected $description = 'Commit and push Orbit content changes to Git.';
-
-    public function handle()
-    {
-        if (Orbit::isTesting()) {
-            return 0;
-        }
-
-        /** @var \RyanChandler\Git\Git $git */
-        $git = Git::open(
-            Orbit::getGitRoot()
-        );
-
-        $git->add(
-            config('orbit.paths.content')
-        );
-
-        try {
-            $git->commit(
-                $this->argument('message') ?? 'orbit: changes committed manually'
-            );
-        } catch (ProcessFailedException $e) {
-            $this->error('Failed to commit changes. [Message] ' . $e->getMessage());
-
-            return 1;
-        }
-
-        $git->push();
-
-        $this->info('Succesfully committed and pushed the latest Orbit content changes.');
-
-        return 0;
-    }
-}
diff --git a/src/Commands/FreshCommand.php b/src/Commands/FreshCommand.php
index 85a1054..af76f90 100644
--- a/src/Commands/FreshCommand.php
+++ b/src/Commands/FreshCommand.php
@@ -14,7 +14,15 @@ class FreshCommand extends Command
 
     public function handle()
     {
-        (new Filesystem)->deleteDirectory(
+        $confirm = $this->confirm('Are you sure you want to remove all existing Orbit data?');
+
+        if (! $confirm) {
+            $this->warn('Cancelling...');
+
+            return 0;
+        }
+
+        (new Filesystem())->deleteDirectory(
             Orbit::getContentPath()
         );
 
diff --git a/src/Commands/GenerateCommand.php b/src/Commands/GenerateCommand.php
index 11007a6..f381643 100644
--- a/src/Commands/GenerateCommand.php
+++ b/src/Commands/GenerateCommand.php
@@ -2,11 +2,11 @@
 
 namespace Orbit\Commands;
 
-use Illuminate\Support\Str;
 use Illuminate\Console\Command;
-use Illuminate\Support\Collection;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Schema\ColumnDefinition;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Str;
 
 class GenerateCommand extends Command
 {
@@ -50,7 +50,7 @@ class GenerateCommand extends Command
 
         return collect($blueprint->getColumns())->mapWithKeys(function (ColumnDefinition $column): array {
             return [
-                $column->getAttributes()['name'] => $column
+                $column->getAttributes()['name'] => $column,
             ];
         });
     }
diff --git a/src/Commands/PullCommand.php b/src/Commands/PullCommand.php
deleted file mode 100644
index d4f3763..0000000
--- a/src/Commands/PullCommand.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-namespace Orbit\Commands;
-
-use Orbit\Facades\Orbit;
-use RyanChandler\Git\Git;
-use Illuminate\Console\Command;
-
-class PullCommand extends Command
-{
-    protected $name = 'orbit:pull';
-
-    protected $description = 'Pull the latest Git changes.';
-
-    public function handle()
-    {
-        if (Orbit::isTesting() || ! config('orbit.git.enabled')) {
-            return 0;
-        }
-
-        /** @var \RyanChandler\Git\Git $git */
-        $git = Git::open(
-            Orbit::getGitRoot()
-        );
-
-        $git->pull();
-
-        $this->info('Succesfully pulled the latest changes from Git.');
-
-        $path = Orbit::getDatabasePath();
-
-        if (! file_exists($path)) {
-            return 0;
-        }
-
-        unlink($path);
-
-        $this->info('Succesfully cleared the Orbit cache.');
-
-        return 0;
-    }
-}
diff --git a/src/Concerns/Orbital.php b/src/Concerns/Orbital.php
index 9ecdf39..068e70d 100644
--- a/src/Concerns/Orbital.php
+++ b/src/Concerns/Orbital.php
@@ -2,17 +2,15 @@
 
 namespace Orbit\Concerns;
 
-use Illuminate\Database\Connectors\ConnectionFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Schema\Blueprint;
-use Orbit\Facades\Orbit;
-use Illuminate\Support\Str;
 use Illuminate\Filesystem\Filesystem;
 use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Schema;
+use Illuminate\Support\Str;
 use Orbit\Events\OrbitalCreated;
 use Orbit\Events\OrbitalDeleted;
 use Orbit\Events\OrbitalUpdated;
+use Orbit\Facades\Orbit;
 use ReflectionClass;
 
 trait Orbital
@@ -30,9 +28,9 @@ trait Orbital
             Orbit::isTesting() ||
             filemtime($modelFile) > filemtime(Orbit::getDatabasePath()) ||
             $driver->shouldRestoreCache(static::getOrbitalPath()) ||
-            ! static::resolveConnection()->getSchemaBuilder()->hasTable((new static)->getTable())
+            ! static::resolveConnection()->getSchemaBuilder()->hasTable((new static())->getTable())
         ) {
-            (new static)->migrate();
+            (new static())->migrate();
         }
 
         static::created(function (Model $model) {
@@ -40,12 +38,16 @@ trait Orbital
                 return;
             }
 
+            // We need to refresh the model so that we can get all of the columns
+            // and default values from the SQLite cache.
+            $model->refresh();
+
             $status = Orbit::driver(static::getOrbitalDriver())->save(
                 $model,
                 static::getOrbitalPath()
             );
 
-            OrbitalCreated::dispatch($model);
+            event(new OrbitalCreated($model));
 
             return $status;
         });
@@ -60,7 +62,7 @@ trait Orbital
                 static::getOrbitalPath()
             );
 
-            OrbitalUpdated::dispatch($model);
+            event(new OrbitalUpdated($model));
 
             return $status;
         });
@@ -75,7 +77,7 @@ trait Orbital
                 static::getOrbitalPath()
             );
 
-            OrbitalDeleted::dispatch($model);
+            event(new OrbitalDeleted($model));
 
             return $status;
         });
@@ -157,7 +159,7 @@ trait Orbital
 
     protected static function ensureOrbitDirectoriesExist()
     {
-        $fs = new Filesystem;
+        $fs = new Filesystem();
 
         $fs->ensureDirectoryExists(
             static::getOrbitalPath()
diff --git a/src/Concerns/SoftDeletes.php b/src/Concerns/SoftDeletes.php
index 1f05adc..fec5b04 100644
--- a/src/Concerns/SoftDeletes.php
+++ b/src/Concerns/SoftDeletes.php
@@ -2,15 +2,15 @@
 
 namespace Orbit\Concerns;
 
-use Orbit\Facades\Orbit;
-use Orbit\Events\OrbitalDeleted;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes as EloquentSoftDeletes;
+use Illuminate\Database\Eloquent\SoftDeletingScope;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Schema\ColumnDefinition;
-use Illuminate\Database\Eloquent\SoftDeletingScope;
-use Illuminate\Database\Eloquent\SoftDeletes as EloquentSoftDeletes;
+use Orbit\Events\OrbitalDeleted;
 use Orbit\Events\OrbitalForceDeleted;
 use Orbit\Events\OrbitalUpdated;
+use Orbit\Facades\Orbit;
 
 trait SoftDeletes
 {
@@ -18,24 +18,26 @@ trait SoftDeletes
 
     public static function bootSoftDeletes()
     {
-        static::addGlobalScope(new SoftDeletingScope);
+        static::addGlobalScope(new SoftDeletingScope());
 
         static::deleted(function (Model $model) {
             $status = Orbit::driver(static::getOrbitalDriver())->save(
-                $model, static::getOrbitalPath()
+                $model,
+                static::getOrbitalPath()
             );
 
-            OrbitalDeleted::dispatch($model);
+            event(new OrbitalDeleted($model));
 
             return $status;
         });
 
         static::restored(function (Model $model) {
             $status = Orbit::driver(static::getOrbitalDriver())->save(
-                $model, static::getOrbitalPath()
+                $model,
+                static::getOrbitalPath()
             );
 
-            OrbitalUpdated::dispatch($model);
+            event(new OrbitalUpdated($model));
 
             return $status;
         });
@@ -50,7 +52,7 @@ trait SoftDeletes
                 static::getOrbitalPath()
             );
 
-            OrbitalForceDeleted::dispatch($model);
+            event(new OrbitalForceDeleted($model));
 
             return $status;
         });
diff --git a/src/Drivers/FileDriver.php b/src/Drivers/FileDriver.php
index b95d8e0..d019f2c 100644
--- a/src/Drivers/FileDriver.php
+++ b/src/Drivers/FileDriver.php
@@ -5,8 +5,8 @@ namespace Orbit\Drivers;
 use FilesystemIterator;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Collection;
-use Orbit\Facades\Orbit;
 use Orbit\Contracts\Driver as DriverContract;
+use Orbit\Facades\Orbit;
 use SplFileInfo;
 
 abstract class FileDriver implements DriverContract
@@ -54,7 +54,9 @@ abstract class FileDriver implements DriverContract
         $files = new FilesystemIterator($directory);
 
         foreach ($files as $file) {
-            if ($file->getExtension() !== $this->extension()) continue;
+            if ($file->getExtension() !== $this->extension()) {
+                continue;
+            }
 
             $collection->push($this->parseContent($file));
         }
diff --git a/src/Drivers/MarkdownJson.php b/src/Drivers/MarkdownJson.php
deleted file mode 100644
index 1c85079..0000000
--- a/src/Drivers/MarkdownJson.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-namespace Orbit\Drivers;
-
-use SplFileInfo;
-use Illuminate\Database\Eloquent\Model;
-use Spatie\YamlFrontMatter\YamlFrontMatter;
-
-class MarkdownJson extends Markdown
-{
-    protected function dumpContent(Model $model): string
-    {
-        $matter = array_filter($this->getModelAttributes($model), function ($value, $key) {
-            return $key !== 'content' && $value !== null;
-        }, ARRAY_FILTER_USE_BOTH);
-
-        $json = json_encode($matter, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
-
-        return implode(PHP_EOL, [
-            '---',
-            rtrim($json, PHP_EOL),
-            '---',
-            $model->getAttribute('content'),
-        ]);
-    }
-
-    protected function parseContent(SplFileInfo $file): array
-    {
-        $content = file_get_contents($file->getPathname());
-
-        $pattern = '/^[\s\r\n]?---[\s\r\n]?$/sm';
-
-        $parts = preg_split($pattern, PHP_EOL . ltrim($content));
-
-        $matter = count($parts) < 3 ? [] : json_decode(trim($parts[1]), true);
-
-        $body = implode(PHP_EOL.'---'.PHP_EOL, array_slice($parts, 2));
-
-        return array_merge(
-            $matter,
-            ['content' => trim($body)]
-        );
-    }
-}
diff --git a/src/Facades/Orbit.php b/src/Facades/Orbit.php
index 6940bd5..7f184b3 100644
--- a/src/Facades/Orbit.php
+++ b/src/Facades/Orbit.php
@@ -3,20 +3,15 @@
 namespace Orbit\Facades;
 
 use Illuminate\Support\Facades\Facade;
+use Orbit\OrbitManager;
 
 /**
  * @method static \Orbit\Contracts\Driver driver(string|null $driver)
  * @method static \Orbit\OrbitManager extend(string $driver, \Closure $callback)
- * @method static \Orbit\OrbitManager resolveGitNameUsing(\Closure $callback)
- * @method static \Orbit\OrbitManager resolveGitEmailUsing(\Closure $callback)
  * @method static array getDrivers()
  * @method static string getDefaultDriver()
  * @method static string getDatabasePath()
  * @method static string getContentPath()
- * @method static string getGitName()
- * @method static string getGitEmail()
- * @method static string getGitRoot()
- * @method static string getGitBinary()
  * @method static \Orbit\OrbitManager test()
  * @method static bool isTesting()
  *
@@ -26,6 +21,6 @@ class Orbit extends Facade
 {
     protected static function getFacadeAccessor()
     {
-        return 'orbit';
+        return OrbitManager::class;
     }
 }
diff --git a/src/Listeners/ProcessGitTransaction.php b/src/Listeners/ProcessGitTransaction.php
deleted file mode 100644
index 435d140..0000000
--- a/src/Listeners/ProcessGitTransaction.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-
-namespace Orbit\Listeners;
-
-use Orbit\Events\OrbitalCreated;
-use Orbit\Events\OrbitalDeleted;
-use Orbit\Events\OrbitalForceDeleted;
-use Orbit\Events\OrbitalUpdated;
-use Orbit\Facades\Orbit;
-use RyanChandler\Git\Git;
-use Symplify\GitWrapper\GitWrapper;
-
-class ProcessGitTransaction
-{
-    public function created(OrbitalCreated $event)
-    {
-        $this->commit([
-            'event' => 'created',
-            'model' => class_basename($event->model),
-            'primary_key' => $event->model->getKey(),
-        ]);
-    }
-
-    public function updated(OrbitalUpdated $event)
-    {
-        $this->commit([
-            'event' => 'updated',
-            'model' => class_basename($event->model),
-            'primary_key' => $event->model->getKey(),
-        ]);
-    }
-
-    public function deleted($event)
-    {
-        $this->commit([
-            'event' => $event instanceof OrbitalForceDeleted ? 'force deleted' : 'deleted',
-            'model' => class_basename($event->model),
-            'primary_key' => $event->model->getKey(),
-        ]);
-    }
-
-    protected function commit(array $keys)
-    {
-        /** @var \RyanChandler\Git\Git $git */
-        $git = Git::open(
-            Orbit::getGitRoot()
-        );
-
-        if (! $git->hasChanges()) {
-            return;
-        }
-
-        $git->add(
-            config('orbit.paths.content')
-        );
-
-        $message = config('orbit.git.message_template');
-
-        foreach ($keys as $search => $replacement) {
-            $message = str_replace("{{$search}}", $replacement, $message);
-        }
-
-        $git->commit($message);
-
-        $git->push();
-    }
-}
diff --git a/src/OrbitManager.php b/src/OrbitManager.php
index 4db29ea..6429318 100644
--- a/src/OrbitManager.php
+++ b/src/OrbitManager.php
@@ -2,18 +2,13 @@
 
 namespace Orbit;
 
-use Closure;
-use Illuminate\Support\Manager;
 use Illuminate\Support\Facades\App;
+use Illuminate\Support\Manager;
 
 class OrbitManager extends Manager
 {
     protected $testing = false;
 
-    protected Closure $resolveGitName;
-
-    protected Closure $resolveGitEmail;
-
     public function test()
     {
         $this->testing = true;
@@ -44,46 +39,4 @@ class OrbitManager extends Manager
     {
         return config('orbit.paths.content');
     }
-
-    public function resolveGitNameUsing(Closure $callback)
-    {
-        $this->resolveGitName = $callback;
-
-        return $this;
-    }
-
-    public function resolveGitEmailUsing(Closure $callback)
-    {
-        $this->resolveGitEmail = $callback;
-
-        return $this;
-    }
-
-    public function getGitName()
-    {
-        if ($this->resolveGitName) {
-            return value($this->resolveGitName);
-        }
-
-        return config('orbit.git.name');
-    }
-
-    public function getGitEmail()
-    {
-        if ($this->resolveGitEmail) {
-            return value($this->resolveGitEmail);
-        }
-
-        return config('orbit.git.email');
-    }
-
-    public function getGitRoot()
-    {
-        return config('orbit.git.root');
-    }
-
-    public function getGitBinary()
-    {
-        return config('orbit.git.binary');
-    }
 }
diff --git a/src/OrbitServiceProvider.php b/src/OrbitServiceProvider.php
index 8f11da7..af37dee 100644
--- a/src/OrbitServiceProvider.php
+++ b/src/OrbitServiceProvider.php
@@ -3,17 +3,14 @@
 namespace Orbit;
 
 use Exception;
+use Illuminate\Database\Events\DatabaseRefreshed;
 use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Schema\ColumnDefinition;
 use Illuminate\Support\Facades\Event;
 use Illuminate\Support\ServiceProvider;
+use Orbit\Actions\ClearCache;
 use Orbit\Contracts\Driver;
-use Orbit\Events\OrbitalCreated;
-use Orbit\Events\OrbitalDeleted;
-use Orbit\Events\OrbitalForceDeleted;
-use Orbit\Events\OrbitalUpdated;
 use Orbit\Facades\Orbit;
-use Orbit\Listeners\ProcessGitTransaction;
 
 class OrbitServiceProvider extends ServiceProvider
 {
@@ -21,7 +18,7 @@ class OrbitServiceProvider extends ServiceProvider
     {
         $this->mergeConfigFrom(__DIR__.'/../config/orbit.php', 'orbit');
 
-        $this->app->singleton('orbit', function ($app) {
+        $this->app->scoped(OrbitManager::class, function ($app) {
             $manager = new OrbitManager($app);
 
             foreach ($this->app['config']->get('orbit.drivers') as $key => $driver) {
@@ -52,8 +49,6 @@ class OrbitServiceProvider extends ServiceProvider
             $this->commands([
                 Commands\ClearCommand::class,
                 Commands\FreshCommand::class,
-                Commands\PullCommand::class,
-                Commands\CommitCommand::class,
                 Commands\GenerateCommand::class,
             ]);
 
@@ -62,12 +57,7 @@ class OrbitServiceProvider extends ServiceProvider
             ], 'orbit:config');
         }
 
-        if ($this->app['config']->get('orbit.git.enabled')) {
-            Event::listen(OrbitalCreated::class, [ProcessGitTransaction::class, 'created']);
-            Event::listen(OrbitalUpdated::class, [ProcessGitTransaction::class, 'updated']);
-            Event::listen(OrbitalDeleted::class, [ProcessGitTransaction::class, 'deleted']);
-            Event::listen(OrbitalForceDeleted::class, [ProcessGitTransaction::class, 'deleted']);
-        }
+        Event::listen(DatabaseRefreshed::class, ClearCache::class);
 
         Blueprint::macro('hasColumn', function (string $name): bool {
             /** @var \Illuminate\Database\Schema\Blueprint $this */


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 3a0ca2e..20cb90a 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -9,12 +9,12 @@ jobs:
       fail-fast: true
       matrix:
         os: [ubuntu-latest, windows-latest]
-        php: [7.4, 8.0]
-        laravel: [8.*]
+        php: [8.0]
+        laravel: [9.*]
         stability: [prefer-lowest, prefer-stable]
         include:
-          - laravel: 8.*
-            testbench: 6.*
+          - laravel: 9.*
+            testbench: 7.*
 
     name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
 
diff --git a/tests/AdvancedOrbitalTest.php b/tests/AdvancedOrbitalTest.php
index a1779bd..af79947 100644
--- a/tests/AdvancedOrbitalTest.php
+++ b/tests/AdvancedOrbitalTest.php
@@ -2,10 +2,9 @@
 
 namespace Orbit\Tests;
 
-use Orbit\Tests\Fixtures\Post;
 use Orbit\Tests\Fixtures\CustomKey;
 use Orbit\Tests\Fixtures\JsonModel;
-use Orbit\Tests\Fixtures\MarkdownJsonModel;
+use Orbit\Tests\Fixtures\Post;
 use Orbit\Tests\Fixtures\YamlModel;
 
 class AdvancedOrbitalTest extends TestCase
@@ -61,15 +60,6 @@ class AdvancedOrbitalTest extends TestCase
         $this->assertFileExists(__DIR__.'/content/yaml_models/'.$yaml->getKey().'.yml');
     }
 
-    public function test_it_can_use_markdown_json_driver()
-    {
-        $md = MarkdownJsonModel::create([
-            'name' => 'Ryan',
-        ]);
-
-        $this->assertFileExists(__DIR__.'/content/markdown_json_models/'.$md->getKey().'.md');
-    }
-
     public function test_it_writes_hidden_columns()
     {
         $post = Post::create([
diff --git a/tests/BasicOrbitalTest.php b/tests/BasicOrbitalTest.php
index 8895613..91e588a 100644
--- a/tests/BasicOrbitalTest.php
+++ b/tests/BasicOrbitalTest.php
@@ -2,8 +2,8 @@
 
 namespace Orbit\Tests;
 
-use Orbit\Tests\Fixtures\Post;
 use Orbit\Tests\Fixtures\Emptiness;
+use Orbit\Tests\Fixtures\Post;
 
 class BasicOrbitalTest extends TestCase
 {
diff --git a/tests/ClearCacheTest.php b/tests/ClearCacheTest.php
new file mode 100644
index 0000000..eb490d2
--- /dev/null
+++ b/tests/ClearCacheTest.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Orbit\Tests;
+
+use Illuminate\Database\Events\DatabaseRefreshed;
+use Illuminate\Support\Facades\Event;
+use Orbit\Actions\ClearCache;
+
+class ClearCacheTest extends TestCase
+{
+    public function test_it_clears_orbit_cache_when_migrating_fresh()
+    {
+        Event::fake();
+        Event::assertListening(DatabaseRefreshed::class, ClearCache::class);
+    }
+}
diff --git a/tests/DefaultDatabaseValuesTest.php b/tests/DefaultDatabaseValuesTest.php
new file mode 100644
index 0000000..2376415
--- /dev/null
+++ b/tests/DefaultDatabaseValuesTest.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Orbit\Tests;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Schema\Blueprint;
+use Orbit\Concerns\Orbital;
+
+class DefaultValues extends Model
+{
+    use Orbital;
+
+    protected $guarded = [];
+
+    public static function schema(Blueprint $table)
+    {
+        $table->bigIncrements('id');
+        $table->string('name');
+        $table->string('email')->default('foo@test.com');
+    }
+}
+
+class DefaultDatabaseValuesTest extends TestCase
+{
+    protected function tearDown(): void
+    {
+        DefaultValues::all()->each->delete();
+    }
+
+    public function test_default_values_are_stored_on_disk()
+    {
+        $model = DefaultValues::create([
+            'name' => 'Ryan',
+        ]);
+
+        $this->assertSame('foo@test.com', $model->email);
+
+        $contents = file_get_contents(__DIR__.'/content/default_values/'.$model->id.'.md');
+
+        $this->assertStringContainsString('email: foo@test.com', $contents);
+    }
+}
diff --git a/tests/OrbitManagerTest.php b/tests/OrbitManagerTest.php
index 1507610..efc9ca6 100644
--- a/tests/OrbitManagerTest.php
+++ b/tests/OrbitManagerTest.php
@@ -2,8 +2,8 @@
 
 namespace Orbit\Tests;
 
-use Orbit\Drivers\Markdown;
 use Orbit\Drivers\Json;
+use Orbit\Drivers\Markdown;
 use Orbit\Facades\Orbit;
 use Orbit\OrbitManager;
 
@@ -31,38 +31,10 @@ class OrbitManagerTest extends TestCase
 
     public function test_it_can_register_custom_drivers()
     {
-        $class = new class {};
+        $class = new class () {};
 
         Orbit::extend('example', fn () => $class);
 
         $this->assertEquals($class, Orbit::driver('example'));
     }
-
-    public function test_it_can_return_a_custom_git_name()
-    {
-        Orbit::resolveGitNameUsing(fn () => 'Ryan');
-
-        $this->assertEquals('Ryan', Orbit::getGitName());
-    }
-
-    public function test_it_can_return_a_custom_git_email()
-    {
-        Orbit::resolveGitEmailUsing(fn () => 'ryan@test.com');
-
-        $this->assertEquals('ryan@test.com', Orbit::getGitEmail());
-    }
-
-    public function test_it_can_return_a_custom_git_root()
-    {
-        config(['orbit.git.root' => '/my/folder']);
-
-        $this->assertEquals('/my/folder', Orbit::getGitRoot());
-    }
-
-    public function test_it_can_return_a_custom_git_binary()
-    {
-        config(['orbit.git.binary' => '/usr/local/bin/git']);
-
-        $this->assertEquals('/usr/local/bin/git', Orbit::getGitBinary());
-    }
 }
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 6e37b34..0b0163d 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -17,6 +17,8 @@ abstract class TestCase extends BaseTestCase
 
     public function getEnvironmentSetUp($app)
     {
+        $app['config']->set('database.default', 'sqlite');
+        $app['config']->set('database.connections.sqlite.database', ':memory:');
         $app['config']->set('orbit.paths.content', __DIR__.'/content');
 
         Orbit::test();