feat(vcs): Support several git repositories in one project (multi-root)

Only the repository containing the project root was known, so nested clones and
submodules (or a folder of side-by-side service repositories) showed no changes and
could not be committed or pushed. The project now has IDEA's VCS roots: the enclosing
repository plus those found below the project (scanned in the background, rescanned when
a .git appears or goes). Status covers all of them; path-based commands go to the file's
repository and repository-scoped ones take the selected repository.

The Commit view groups changes by repository and commits each one with included changes;
the branch widget names the selected repository and switches between them; Update Project
and Fetch run in every repository; Push lists every repository with outgoing commits; a
repository that stops in a merge or rebase is selected so Continue / Abort act on it.

Closes #12
Цей коміт міститься в:
l0ng-ai committed 2026-10-23 23:15:09 +08:00
1 джерело 0f7008391c
коміт 059a5193ff
32 files changed
+1087 -169

No files matched your search

+1 -1
Переглянути файл
@@ -71,7 +71,7 @@ function CreateDialog(props: {
useEffect(() => {
let alive = true;
// Base candidates: branches of the remotes (without `origin/`), the default first.
call(commands.vcsBranches())
call(commands.vcsBranches(null))
.then((branches) => {
const names = new Set<string>();
if (props.defaultBase) names.add(props.defaultBase);
+1 -1
Переглянути файл
@@ -89,7 +89,7 @@ export async function createPullRequest() {
let needsPush = true;
let title = "";
try {
const info = await call(commands.vcsBranchInfo());
const info = await call(commands.vcsBranchInfo(null));
head = info.head;
needsPush = !info.upstream || info.ahead > 0;
if (head) title = head.replace(/^[^/]+\//, "").replace(/[-_]+/g, " ").replace(/^\w/, (c) => c.toUpperCase());