diff --git a/content/reference/sql/version-control/dolt-sql-procedures.md b/content/reference/sql/version-control/dolt-sql-procedures.md index 69f595127..f1299941b 100644 --- a/content/reference/sql/version-control/dolt-sql-procedures.md +++ b/content/reference/sql/version-control/dolt-sql-procedures.md @@ -20,6 +20,7 @@ title: Dolt SQL Procedures - [dolt_pull()](#dolt_pull) - [dolt_purge_dropped_databases()](#dolt_purge_dropped_databases) - [dolt_push()](#dolt_push) + - [dolt_rebase()](#dolt_rebase) - [dolt_remote()](#dolt_remote) - [dolt_reset()](#dolt_reset) - [dolt_revert()](#dolt_revert) @@ -995,6 +996,123 @@ CALL DOLT_COMMIT('-a', '-m', 'create table test'); CALL DOLT_PUSH('origin', 'feature-branch'); ``` + +## `DOLT_REBASE()` + +Rewrites commit history for the current branch by replaying commits, allowing the commits to be reordered, squashed, or dropped. The commits included in the rebase plan are the commits reachable by the current branch, but NOT reachable from the branch specified as the argument when starting a rebase (also known as the upstream branch). This is the same as Git and Dolt's ["two dot log" syntax](https://www.dolthub.com/blog/2022-11-11-two-and-three-dot-diff-and-log/#two-dot-log), or |upstreamBranch|..|currentBranch|. + +For example, consider the commit graph below, where a `feature` branch has branched off of a `main` branch, and both branches have added commits: +```sql +A → B → C → D → E → F main + ↘ + G → H → I feature +``` + +If we rebase from the `feature` branch using the `main` branch as our upstream, the default rebase plan will include commits `G`, `H`, and `I`, since those commits are reachable from our current branch, but NOT reachable from the upstream branch. By default, the changes from those same commits will be reapplied, in the same order, to the tip of the upstream branch `main`. The resulting commit graph will then look like: +```sql +A → B → C → D → E → F main + ↘ + G' → H' → I' feature +``` + +Rebasing is useful to clean and organize your commit history, especially before merging a feature branch back to a shared branch. For example, you can drop commits that contain debugging or test changes, or squash or fixup small commits into a single commit, or reorder commits so that related changes are adjacent in the new commit history. + +```sql +CALL DOLT_REBASE('--interactive', 'main'); +CALL DOLT_REBASE('-i', 'main'); +CALL DOLT_REBASE('--continue'); +CALL DOLT_REBASE('--abort'); +``` + +### Limitations +Currently only interactive rebases are supported, and there is no support for resolving conflicts that arise while executing a rebase plan. If applying a commit creates a conflict, the rebase will be automatically aborted. + +### Options + +`--interactive`: Start an interactive rebase. Currently only interactive rebases are supported, so this option is required. +`--continue`: Continue an interactive rebase after adjusting the rebase plan stored in `dolt_rebase`. +`--abort`: Abort a rebase in progress. + +### Output Schema + +```text ++---------+------+-----------------------------+ +| Field | Type | Description | ++---------+------+-----------------------------+ +| status | int | 0 if successful, 1 if not | +| message | text | success/failure information | ++---------+------+-----------------------------+ +``` + +### Example + +```sql +-- create a simple table +create table t (pk int primary key); +call dolt_commit('-Am', 'creating table t'); + +-- create a new branch that we'll add more commits to later +call dolt_branch('branch1'); + +-- create another commit on the main branch, right after where branch1 branched off +insert into t values (0); +call dolt_commit('-am', 'inserting row 0'); + +-- switch to branch1 and create three more commits that each insert one row +call dolt_checkout('branch1'); +insert into t values (1); +call dolt_commit('-am', 'inserting row 1'); +insert into t values (2); +call dolt_commit('-am', 'inserting row 2'); +insert into t values (3); +call dolt_commit('-am', 'inserting row 3'); + +-- check out what our commit history on branch1 looks like before we rebase +select commit_hash, message from dolt_log; ++----------------------------------+----------------------------+ +| commit_hash | message | ++----------------------------------+----------------------------+ +| tsq01op7b48ij6dfa2tst60vbfm9rcus | inserting row 3 | +| uou7dibe86e9939pu8fdtjdce5pt7v1c | inserting row 2 | +| 3umkjmqeeep5ho7nn0iggfinajoo1l6q | inserting row 1 | +| 35gfll6o322aq9uffdqin1dqmq7q3vek | creating table t | +| do1tp9u39vsja3c8umshv9p6fernr0lt | Inіtіalizе dаta repоsitоry | ++----------------------------------+----------------------------+ + +-- start an interactive rebase and check out the default rebase plan; this will rebase +-- all the new commits on this branch and move them to the tip of the main branch +call dolt_rebase('-i', 'main'); +select * from dolt_rebase order by rebase_order; ++--------------+--------+----------------------------------+-----------------+ +| rebase_order | action | commit_hash | commit_message | ++--------------+--------+----------------------------------+-----------------+ +| 1.00 | pick | 3umkjmqeeep5ho7nn0iggfinajoo1l6q | inserting row 1 | +| 2.00 | pick | uou7dibe86e9939pu8fdtjdce5pt7v1c | inserting row 2 | +| 3.00 | pick | tsq01op7b48ij6dfa2tst60vbfm9rcus | inserting row 3 | ++--------------+--------+----------------------------------+-----------------+ + +-- adjust the rebase plan to reword the first commit, drop the commit that inserted row 2, +-- and combine the third commit into the previous commit +update dolt_rebase set action='reword', commit_message='insert rows' where rebase_order=1; +update dolt_rebase set action='drop' where rebase_order=2; +update dolt_rebase set action='fixup' where rebase_order=3; + +-- continue rebasing now that we've adjusted the rebase plan +call dolt_rebase('--continue'); + +-- check out the history +select commit_hash, message from dolt_log; ++----------------------------------+----------------------------+ +| commit_hash | message | ++----------------------------------+----------------------------+ +| 8jc1dpj25fv6f2kn3bd47uokc8hs1vp0 | insert rows | +| hb9fnqnrsd5ghq3fgag0kiq6nvpsasvo | inserting row 0 | +| 35gfll6o322aq9uffdqin1dqmq7q3vek | creating table t | +| do1tp9u39vsja3c8umshv9p6fernr0lt | Inіtіalizе dаta repоsitоry | ++----------------------------------+----------------------------+ +``` + + ## `DOLT_REMOTE()` Adds a remote for a database at given url, or removes an existing remote with its remote-tracking branches diff --git a/content/reference/sql/version-control/dolt-system-tables.md b/content/reference/sql/version-control/dolt-system-tables.md index 3f4d9cf9a..286e586f4 100644 --- a/content/reference/sql/version-control/dolt-system-tables.md +++ b/content/reference/sql/version-control/dolt-system-tables.md @@ -19,13 +19,16 @@ title: Dolt System Tables - [dolt_blame\_$tablename](#dolt_blame_usdtablename) - [dolt_commit_ancestors](#dolt_commit_ancestors) - - [dolt_commit_diff\_$tablename](#dolt_commit_diff_usdtablename) - [dolt_commits](#dolt_commits) + - [dolt_history\_$tablename](#dolt_history_usdtablename) + - [dolt_log](#dolt_log) + +- [Database Diffs](#database-diffs) + + - [dolt_commit_diff\_$tablename](#dolt_commit_diff_usdtablename) - [dolt_diff](#dolt_diff) - [dolt_column_diff](#dolt_column_diff) - [dolt_diff\_$tablename](#dolt_diff_usdtablename) - - [dolt_history\_$tablename](#dolt_history_usdtablename) - - [dolt_log](#dolt_log) - [Working Set Metadata](#working-set-metadata-system-tables) @@ -40,10 +43,15 @@ title: Dolt System Tables - [dolt_constraint_violations](#dolt_constraint_violations) - [dolt_constraint_violations\_$tablename](#dolt_constraint_violations_usdtablename) -- [Configuration Tables](#configuration-tables) +- [Configuration](#configuration-tables) - [dolt_ignore](#dolt_ignore) +- [Rebasing](#rebasing-tables) + + - [dolt_rebase](#dolt_rebase) + + # Database Metadata System Tables ## `dolt_branches` @@ -438,6 +446,129 @@ merged will have `parent_index` 1. +--------------+------+------+-----+---------+-------+ ``` + +## `dolt_commits` + +The `dolt_commits` system table shows _ALL_ commits in a Dolt database. + +This is similar, but different from the `dolt_log` [system table](https://docs.dolthub.com/reference/sql/dolt-system-tables#dolt_log) +and the `dolt log` [CLI command](https://docs.dolthub.com/reference/cli#dolt-log). +`dolt log` shows you commit history for all commit ancestors reachable from the current `HEAD` of the +checked out branch, whereas `dolt_commits` shows all commits from the entire database, no matter which branch is checked out. + +### Schema + +```text +> describe dolt_commits; ++-------------+----------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++-------------+----------+------+-----+---------+-------+ +| commit_hash | text | NO | PRI | | | +| committer | text | NO | | | | +| email | text | NO | | | | +| date | datetime | NO | | | | +| message | text | NO | | | | ++-------------+----------+------+-----+---------+-------+ +``` + +### Example Query + +Using the [`dolthub/first-hour-db` database from DoltHub](https://www.dolthub.com/repositories/dolthub/first-hour-db), +we can query for the five commits before April 20th, 2022, across all commits in the database +(regardless of what is checked out to `HEAD`) with this query: + +{% embed url="https://www.dolthub.com/repositories/dolthub/first-hour-db/embed/main?q=SELECT+*%0AFROM+dolt_commits%0Awhere+date+%3C+%222022-04-20%22%0A" %} + + +## `dolt_history_$TABLENAME` + +For every user table named `$TABLENAME`, there is a read-only system table named `dolt_history_$TABLENAME` +that can be queried to find a row's value at every commit in the current branch's history. + +### Schema + +Every Dolt history table contains columns for `commit_hash`, `committer`, and `commit_date`, plus every column +from the user table's schema at the current checked out branch. + +```text ++-------------+----------+ +| field | type | ++-------------+----------+ +| commit_hash | TEXT | +| committer | TEXT | +| commit_date | DATETIME | +| other cols | | ++-------------+----------+ +``` + +### Example Schema + +Consider a table named `mytable` with the following schema: + +```text ++------------+--------+ +| field | type | ++------------+--------+ +| x | INT | ++------------+--------+ +``` + +The schema for `dolt_history_states` would be: + +```text ++-------------+----------+ +| field | type | ++-------------+----------+ +| x | INT | +| commit_hash | TEXT | +| committer | TEXT | +| commit_date | DATETIME | ++-------------+----------+ +``` + +### Example Query + +Assume a database with the `mytable` table above and the following commit graph: + +```text + B---E feature + / + A---C---D main +``` + +When the `feature` branch is checked out, the following query returns the results below, showing +the row at every ancestor commit reachable from our current branch. + +{% embed url="https://www.dolthub.com/repositories/dolthub/docs_examples/embed/feature?q=SELECT+*+FROM+dolt_history_mytable%3B" %} + +## `dolt_log` + +The `dolt_log` system table contains the commit log for all commits reachable from the current `HEAD`. +This is the same data returned by the [`dolt log` CLI command](https://docs.dolthub.com/reference/cli#dolt-log). + +### Schema + +```text ++-------------+----------+ +| field | type | ++-------------+--------- + +| commit_hash | text | +| committer | text | +| email | text | +| date | datetime | +| message | text | ++-------------+--------- + +``` + +### Example Query + +The following query shows the commits reachable from the current checked out head and created by user `jennifersp` since April, 2022: + +{% embed url="https://www.dolthub.com/repositories/dolthub/first-hour-db/embed/main?q=SELECT+*%0AFROM+dolt_log%0AWHERE+committer+%3D+%22jennifersp%22+and+date+%3E+%222022-04-01%22%0AORDER+BY+date%3B" %} + + +# Database Diffs + ## `dolt_commit_diff_$TABLENAME` For every user table named `$TABLENAME`, there is a read-only system table named `dolt_commit_diff_$TABLENAME` @@ -544,38 +675,6 @@ to HEAD. It is often useful to use [the `HASHOF()` function](dolt-sql-functions. to get the commit hash of a branch, or an ancestor commit. The above table requires both `from_commit` and `to_commit` to be filled. -## `dolt_commits` - -The `dolt_commits` system table shows _ALL_ commits in a Dolt database. - -This is similar, but different from the `dolt_log` [system table](https://docs.dolthub.com/reference/sql/dolt-system-tables#dolt_log) -and the `dolt log` [CLI command](https://docs.dolthub.com/reference/cli#dolt-log). -`dolt log` shows you commit history for all commit ancestors reachable from the current `HEAD` of the -checked out branch, whereas `dolt_commits` shows all commits from the entire database, no matter which branch is checked out. - -### Schema - -```text -> describe dolt_commits; -+-------------+----------+------+-----+---------+-------+ -| Field | Type | Null | Key | Default | Extra | -+-------------+----------+------+-----+---------+-------+ -| commit_hash | text | NO | PRI | | | -| committer | text | NO | | | | -| email | text | NO | | | | -| date | datetime | NO | | | | -| message | text | NO | | | | -+-------------+----------+------+-----+---------+-------+ -``` - -### Example Query - -Using the [`dolthub/first-hour-db` database from DoltHub](https://www.dolthub.com/repositories/dolthub/first-hour-db), -we can query for the five commits before April 20th, 2022, across all commits in the database -(regardless of what is checked out to `HEAD`) with this query: - -{% embed url="https://www.dolthub.com/repositories/dolthub/first-hour-db/embed/main?q=SELECT+*%0AFROM+dolt_commits%0Awhere+date+%3C+%222022-04-20%22%0A" %} - ## `dolt_diff` The `dolt_diff` system table shows which tables in the current database were changed in each commit reachable from the active branch's HEAD. When multiple tables are changed in a single commit, there is one row in the `dolt_diff` system table for each table, all with the same commit hash. Any staged or unstaged changes in the working set are included with the value `WORKING` for their `commit_hash`. After identifying the tables that changed in a commit, the `dolt_diff_$TABLENAME` system tables can be used to determine the data that changed in each table. @@ -772,92 +871,6 @@ num_inmates_rated_for have changed the most between 2 versions. {% embed url="https://www.dolthub.com/repositories/dolthub/us-jails/embed/main?q=SELECT+to_county%2C+from_county%2Cto_num_inmates_rated_for%2Cfrom_num_inmates_rated_for%2C++abs%28to_num_inmates_rated_for+-+from_num_inmates_rated_for%29+AS+delta%0AFROM+dolt_diff_jails%0AWHERE+from_commit+%3D+HASHOF%28%22HEAD~3%22%29+AND+diff_type+%3D+%22modified%22%0AORDER+BY+delta+DESC%0ALIMIT+10%3B%0A" %} -## `dolt_history_$TABLENAME` - -For every user table named `$TABLENAME`, there is a read-only system table named `dolt_history_$TABLENAME` -that can be queried to find a row's value at every commit in the current branch's history. - -### Schema - -Every Dolt history table contains columns for `commit_hash`, `committer`, and `commit_date`, plus every column -from the user table's schema at the current checked out branch. - -```text -+-------------+----------+ -| field | type | -+-------------+----------+ -| commit_hash | TEXT | -| committer | TEXT | -| commit_date | DATETIME | -| other cols | | -+-------------+----------+ -``` - -### Example Schema - -Consider a table named `mytable` with the following schema: - -```text -+------------+--------+ -| field | type | -+------------+--------+ -| x | INT | -+------------+--------+ -``` - -The schema for `dolt_history_states` would be: - -```text -+-------------+----------+ -| field | type | -+-------------+----------+ -| x | INT | -| commit_hash | TEXT | -| committer | TEXT | -| commit_date | DATETIME | -+-------------+----------+ -``` - -### Example Query - -Assume a database with the `mytable` table above and the following commit graph: - -```text - B---E feature - / - A---C---D main -``` - -When the `feature` branch is checked out, the following query returns the results below, showing -the row at every ancestor commit reachable from our current branch. - -{% embed url="https://www.dolthub.com/repositories/dolthub/docs_examples/embed/feature?q=SELECT+*+FROM+dolt_history_mytable%3B" %} - -## `dolt_log` - -The `dolt_log` system table contains the commit log for all commits reachable from the current `HEAD`. -This is the same data returned by the [`dolt log` CLI command](https://docs.dolthub.com/reference/cli#dolt-log). - -### Schema - -```text -+-------------+----------+ -| field | type | -+-------------+--------- + -| commit_hash | text | -| committer | text | -| email | text | -| date | datetime | -| message | text | -+-------------+--------- + -``` - -### Example Query - -The following query shows the commits reachable from the current checked out head and created by user `jennifersp` since April, 2022: - -{% embed url="https://www.dolthub.com/repositories/dolthub/first-hour-db/embed/main?q=SELECT+*%0AFROM+dolt_log%0AWHERE+committer+%3D+%22jennifersp%22+and+date+%3E+%222022-04-01%22%0AORDER+BY+date%3B" %} - # Working Set Metadata System Tables ## `dolt_conflicts` @@ -1175,3 +1188,51 @@ WHERE staged=true; | generated_exception | true | new table | +---------------------+--------+-----------+ ``` + +# Rebasing Tables + +## `dolt_rebase` + +`dolt_rebase` is only present while an interactive rebase is in progress, and only on the branch where the rebase is being executed. For example, when rebasing the `feature1` branch, the rebase will be executed on the `dolt_rebase_feature1` branch, and the `dolt_rebase` system table will exist on that branch while the rebase is in-progress. The `dolt_rebase` system table starts off with the default rebase plan, which is to `pick` all of the commits identified for the rebase. Users can adjust the rebase plan by updating the `dolt_rebase` table to change the rebase action, reword a commit message, or even add new rows with additional commits to be applied as part of the rebase. For more details about rebasing, see [the `dolt_rebase()` stored procedure](dolt-sql-procedures.md#dolt_rebase). + +### Schema + +```text ++----------------+---------------------------------------------------+ +| Field | Type | ++----------------+---------------------------------------------------+ +| rebase_order | DECIMAL(6,2) | +| action | ENUM('pick', 'drop', 'reword', 'squash', 'fixup') | +| commit_hash | TEXT | +| commit_message | TEXT | ++----------------+---------------------------------------------------+ +``` + +The `action` field can take one of the following rebase actions: +- `pick` - apply a commit as is and keep its commit message. +- `drop` - do not apply a commit. The row in the `dolt_rebase` table can also be deleted to drop a commit from the rebase plan. +- `reword` - apply a commit, and use the updated commit message from the `commit_message` field in the `dolt_rebase` table for its commit message. Note that if you edit the `commit_message` but do not use the `reword` action, the original commit message will still be used. +- `squash` - apply a commit, but include its changes in the previous commit instead of creating a new commit. The commit message of the previous commit will be altered to include the previous commit message as well as the commit message from the squashed commit. Note that the rebase plan MUST include a `pick` or `reword` action in the plan before a `squash` action. +- `fixup` - apply a commit, but include its changes in the previous commit instead of creating a new commit. The commit message of the previous commit will NOT be changed, and the commit message from the fixup commit will be discarded. Note that the rebase plan MUST include a `pick` or `reword` action in the plan before a `fixup` action. + +### Example Queries + +To squash all commits into a single commit and include the commit messages from all commits, the following query can be used: +```sql +update dolt_rebase set action = 'squash' where rebase_order > 1; +``` + +To reword a commit with commit hash '123aef456f', be sure to set the action to `reword` and to update the `commit_message` field: +```sql +update dolt_rebase set action = 'reword', commit_message = 'here is my new message' where commit_hash = '123aef456f'; +``` + +To drop the second commit in the rebase plan, you can use the `drop` action: +```sql +update dolt_rebase set action = 'drop' where rebase_order = 2; +``` + +Or you can simply delete that row from the `dolt_rebase` table: +```sql +delete from dolt_rebase where rebase_order = 2; +``` \ No newline at end of file