Dolt for Beginners: Working Set and Staging
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 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.