dolt commit -a leaves a working-tree table rename entirely unstaged (git commits the drop half; arguably -a should stage the whole rename)
- Dominant language
- Go
- Stars
- 24.4k
- Forks
- 873
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 121
Description
## Observed behavior (Dolt 2.2.2)
With a committed table `t`, rename it and commit with `-a` in one SQL session:
```sql
CREATE TABLE t(id INT PRIMARY KEY, v INT);
CREATE INDEX tvi ON t(v);
INSERT INTO t VALUES (1, 10);
CALL dolt_add('-A');
CALL dolt_commit('-m', 'c1');
ALTER TABLE t RENAME TO t2;
CALL dolt_commit('-am', 'commit the rename');
SELECT * FROM dolt_status;
SELECT message FROM dolt_log;
```
Result: **no commit is created** (the `-am` finds nothing stageable when the rename is the only change), and status still shows the rename fully unstaged:
```
t -> t2 | 0 | renamed
```
With a modified bystander table (`ALTER TABLE t RENAME TO z; INSERT INTO u VALUES (3,3); CALL dolt_commit('-am', ...)`), the commit is created containing only `u`'s modification, and `t -> z | 0 | renamed` remains unstaged.
So `-a` stages neither half of a rename: the new name reads as a new table (which `-a` never stages), and the old name's deletion is evidently also skipped.
## What git does (verified)
```
$ git init; echo data > old.txt; git add -A; git commit -m c1
$ mv old.txt new.txt
$ git commit -am "rename via -a"
[main ed83ed9] rename via -a
1 file changed, 1 deletion(-)
delete mode 100644 old.txt
$ git status --short
?? new.txt
$ git ls-tree --name-only HEAD
(empty)
```
Git commits **the deletion half only**: HEAD's tree no longer contains the file at all, and the renamed file is left untracked. Git can do this because files have no identity — a rename at the index level is a tracked deletion plus an untracked path.
## Why neither behavior seems right for tables
- Git's literal behavior translated to tables would commit a point in history where the table and its rows do not exist, with the "rename" appearing later as a re-creation. For a database that reads as data loss at that commit.
- Dolt's current behavior is safer but surprising: Dolt's own status models the rename as **one object** (`renamed: t -> t2`), yet `-a` silently declines to stage it, and a lone rename makes `dolt_commit -am` fail with nothing to commit.
Since Dolt tables have identity (unlike git files), the natural semantics for `-a` would be to stage the **whole rename** — treat it as a modification of one object, the same way status already renders it — rather than either skipping it (current) or committing only the drop half (git-literal).
## Context
Found while aligning DoltLite's `dolt_commit -a` with Dolt as the semantics oracle: DoltLite previously committed the drop half (git-like), which erased the table from the committed history; it now matches Dolt's skip-the-rename behavior. If Dolt moves to staging whole renames under `-a`, DoltLite will follow.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by locating the implementation and tests for `dolt_commit -a` staging, then reproduce the SQL table-rename case described in the issue. Define the expected behavior for a rename-only commit and verify that the full rename is staged and committed without leaving either half unstaged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, go, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100