Dolt for Beginners: Working Set and Staging

REFERENCE
6 min read

The Dolt for Beginners series focuses on topics people getting started with Dolt will likely be interested in. Most of our other blog articles go pretty deep so we want a space to talk about topics that experts may find boring.

Dolt for Beginners

Dolt models its version control functionality after Git, including working sets and staging areas. These Git-specific concepts can be tricky for beginners coming to Dolt from other SQL databases. This article explains the working set and staging area through an illustrative example.

Working Sets

In Git and Dolt, you store a permanent marker in your commit history using commits. Each branch points to a commit. This is called the head of the branch and can be referred to by the Git keyword HEAD.

Any modifications made to the head of a branch are stored in the working set of the branch. The working set can be referred to by the Git keyword WORKING. In other words, the working set contains all the changes for a branch since you last indicated you wanted to store changes permanently with a commit. Practically, if you run git diff or dolt diff, it is showing you the changes in your working set.

For those coming from a database world instead of a Git world, I like to think of other databases like MySQL and Postgres as only having a single working set. All the changes you make are stored on disk but once you change a row, that change is gone forever. The same is tre for Dolt's working sets. There is no built-in mechanism to store the state of the database forever or make multiple branches in traditional databases. All you have is the working set of your main branch.

Staging Areas

Working Sets are relatively easy to understand but Git has an additional, harder to understand concept, called a staging area. To create a commit in Git or Dolt, you must first add your changes to the staging area. When you deem your staging area ready, the staging area is committed. Practically, the staging area allows you to optionally commit some, not all, of the changes in your working set. You can refer to changes in your staging area using the Git keyword STAGED.

The standard lifecycle of changes in Git and Dolt look like this.

HEAD -> WORKING -> STAGED -> HEAD -> WORKING ...

To move changes from your working set to staging you use the add command. To unstage changes you use the reset command.

In practice, staging can often be safely ignored. Especially in Dolt, you mainly stage all your changes. You can skip staging changes by adding the --all flag to your commit. This is a common practice in Dolt especially if you are using the SQL interface.

Install Dolt

To experiment with working sets and staging areas, you must first install Dolt. Dolt is not complicated software. There is no complicated install process. You don't need a Docker container or multiple dependencies installed. You download the single Dolt program and run it.

We have even more convenient ways to install Dolt for every platform.

Once you have Dolt installed, you need to open a terminal like "Terminal" on Mac or Powershell on Windows. Make sure Dolt is on your PATH by typing dolt. If everything is working you'll be greeted by a help message with all the valid Dolt commands. For those familiar with the Git command line, Dolt should look pretty similar.

$ dolt
Valid commands for dolt are
                init - Create an empty Dolt data repository.
              status - Show the working tree status.
                 add - Add table changes to the list of staged table changes.
                diff - Diff a table.
... <trimmed for length>
... <trimmed for length>
... <trimmed for length>
              reflog - Show history of named refs.
              rebase - Reapplies commits on top of another base tip
                  ci - Commands for working with Dolt continuous integration configuration.

Configure Your User

This example is going to make use of the Dolt command line, specifically commits. Just like Git, Dolt needs a user and email to create commits on the command line. To set up your user for this computer you use the dolt config command.

$ dolt config --global --add user.name "Tim Sehn"
$ dolt config --global --add user.email "tim@dolthub.com"

Make a database

We're going to focus on the command-line interface (CLI) to Dolt today. The working set and staging area are best shown off through the command line interface because the flow is modeled after Git.

Open a shell, like Terminal on Mac, or Powershell on Windows. Navigate to the directory where you want your Dolt databases stored. I put mine in ~/dolt. Let's call our database working_staged. To create a database, we use dolt init. Dolt names databases after the directory they are created in so we make a working_staged directory and cd into it.

$ mkdir working_staged
$ cd working_staged 
$ dolt init
Successfully initialized dolt data repository.

Create a Table

When you create a Dolt database using dolt init, an initial commit is made for you on the main branch. This empty database is now acting as our head so any changes we make will go in our working set. Let's create a table and examine the working set using the status command. status is the gateway into what is going on in your working set and staging area.

dolt sql -q "create table people (id int primary key, first_name varchar(100),last_name varchar(100))"

This table is in your working set. Let's see what dolt status has to say.

$ dolt status
On branch main
Untracked tables:
  (use "dolt add <table>" to include in what will be committed)
	new table:        people

Just like Git for files, new tables start as "untracked". I'll make second change later on this table after it exists in the head so you can see the difference.

Stage the Table

Now, it's time to move the table to the staging area. Conveniently, dolt status tells me how to do this: dolt add people.

$ dolt add people
$ dolt status
On branch main
Changes to be committed:
  (use "dolt reset <table>..." to unstage)
	new table:        people

As you can see, the table is now staged and I can unstage it using reset.

Make a Commit

I use dolt commit to make a commit. This will move all my staged changes into a new head commit and my working set and staging area will be clean again.

$ dolt commit -m "Created new table"
commit 7ee25trr1suluqjeu24mcr7au6e87tee (HEAD -> main) 
Author: timsehn <tim@dolthub.com>
Date:  Fri May 09 12:53:08 -0700 2025

        Created new table

$ dolt status
On branch main
nothing to commit, working tree clean

Insert a Row

Now let's insert a row so you can see the lifecycle of a tracked table through working set to staging.

$ dolt sql -q "insert into people values (0, 'Tim', 'Sehn')"
Query OK, 1 row affected (0.01 sec)
$ dolt status
On branch main

Changes not staged for commit:
  (use "dolt add <table>" to update what will be committed)
  (use "dolt checkout <table>" to discard changes in working directory)
	modified:         people

Note, your staging area and working set can diverge. If I stage the table with the single "Tim Sehn" row and add another row, my working set and my staging area are different.

$ dolt add people                                          
$ dolt sql -q "insert into people values (1, 'Brian', 'Hendriks')"
Query OK, 1 row affected (0.01 sec)
$ dolt status                                                     
On branch main
Changes to be committed:
  (use "dolt reset <table>..." to unstage)
	modified:         people

Changes not staged for commit:
  (use "dolt add <table>" to update what will be committed)
  (use "dolt checkout <table>" to discard changes in working directory)
	modified:         people

I can see the difference between the two using dolt diff by referring to the keywords WORKING and STAGED.

$ dolt diff STAGED WORKING
diff --dolt a/people b/people
--- a/people
+++ b/people
+---+----+------------+-----------+
|   | id | first_name | last_name |
+---+----+------------+-----------+
| + | 1  | Brian      | Hendriks  |
+---+----+------------+-----------+

I can't be bothered with this staging area nonsense so let's just commit everything in working using --all. This is my normal workflow in both Git and Dolt.

$ dolt commit --all -m "Committed everything"
commit eoim44o1e19spgaedrurpapmci35v3j8 (HEAD -> main) 
Author: timsehn <tim@dolthub.com>
Date:  Fri May 09 13:01:04 -0700 2025

        Committed everything

$ dolt sql -q "select * from people"
+----+------------+-----------+
| id | first_name | last_name |
+----+------------+-----------+
| 0  | Tim        | Sehn      |
| 1  | Brian      | Hendriks  |
+----+------------+-----------+

Conclusion

So, there you have it. Dolt's working set and staging area functionality mimic Git. These concepts are a bit tricky to understand but critical to understanding your database changes' lifecycle under versioning. More questions? Check out the rest of our beginners series or come by our Discord and ask us directly. We love getting new people started with Dolt.

SHARE

JOIN THE DATA EVOLUTION

Get started with Dolt

Or join our mailing list to get product updates.