Hi Team,
I believe I found a reproducible bug where **project stage** works correctly in a normal Git checkout, but fails when executed inside a Git worktree.
It looks like SQLcl Project does not correctly detect modified files when the working directory is a Git worktree.
Below is a complete test script you can paste into SQLcl to reproduce the issue.
1. Why this matters
Git worktrees allow developers to open and work in multiple branches at the same time — each in its own directory — without constantly stashing, committing unfinished work, or switching back and forth.
Because SQLcl Project currently does not work inside a worktree:
- I cannot open several branches at the same time for parallel development.
- I have to constantly switch the same working directory between branches, which is slow and error-prone.
- This breaks typical multi-branch workflows (feature development + hotfix + customer-specific branch, etc.).
- Worktrees are a standard Git feature and widely used in modern CI/CD setups.
Supporting Git worktrees would significantly improve developer productivity when working with SQLcl Project.
2. Setup (normal Git repo)
-- connect as DBA
create user wt identified by oracle;
grant connect, resource to wt;
conn wt/oracle@//localhost:1521/freepdb1
create function f1 return number as begin return 1; end;
/
project init -name wt -directory wt -schemas wt
cd wt
!git init -b main
project export -o f1
!git commit -m "init"
Verify baseline:
!cat src/database/wt/functions/f1.sql
3. Local branch workflow (works correctly)
!git checkout -b local
create or replace function f1 return number as begin return 2; end;
/
proj export -o wt.f1
!git commit -m 'local-change'
project stage
!git commit -m "local-stage"
SQLcl Project correctly detects changes:
!git diff main -- src/database
And stages them into dist:
!git diff --name-only main -- dist
dist/install.sql
dist/releases/main.changelog.xml
dist/releases/next/changes/local/stage.changelog.xml
dist/releases/next/changes/local/wt/functions/f1.sql
dist/releases/next/release.changelog.xml
dist/utils/prechecks.sql
dist/utils/recompile.sql
✔ Everything works as expected in a normal branch. Note **dist/releases/next/changes/local/wt/functions/f1.sql**
4. Git worktree workflow (this fails)
!git switch main
!git worktree add ../wt-tree -b tree
cd ../wt-tree
Make a change:
create or replace function f1 return number as begin return 3; end;
/
proj export -o wt.f1
!git add .
!git commit -m 'tree'
Export works as expected, Git correctly sees the change:
!git diff main -- src/database
diff --git a/src/database/wt/functions/f1.sql b/src/database/wt/functions/f1.sql
index e06f97a..49c1af1 100644
--- a/src/database/wt/functions/f1.sql
+++ b/src/database/wt/functions/f1.sql
@@ -1,8 +1,8 @@
create or replace function wt.f1 return number as
begin
- return 1;
+ return 3;
end;
/
--- sqlcl_snapshot {"hash":"502b3482b828ec3642f69e31d7b4e3c7a09b550d","type":"FUNCTION","name":"F1","schemaName":"WT","sxml":""}
\ No newline at end of file
+-- sqlcl_snapshot {"hash":"2a37c4cb3fc31d7f7ec0fd74887c7b10e29e38b7","type":"FUNCTION","name":"F1","schemaName":"WT","sxml":""}
\ No newline at end of file
5. Run **project stage** inside worktree
proj stage -v
Then check dist:
!git diff --name-only main -- dist
Problem: the object-level change is NOT staged
Output:
dist/install.sql
dist/releases/main.changelog.xml
dist/releases/next/changes/tree/stage.changelog.xml
dist/releases/next/release.changelog.xml
dist/utils/prechecks.sql
dist/utils/recompile.sql
❌ No wt/functions/f1.sql in dist/releases/next/changes/tree/
❌ Only empty stage changelog is generated
❌ SQLcl Project ignores all changed objects in the worktree
6. Summary of the issue
proj export works inside worktree
- Git correctly detects modified files
- But
**project stage** fails to detect changed objects when inside a Git worktree
- Same workflow works perfectly in a normal checkout
- As a result, I cannot have multiple branches open at the same time, which is very inconvenient for real development workflows ( if in doubt ask APEX Development Team :) - they use worktrees a lot!)
7. Likely root cause
Git worktrees use a different .git layout:
- Normal repo:
.git/ is a directory
- Worktree:
.git is a file pointing to the shared Git directory
If SQLcl Project assumes .git/ is always a directory, path resolution will be wrong.
This was tested on
SQL> version
Oracle SQLDeveloper Command-Line (SQLcl) version: 25.3.0.0 build: 25.3.0.274.1210
Many thanks,
Alex