# Hi, Gitamic!

Gitamic is a premium Statamic add-on that allows you to take full control of your git workflow from within your CMS.

{% hint style="success" %} <mark style="color:green;">**SPECIAL 2024 PRICE: 30% OFF ALL PLANS—ALL YEAR!**</mark>
{% endhint %}

Gitamic adds a **simple**, **beautiful** and **intuitive** git UI to your [Statamic](https://statamic.com/) CP so that you can have more control over your commits.

It's great for solo sites where you want more granular control of your git history, but really shines on more complex sites that rely on live-publishing whilst pushing changes from your Statamic CP back to your git repository.

### Features

Gitamic supports many of the features you'd expect from a git GUI:

* View the 'working tree'
* Stage and unstage changes (even in bulk)
* Discard unstaged changes
* Commit staged changes
* Push to & pull from the remote branch
* See the commit history
* View diffs

**Gitamic is under active development.** More features are on the way. If you've got any specific requests, please see how to raise [#bugs-features](#bugs-features "mention")

Please support this project by purchasing a license, as it allows me to continue working on it. 🙏

### Requirements

| Gitamic  | v1    | v2    |
| -------- | ----- | ----- |
| PHP      | 7.4+  | 8.1+  |
| Statamic | 3+    | 4+    |
| Git      | 2.30+ | 2.30+ |

#### Statamic Pro

Gitamic does not require Statamic Pro, nor [Statamic's Git Automation](https://statamic.dev/git-integration) to be enabled, in order to work. It can independently work with your repository at no extra expense.

**This means you can even use Gitamic on your Statamic Free sites!**

But you *can* also use Gitamic with Statamic Pro's Git Automation. See [/pages/XbNEO37ylnfJT6slfRIT#3.-optional-play-nicely-with-statamic-pro](https://gitamic.simonhamp.me/pages/XbNEO37ylnfJT6slfRIT#3.-optional-play-nicely-with-statamic-pro "mention") for more details.

### Pricing & Bundles

{% hint style="success" %}
You can pay for Gitamic in **$ USD**, **£ GBP** or **€ EUR**
{% endhint %}

Gitamic comes in a few licensing flavours:

#### **🌱 Gitamic Pro - Single-site, annual license**

One year of updates and support. Renews annually at a discounted rate.\
\
**Also available in a 5-site bundle 🪴 Buy four, get one free!**\
\
And don't worry, you don't need to keep paying to keep using... if you choose to stop renewing at any point, you will only miss out on the latest updates and support.

#### **🌳 Gitamic Lifetime**

A single payment (no renewals), access to every version of Gitamic. Plus direct access to the Gitamic repo, so you'll get to beta test pre-release versions and have a lifetime of *priority* support.

#### **🌲 Gitamic Lifetime Unlimited license**

Great if you're planning to build lots of sites with Gitamic or just *really* want to support its continued development.

As well as being able to use it on as many sites as you want, having lifetime direct access to the repo *and* priority support, **you'll get a permanent spot in an Acknowledgements file that will be included with every installation**.

{% hint style="info" %}
For the latest prices and offers, keep your eye on the `Pricing` tab on [Gitamic's Anystack Marketplace listing](https://marketplace.anystack.sh/item/gitamic).
{% endhint %}

### Installation

1. To install and use Gitamic, you first need a license key. Purchase one on [Anystack](https://marketplace.anystack.sh/item/gitamic)
2. Activate your license key in your Anystack dashboard
3. [Install Gitamic](/getting-started/installation)
4. [Setup your application](/getting-started/setup)

### Bugs and Feature Requests <a href="#bugs-features" id="bugs-features"></a>

If you experience any problems with Gitamic, please [raise an issue](https://github.com/simonhamp/gitamic-support/issues) using the appropriate template.

For feature requests, please [start a Discussion](https://github.com/simonhamp/gitamic-support/discussions/new?category=ideas) in the Ideas category.

You can also find me ([@simonhamp](https://twitter.com/simonhamp)) in the `#3rd-party` channel on the [Statamic Discord](https://statamic.com/discord). (Note that I will likely still ask you to fill out a GitHub issue).

### Security

If you discover any security related issues, please see the [Security policy](/legal-security-support/security-policy) for what to do.

### License

Gitamic is a premium add-on and you must [purchase a license key](https://marketplace.anystack.sh/item/gitamic) in order to use it.

Read the full [License agreement](/legal-security-support/license-agreement)


# Roadmap

There's a lot I want Gitamic to do!

### Now

* ~~Staging & unstaging hunks instead of whole files~~ ✅
* AI-generated commit messages
* Revert to a previous (local-only) commit
* Stashing & unstashing
* Managing .gitignore files
* Improved diff summaries - show the number of changes

### Next - v3

* Remote management & tracking
* Side-by-side diffs
* Blame support
* Permissions & approvals
* GitHub integration
* Image diffs (before & after)
* Character diffing - richer diffs that highlight exactly which parts of a line are different
* Syntax highlighting
* Deletion & addition summaries (LOC)
* Chunk discarding

### Later

* Line-by-line staging/unstaging/discarding
* Branching & merging
* Rich image diffs
* Deeper Statamic integration - e.g. show version history on an Entry edit screen

Have you got any must-have features? [Start a discussion thread](https://github.com/simonhamp/gitamic-support/discussions/new?category=ideas)


# Installation

Gitamic is installed via Composer.

Before you install Gitamic, make sure your system and application meets the [Hi, Gitamic!](/#requirements).

### Composer

To install Gitamic, you must use [Composer.](https://getcomposer.org/)

Gitamic is not available on the public Composer package repository Packagist, so to install Gitamic, we must first tell Composer how to find it.

To do that, you must add the private repository URL to the `repositories` array in your `composer.json`:

```json
"repositories": [
  {
    "type": "composer",
    "url": "https://gitamic.composer.sh"
  }
],
```

Then, you can install the package via Composer as you'd expect:

```bash
composer require simonhamp/gitamic
```

The first time you run this, you'll be prompted to authenticate against the private package repository:

```bash
Loading composer repositories with package information
Authentication required (gitamic.composer.sh):
  Username: 
  Password: 
```

The authentication details will depend on where you purchased your license:

{% tabs %}
{% tab title="Anystack" %}

* **`Username`**: Your Anystack account email address.
* **`Password`**: Your [license key](https://account.anystack.sh/licenses) followed by a colon `:` and the domain name you entered when activating your license.\
  \
  For example: `9227fd74-ed29-4d1a-ad75-0bc41bea16a9:abc-widgets.com`

{% hint style="danger" %}
**Don't forget to activate your license first!**
{% endhint %}
{% endtab %}

{% tab title="Statamic Marketplace" %}
Your Statamic Marketplace license for Gitamic has been migrated to [Anystack](https://anystack.sh/).

You should have received an email encouraging you to [sign up for an Anystack Customer account](https://auth.anystack.sh/register?accountType=customer).

Your license key is associated with the email address you originally used to purchase Gitamic from the Statamic Marketplace. To retrieve it, please register with Anystack using the same email address.

* **`Username`**: Your Anystack account email address
* **`Password`**: Your license key is available in your [Anystack dashboard](https://account.anystack.sh/licenses)

{% hint style="info" %}
There is no need to activate your license code
{% endhint %}

{% hint style="success" %}
**All Statamic Marketplace licenses have been upgraded to Gitamic Pro!**\
\
[Make sure you change your `config/statamic/editions.php`](https://gitamic.simonhamp.me/getting-started/pages/XbNEO37ylnfJT6slfRIT#1.-register-the-add-on-within-statamic)
{% endhint %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Your Anystack email address cannot be changed.** If you cannot remember your license key and no longer have access to that email account, you will need to purchase another license
{% endhint %}

{% hint style="success" %}
Consider saving these details to your `auth.json` file so that you don't need to enter them every time you run a `composer install` or `composer update`
{% endhint %}


# Setup

Once you've installed Gitamic, you'll need to update your application's configuration. This is usually a one-time thing for each Statamic site where you use Gitamic.

### 1. Register the add-on within Statamic

Update your `config/statamic/editions.php` config file to indicate that you're using the `pro` edition of Gitamic:

```php
'addons' => [
    'simonhamp/gitamic' => 'pro',
],
```

### 2. \[Optional] Set the commit author details

By default, Gitamic uses the following details for the git committer name and email address:

* name: `Gitamic`
* email: `gitamic@[domain from APP_URL]`

You can easily override these values in your `.env` by adding the following keys, e.g.:

```dotenv
GITAMIC_GIT_USER_NAME="Simon Hamp"
GITAMIC_GIT_USER_EMAIL="simon.hamp@me.com"
```

Alternatively, publish the Gitamic config file to your application. This should already happen as part of the add-on's installation, but for some reason it doesn't exist, run the following command in your terminal:

```bash
php artisan vendor:publish --provider=SimonHamp\\Gitamic\\ServiceProvider
```

Then, if you prefer your whole team to use the same committer details, you can hard-code these settings into the `config/gitamic.php` config file.

{% hint style="info" %}
If you're using Statamic Pro's Git Integration and would prefer Gitamic to use the same set of user details, simply set these values to `null` in your `config/gitamic.php` config file.\
\
Gitamic will then use `STATAMIC_GIT_USER_NAME` and `STATAMIC_GIT_USER_EMAIL` instead, if those have been defined.
{% endhint %}

If you'd like to use the details of the logged-in Statamic user as the committer, you will need to enable the `gitamic.use_authenticated` option in `config/gitamic.php`:

```php
return [
    'use_authenticated' => true,

    'user' => ...
];
```

### 3. \[Optional] Play nicely with Statamic Pro

If you have [Statamic Pro](https://statamic.com/pricing) (you should, it's great!) and you have [Statamic's Git Automation](https://statamic.dev/git-automation) enabled, you may find it better to *disable* Statamic's '[automatic commits](https://statamic.dev/git-automation#committing-changes)' feature so that Statamic doesn't automatically commit every change.

This will leave you to manage your commits via Gitamic, if that's what you prefer.

To disable Statamic's automatic commits, add the following to your `.env` file:

```dotenv
STATAMIC_GIT_AUTOMATIC=false
```

***

{% hint style="info" %}
You should commit these changes to your application to save the rest of your team from having to follow the same steps
{% endhint %}


# Deployment

Some notes on various deployment scenarios whilst using Gitamic.

### Authentication

When building your application in its production environment or running it through a CI[^1] pipeline, you will likely need to install its dependencies, and this may include Gitamic.

When that happens, Composer will need to authenticate against the private repository in order to install Gitamic.

You probably don't want to be doing this manually in a terminal every time – and [thanks to Composer, you don't have to](https://getcomposer.org/doc/articles/authentication-for-private-packages.md)!

How you authenticate will depend on how you deploy:

{% tabs %}
{% tab title="Laravel Forge" %}
Laravel Forge has [built-in support](https://forge.laravel.com/docs/1.0/sites/packages.html) for private package repository authentication.

* Repository URL: **`gitamic.composer.sh`**
* Username: Your Anystack email address
* Password: [Your license key](/getting-started/installation#anystack) (which depends on how you purchased it)
  {% endtab %}

{% tab title="Netlify" %}
Create a `COMPOSER_AUTH` Environment Variable with the JSON structure that Composer expects, e.g.

```json
{"http-basic":{"HOSTNAME":{"username":"USERNAME","password":"PASSWORD"}}}
```

Replace the placeholders with the following values:

* `HOSTNAME`: **`gitamic.composer.sh`**
* `USERNAME`: Your Anystack email address
* `PASSWORD`: [Your license key](/getting-started/installation#anystack) (which depends on how you purchased it)

For compatibility, remove all spaces and line breaks.
{% endtab %}

{% tab title="Custom / Other" %}
Any of the following methods should work. **You only need to pick one.**

#### `auth.json`

You can create an `auth.json` file [in your project](https://getcomposer.org/doc/articles/authentication-for-private-packages.md#authentication-in-auth-json-per-project) or in [a global `auth.json`](https://getcomposer.org/doc/articles/authentication-for-private-packages.md#global-authentication-credentials) that stores these credentials.

{% hint style="danger" %}
**Do not commit your `auth.json` file to git**
{% endhint %}

#### `COMPOSER_AUTH`

Create a `COMPOSER_AUTH` environment variable similarly to the approach used for [#netlify](#netlify "mention").

You can set this environment variable in your shell config file or you can create it on-the-fly as part of your `composer` CLI commands:

```bash
COMPOSER_AUTH={JSON} composer install ...
```

See the [#netlify](#netlify "mention") example for what to replace the `{JSON}` placeholder with
{% endtab %}
{% endtabs %}

### Auto-deployment

If you're using Gitamic to `push` commits from a server that is also the target for automated deployments, when you `push` from Gitamic it might trigger a redundant deployment back to the environment that is the *source* of those changes.

To prevent this, in your deployment script, you will need to write a statement that exits the deployment when it detects that Gitamic initiated the commit.

For example, if you use [Laravel Forge](https://forge.laravel.com/) (and you haven't customised the git commiter name - see [/pages/XbNEO37ylnfJT6slfRIT#2.-optional-set-the-git-committer](https://gitamic.simonhamp.me/getting-started/pages/XbNEO37ylnfJT6slfRIT#2.-optional-set-the-git-committer "mention")), you could add the following to the beginning of your deploy script, which inspects the author of the commit and stops the process before it begins:

```bash
[[ "$FORGE_DEPLOY_AUTHOR" == "Gitamic" ]] && echo "Commit by $FORGE_DEPLOY_AUTHOR" && exit 0

# The rest of your deployment script...
```

However, the specific approach you should use will depend on your unique setup.

[^1]: Continuous Integration


# Git basics

A brief introduction to some basic Git concepts

Git is probably the most popular source code/version control software available on the planet. And for good reason! It's a mature, robust, and reliable way to work collaboratively through a distributed system of maintaining file change history... and so much more.

This allows you to track changes to files over time, seeing how they changed, when they changed, and who made those changes. This makes it especially powerful for auditing and review! If used well, Git can help you:

* Review your own work, or someone else's, before merging it
* Run multiple streams of work concurrently
* Find when a bug was introduced into a codebase
* See who wrote that beautiful paragraph
* Quickly see the changes made between distant versions of multiple files

This is very useful in a number of highly-specific contexts – Git was created to make building Linux more manageable, so it's particularly great if you're building software/writing code – but in general it's great for managing changes to any sort of text file.

This is great in the context of Statamic when used as a flat-file CMS, as it enables some very powerful workflows!

This guide assumes you're familiar with Git to some degree (what it is and why it's used) and that you've already got Git installed on the relevant systems.

What we're going to cover here are just some of the basic concepts that Gitamic features expose. If you want to go into more detail about Git, check out the [Resources](#resources) section at the bottom of this page.

### Repository

A Git **Repository** (or 'repo' for short) is a combination of a Git database and all of the files included in it. This can be thought of most simply as the folder which contains your Statamic site.

Each repository has a special `.git` folder (usually hidden) within it – this is the Git database. Usually, the repository includes all files in the same directory as this `.git` directory, and all directories below it.

{% hint style="success" %}
**You don't need a Git repository to get started with Gitamic!** If your site isn't part of a Git repo, Gitamic will detect that and suggest some ways to get started.
{% endhint %}

### Revisions

A revision is a reference to a Git object. [#commits](#commits "mention") are a type of revision.

Each revision will have some form of absolute or relative identifier, e.g. a commit hash.

### Branches

**Branches** are an important concept in Git. Branches are offshoots, alternative timelines, of your project. They are lightweight and easy to create and destroy.

Gitamic doesn't currently support creating or managing branches, but this will change in the future.

It does show you which branch you're currently running and the remote branch that the branch you're working on is tracking. See [#remotes](#remotes "mention") below for more details.

### Merging

Coming soon!

#### Conflicts

### Working tree

The **Working tree** represents all the *differences* between the [#index](#index "mention") and the current state of the file system.

The working tree is divided into a few states:

* **Untracked** - files which Git knows nothing about.\
  These are files that have not yet been added to the Index.
* **Unstaged** - files with changes that are *not ready* to be committed.\
  These are files that exist in Git's index, but changes have been made to them and Git is allowing you the opportunity to review those changes.
* **Staged** - files with changes that *are* ready to be committed.\
  These are files that exist in Git's index and have changes that you have staged ready to be committed, but they are not committed yet.

Gitamic simply splits these into two: **Unstaged** and **Staged**. Untracked files are part of the Unstaged list.

Changes listed in either of these sections have **not** been recorded in Git's [#index](#index "mention") so there is no revision for them.

#### Staging/unstaging changes

Files in the working tree can usually be moved freely between a staged and unstaged state.

### Index

The **Index** is Git's database, its record of changes that have been made. This is what enables Git to identify when changes are made, because it knows what the state of each tracked file should be.

#### Ignored files

It is possible to ignore files so that Git doesn't keep on alerting you to the fact that you have unresolved changes in them by adding a `.gitignore` file to the root of your project.

To ignore a file, simply add it's path on a new line in this `.gitignore` file.

```
.DS_Store
/.idea
```

See the [gitignore documentation](https://git-scm.com/docs/gitignore) for more details.

The `.gitignore` file itself will show up as a change that you will likely wish to commit so that it can be shared with collaborators or deployed to your servers.

### Diffs

Diffs are a comparison of two or more revisions of a given file. This allows you to see the difference between the revisions as represented by a diff view.

The diff view presents an algorithmically-calculated set of lines that Git believes to be different, often presenting changes contextually.

This makes for a convenient and reliable way to review what has changed:

{% content-ref url="/pages/8efvYeynhhBL3jEsWdBt" %}
[Reviewing changes](/using-gitamic/reviewing-changes)
{% endcontent-ref %}

### Commits

**Commits** represent a moment in time. Each commit records a set of file changes (aka a changeset).

A commit can be made for changes of any size – either as little as a single character on one line in one file, or many hundreds of thousands of changes in thousands of files (though you should avoid making very large commits like this).

Each commit includes some metadata about the changes:

* when they occurred
* who made them
* a message written about the commits
* what commits came before this one
* a commit hash

The **commit hash** effectively makes the Git history immutable, which is an important feature if you want to guarantee that what happened according to the log is indeed how it was originally recorded.

{% hint style="success" %}
You can see the 20 most recent commits in Gitamic's **History** tab.
{% endhint %}

Now go see how to create commits in Gitamic:

{% content-ref url="/pages/zsr9PTRj6aIoyQA7QFeE" %}
[Creating commits](/using-gitamic/creating-commits)
{% endcontent-ref %}

#### Commit messages

Writing clear and concise commit messages is an important skill that will serve you well later on. [Read my quick guide](/using-gitamic/creating-commits/writing-commit-messages) on how to do it well.

### Remotes

Git is a *distributed* version control system and it encourages local-first revision control. When you need to share your changes with someone else (or deploy them to a server), you will need to set up a **Remote**.

Remotes are a kind of branch (see [#branches](#branches "mention")). If the other version of this repository (the remote) is using a branch that started off the same as the one you're using, they can diverge and eventually be merged back together.

This allows two instances of the same repository to communicate with each other and determine which commits each is missing. Git can then work out if it's possible to merge the commits from a given remote branch into your local branch.

{% hint style="info" %}

#### A word about '**local'** branches

By 'local' I mean 'local to wherever you're accessing your Statamic CP'. This may be on your own computer if you have your repository installed, e.g. if you're the website developer.

However, if you're editing your website online (e.g. at <https://abcwidgets.com/cp>), then the 'local' branch is most likely on a server somewhere on the Internet.
{% endhint %}

#### Tracking

Tracking remote branches allows Git to automatically compare the local branch to a known remote branch without having to define which branch to compare to every time.

This is like saying "I always want to keep my branch up to date with that branch on the remote end". Git can then allow you to push and pull changes more easily.

{% hint style="danger" %}
Gitamic doesn't yet allow you to manage remotes or set up branch tracking, but it's on the [Roadmap](/roadmap)!
{% endhint %}

#### Pushing & pulling

When you want to send new commits to a tracked remote branch (commits that it doesn't yet have), Git will identify that your branch is "ahead" and will allow you to **Push** the changes to the remote.

When the tracked remote branch has commits that your local branch doesn't have, Git will see that your branch is "behind" and will allow you to **Pull** the changes from the remote.

In some cases, your local branch can be *both ahead and behind*. In those cases, you MUST *pull first*, allowing Git to merge the remote changes into your local branch. Once that's done, you can push all your new commits.

This protects the remote from receiving commits that it can't merge, which would leave it in a messy state (not something you'd want on your production server!)

Now why not try pushing and pulling yourself?

{% content-ref url="/pages/IqlGIJkpgG3Sc71TwpmN" %}
[Pushing & pulling](/using-gitamic/pushing-and-pulling)
{% endcontent-ref %}

***

<details>

<summary>Resources</summary>

* [The official Git website](https://git-scm.com/)
* [gitignore documentation](https://git-scm.com/docs/gitignore)
* [GitHub's Getting started with Git](https://docs.github.com/en/get-started/getting-started-with-git)

</details>


# Reviewing changes

How to use Gitamic to review your work

The Gitamic work area is divided into two main sections: **Unstaged** and **Staged**. You can see at a glance how many files are in each work area, so you can easily see where your attention is needed.

<figure><img src="/files/ZnozDa83IMvUZK33kL1a" alt=""><figcaption><p>Wow! There are 4 changes already</p></figcaption></figure>

### Unstaged files

Start in the **Unstaged** tab. Here you can see all files with changes that Git has identified.

Clicking on a file's path in the list will open the Diff viewer, allowing you to see all of the unstaged changes made to each file. (If you have any *staged* changes in this file, you will need to view the file'ss diff from the **Staged** tab.)

You can stage one file at a time by clicking on the context menu to the right of each file (...) and selecting `Stage`.

<figure><img src="/files/1KI6GngFNuLIvRcvZe9A" alt=""><figcaption><p>Click 'Staged' to mark all changes in this file as ready to be committed</p></figcaption></figure>

`Discard` erases the changes - so if the changes modify the file in any way, discarding them will reverse those changes: new content will be erased, deleted content will be restored.

You can stage many files at once using the bulk action checkboxes. Simply check one of the boxes to the left of each file and the bulk action options will appear at the top.

<figure><img src="/files/XKgj2cyqjldUpPF6i1JM" alt=""><figcaption><p>Bulk actions make it easy to move through lots of changes rapidly</p></figcaption></figure>

It's useful to review the changes of each file and only stage what you know you want to commit. You can leave any changes that you don't want to commit in the *unstaged* state – Git will only commit changes that are *staged*.

### Staged files

In the **Staged** tab you can see all of the files with changes that you have *staged*, or marked as ready to be committed.

You can view the diffs of staged changes by clicking on the file path.

You can unstage a whole file from the context menu by clicking `Unstage`. These changes will now appear in the file's **Unstaged** view again.

You can bulk unstage many files at once.

### Viewing diffs

<figure><img src="/files/Io9sV8Lv8eqBZZxIBMPc" alt=""><figcaption><p>Gitamic's diff viewer is powerful ⚡️</p></figcaption></figure>

The **Diff viewer** is a critical part of reviewing changes made to your files. It shows you quickly what's changed and lets you decide which *parts* of a file you want to commit.

Let's break down the diff viewer.

When viewing diffs from files in the **Staged** or **Unstaged** tabs, you will see the changes for just *one file*. So you will see only one file card in the diff viewer, with the file name at the top of the card.

This also gives you a summary of the changes - an indicator of the type of change (the one above is an <mark style="background-color:green;">A</mark>ddition) and how many chunks have been detected. In this case, this whole file is new, so there's just one chunk.

It looks like a new entry in the `posts` collection!

Then there's the numbers in the left-hand column and the text on the right-hand side.

The numbers are the line numbers in the file. This can make it easier to find the changes in a code editor or other tools.

There are two banks of line numbers side-by-side: the left bank shows the numbers in the file *before* the change, the right shows the numbers *after* the change. In this example, there is no left bank as the file is completely new.

The diff viewer shows *blended* diffs where both versions of the file are shown together. This can sometimes be aid with spotting exactly what has changed in a specific chunk.

The text in the big right-hand column should be obvious: this is the contents of the file. Sometimes it will show the entire file. At other times it will show just some snippets of the file (called **Chunks**).

Each chunk is collapsible (useful when there are many chunks) and can be staged/unstaged independently of other changes. See [#patching-chunks](#patching-chunks "mention")for more.

You can use the `Context lines` setting to adjust how many lines of context are shown next to each chunk (click `Refresh` to see the change). Depending on the size of the file, this may affect the number of chunks.

#### Diffs

The diffs themselves are generally made up of three parts:

* **Old lines** show how the file appeared before any changes were made, according to Git's [Git basics](/using-gitamic/git-basics#index). They appear in <mark style="background-color:red;">red</mark> and indicate that this line has changed or been removed entirely.
* **New lines** show the *current state of the file*. They appear in <mark style="background-color:green;">green</mark> and indicate that this line contains something new or different to what was there previously.
* **Context lines** may or may not appear depending on the state of the file – completely new files or deleted files won't have any context, for example, because the whole file has changed. When they do appear, they have the default background color.

You can `Stage all` or `Unstage all` (depending on where you viewed the diff from – the **Staged** or **Unstaged** tab), using the blue button at the top of the file card.

#### Patching chunks

With Gitamic, you can stage or unstage individual chunks. Simply use the `Stage` or `Unstage` button at the top-right of a chunk to move it from one part of the working tree to another.

Once a chunk's status has changed, it will disappear from the current view as you will be viewing a different context. For example, if you're viewing an unstaged file with 3 chunks and you stage one chunk, you will now see only 2 chunks.

This provides for a nice visual workflow.

When all chunks have been moved into the other context, the context will shift automatically to show you the fully staged or unstaged file and you should see all of the chunks re-appear.

{% hint style="warning" %}
**Remember:** *Everything* in a chunk gets staged or unstaged together. If you want to increase/decrease how much is included in a chunk, change the `Context lines` setting.
{% endhint %}

{% embed url="<https://youtu.be/b-c-q0LngMc>" %}
See chunk patching in action
{% endembed %}


# Creating commits

Creating commits in Gitamic is a cinch

Ok, so you've reviewed the changes and staged the ones you want to make ready. Now it's time to commit.

### How to commit in Gitamic

Once you've got some staged changes, you will see the commit message box.

<figure><img src="/files/rx4RBSfy5wQRkVO4pvPH" alt=""><figcaption><p>The commit message box only appears when needed</p></figcaption></figure>

Any changes listed below the message box will be included in the commit.

Simply write a commit message ([be sure to make it a good one!](/using-gitamic/creating-commits/writing-commit-messages)) and click `Commit` and you're done!

{% hint style="info" %}
You can use the `Cmd+Enter` (on macOS) or `Ctrl+Enter` (on other platforms) keyboard shortcut to save reaching for your mouse.
{% endhint %}


# Writing commit messages

How to write clear and concise commit messages

A lot of this page is inspired by and adapted from [this fantastic post](https://cbea.ms/git-commit/) by cbeams.

> A well-cared for log is a beautiful and useful thing.

> \[Good committers] know that a well-crafted Git commit message is the best way to communicate *context* about a change to fellow developers (and indeed to their future selves)
>
> — [cbeams, 2014](https://cbea.ms/git-commit/)

These are just some useful guidelines, not rules.

### Separate subject from body with a blank line

Not every commit requires both a subject *and* a body. If the subject is enough, it's enough.

But when you do need to provide more detail, separate the subject from the body with a blank line.

```
Here's the subject

And here's the body that goes into a lot more detail.
```

### Limit the subject line to 50 characters

This isn't a rule, but it encourages you to be concise. It also means that the subject will be presented nicely in most places without being trimmed.

### Capitalize the subject line

Readability starts with first principles, but...

### Do not end the subject line with a period

Every character counts when you're being concise.

### Use the imperative mood in the subject line

Write like you're commanding someone to do something, not past tense expressing what you *did*.

### Use the body to explain *what* and *why* vs. how

This is possibly the most important recommendation!

When committing many changes, you should focus on giving context on what has changed and why it was needed, and less on how.

For most content changes this probably won't be a major concern, but if your changes cover code, then the *how* can usually be found by reading the changes in the code; what may be less obvious from the code is *what* changed and *why*.


# Atomic commits

It's a good practice to make them atomic

### What's an atomic commit?

Atomic commits are self-contained and "complete" in the sense that the changes they record work together as a single unit.

If you ever need to reverse (known as a 'revert' in Git lingo) some work, you will find it much easier if many changes that are related to each other (or even depend on each other) are clumped together in a single revision.

{% hint style="info" %}
This is one of the most important reasons for creating manual commits rather than leaving it to an automated process: **you cannot achieve true atomic commits when many changes are automatically rolled up into commits.**
{% endhint %}

Practicing atomic commits also has the side-effect of encouraging smaller sets of changes that can more easily be rolled up together, which helps to bring focus to your work, allowing you to move more quickly.

If you think in terms of jobs to be done, you can think of a commit as the completion of a job: the contents of the commit (the changeset) should represent everything needed to complete that task.

This also leads to your jobs/tasks reaching a useful level of granularity. For example, instead of a task called "Improve homepage CTA" which might incorporate a bundle of small jobs in your project management tool of choice, you end up with discrete tasks for things like "Change 'Join now' to 'Sign up today!' on homepage" because you know this is a clear and concise piece of work.

That, in turn, makes deciding what your commit message should be that much easier – you (or someone else) already wrote it!

And it's far easier to find a commit message that has the name of the task as the heading than it is to search based on any other criteria. Your project management tool may even be able to make the connection between your tasks and your commits automatically for you.

**A virtuous circle!**

### The case for manual commits - an example

{% hint style="danger" %}
This scenario is based on real events that occurred on a Statamic site I built and managed for 5 years.

The team editing it was small - no more than 5 people - and we used Statamic v2 with the Spock add-on, which was the precursor to Statamic's now built-in Git Automation.

We bumped into these kinds of problems almost every week.
{% endhint %}

You made some edits to the homepage of a client site that you help to manage - these changes need to be live today, but because you've used Statamic it's only going to take you a few minutes.

Meanwhile, your client - let's call them Jen - has made a whole bunch of complex edits on a number of different landing pages, some of which were saved a short time from when you made your changes to the homepage.

For getting the work done, this should all be fine. There's no conflicts as Statamic lets you both work on separate pieces of content at the same time without any trouble.

With auto-commits, neither of you have to think about staging or committing any work - all the work done gets committed and pushed to the repo, job done.

A little while later, Jen calls you. It turns out all of the changes they made weren't meant to go live yet and they need to revert all of that work. They could do it manually, but they know you can do it quicker with your software wizardry 🧙 🪄

You check the commit history to see what the damage is, but sadly it's a bit of a mess.

It looks like your changes have been wrapped up with some of Jen's changes into one commit and then there are a few more commits covering a hopscotch of Jen's changes over the course of an hour or so that they were working on the site.

Oh dear!

What you want here is a **single commit** for each set of changes: one that captures just the changes Jen made and one that captures just your changes. Then you could easily roll back only Jen's changes using Git's revert feature.

(Failing that, even a commit for each individual file that was changed would be ok as you could work them all out and do them all one by one.)

Unfortunately you have neither in this world of automatic commits: your homepage changes will get reverted along with all of Jen's changes, meaning that, no matter which way you cut it, there's going to be more manual work here for you than you'd like.

It might still be less than Jen would have to do and it's not like your work is lost - it is recorded in Git after all - but it's grunt work nonetheless and you've got more interesting work you could be doing.

Your short and sweet content update task has now turned into an urgent and time-consuming Git management nightmare.

**This is where manual, atomic commits can save you!**

Granted, this might not happen very often and it's a trade-off - some time spent each time you do some work to think carefully about what's been done and how it should be organised in the repo's history versus potentially spending an extra hour here and there cleaning up some messy revert.

But as soon as more people start making edits to this site, these kinds of headaches become far more frequent... and far messier.

Getting everyone into the good practice of creating manual, atomic commits, however, allows you all to individually decide which parts of the work that you've done can be grouped together into appropriate revisions in the repo's history.

Then, should you ever need to revert a whole chunk of work, it is just a single, clean commit away.


# Pushing & pulling

Coming soon


# License agreement

The legal wording of the Gitamic license.

Copyright © Simon Hamp ([simonhamp.me](https://simonhamp.me))

Permission is hereby granted to any person obtaining a copy of this software (the “Software”) to use, copy, modify, merge, publish and/or distribute copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

1. **Do not plagiarize.** The above copyright notice and this license shall be included in all copies or substantial portions of the Software.
2. **Do not use the same license on more than one project.** Each licensed copy of the Software shall be actively installed in no more than one production environment at a time.
3. **Do not alter the licensing features.** Software features related to licensing shall not be altered or circumvented in any way, including (but not limited to) license validation, feature or edition restrictions, and update eligibility.
4. **Not for reuse.** The Software and the proprietary code therein, not limited to but including designs, components, classes, and patterns, may not be reused in other projects without the express written consent of Simon Hamp.
5. **Follow the law.** All use of the Software shall not violate any applicable law or regulation, nor infringe the rights of any other person or entity.

Failure to comply with the foregoing conditions will automatically and immediately result in termination of the permission granted hereby. This license does not include any right to receive updates to the Software or technical support. Licensees bear all risk related to the quality and performance of the Software and any modifications made or obtained to it, including liability for actual and consequential harm, such as loss or corruption of data, and any necessary service, repair, or correction.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, INCLUDING SPECIAL, INCIDENTAL AND CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


# Security policy

What to do if you become aware of a vulnerability exposed by Gitamic.

### Reporting a Vulnerability

{% hint style="success" %}
**SEND REPORTS TO:** [**gitamic@simonhamp.me**](mailto:gitamic@simonhamp.me)\
With the subject line: **Gitamic Security**
{% endhint %}

{% hint style="danger" %}
**DO NOT REPORT SECURITY VULNERABILITIES PUBLICLY**

Please **do not** report them as issues on GitHub or share your discovery on Twitter, Discord or in any other public forum, as this may result in them being exploited.
{% endhint %}

Each report **MUST** include:

* Gitamic version (e.g. `2.0.0`)\
  `composer show simonhamp/gitamic | grep "versions :"`
* PHP version (e.g. `8.2.7`)\
  `php -v`
* Statamic version (e.g. `4.9.2`)\
  `php please -V`
* Laravel version (e.g. `10.14.1`)\
  `php artisan -V`
* Git version (e.g. `2.34.1`)\
  `git --version`

Besides these key details, please provide as much context as possible to allow me to assess and reproduce the vulnerability.

All reports will be acknowledged within 48 hours of receipt.

Your report will either be `ACCEPTED` or `DECLINED`, and you will be notified of this decision by reply to your original email.

If your report is accepted, I will work on a fix and you will be notified via email once the fix has been released.

**Note that I will not follow up feature requests or bug reports at the above email address.** Please [report an issue](https://github.com/simonhamp/gitamic-support/issues) instead.

### Rewards

The first reporter of an accepted vulnerability report will receive a free Gitamic lifetime license **once the vulnerability has been mitigated**.

There is no cash alternative.

### Supported Versions

| Version | Supported            |
| ------- | -------------------- |
| > 1.0   | :white\_check\_mark: |


