feat(git): add advanced clone options (shallow, sparse, flags)
Add advanced clone options support across the frontend and backend. Users can specify a branch, shallow limits, blobless mode, sparse paths, and custom clone flags when initiating a clone operation. The backend validates inputs, parses custom flags without invoking a shell, and configures sparse checkouts after a successful clone. A small parsing dependency was added and tracked-file parsing was improved to better handle git ls-files output. - Introduce CloneRunOptions and validation helpers for clone inputs - Parse custom flags with a shell-like tokenizer and block managed flags - Support sparse checkout configuration and shallow clone constraints
This commit is contained in:
+10
-5
@@ -148,6 +148,7 @@
|
||||
AppLanguage,
|
||||
AppTheme,
|
||||
AnalyticsSettings,
|
||||
CloneOptions,
|
||||
CustomThemeColors,
|
||||
ConflictFile,
|
||||
DetectedExternalTool,
|
||||
@@ -233,6 +234,7 @@
|
||||
remoteUrl: string;
|
||||
parentPath: string;
|
||||
directoryName: string;
|
||||
cloneOptions?: CloneOptions;
|
||||
}
|
||||
|
||||
interface ErrorAutoHideState {
|
||||
@@ -719,7 +721,7 @@
|
||||
if (pendingStartupCloneRequest) {
|
||||
const request = pendingStartupCloneRequest;
|
||||
pendingStartupCloneRequest = null;
|
||||
await cloneRepo(request.remoteUrl, request.parentPath, request.directoryName);
|
||||
await cloneRepo(request.remoteUrl, request.parentPath, request.directoryName, undefined, undefined, undefined, false, "credentials", request.cloneOptions);
|
||||
return;
|
||||
}
|
||||
const path = pendingStartupRepoPath;
|
||||
@@ -2462,12 +2464,13 @@
|
||||
key?: string | null,
|
||||
fromStore = false,
|
||||
credentialMode: CredentialMode = "credentials",
|
||||
cloneOptions: CloneOptions = { branch: null, blobless: false, customFlags: "", shallowDepth: null, shallowSince: null, sparse: false, sparsePaths: [] },
|
||||
) {
|
||||
if (isBusy) return;
|
||||
if (!remoteUrl) { errorMessage = "Enter a remote URL."; return; }
|
||||
if (!parentPath) { errorMessage = "Select a destination folder."; return; }
|
||||
|
||||
const request: CloneRequest = { remoteUrl, parentPath, directoryName };
|
||||
const request: CloneRequest = { remoteUrl, parentPath, directoryName, cloneOptions };
|
||||
pendingClone = request;
|
||||
const credentialKey = key === undefined ? orgKeyFromUrl(remoteUrl) : key;
|
||||
|
||||
@@ -2483,7 +2486,7 @@
|
||||
credDialogOpen = true;
|
||||
return;
|
||||
}
|
||||
await cloneRepo(remoteUrl, parentPath, directoryName, stored.username, stored.password, credentialKey, true, storedMode);
|
||||
await cloneRepo(remoteUrl, parentPath, directoryName, stored.username, stored.password, credentialKey, true, storedMode, cloneOptions);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2499,6 +2502,7 @@
|
||||
username,
|
||||
password,
|
||||
COMMIT_HISTORY_PAGE_SIZE + 1,
|
||||
cloneOptions,
|
||||
);
|
||||
resetRepositoryState(false);
|
||||
await applyRepositoryBundle(bundle.status.repo_path, bundle);
|
||||
@@ -2555,9 +2559,9 @@
|
||||
trackEvent("clone_dialog_opened");
|
||||
}
|
||||
|
||||
function cloneFromDialog(remoteUrl: string, parentPath: string, directoryName: string, provider?: GitIntegrationProvider, accountId?: string) {
|
||||
function cloneFromDialog(remoteUrl: string, parentPath: string, directoryName: string, cloneOptions: CloneOptions, provider?: GitIntegrationProvider, accountId?: string) {
|
||||
const credentialKey = provider ? integrationCredentialKey(provider, accountId) : undefined;
|
||||
void cloneRepo(remoteUrl, parentPath, directoryName, undefined, undefined, credentialKey, false, provider ? "token" : "credentials");
|
||||
void cloneRepo(remoteUrl, parentPath, directoryName, undefined, undefined, credentialKey, false, provider ? "token" : "credentials", cloneOptions);
|
||||
}
|
||||
|
||||
function openRepoManagement() {
|
||||
@@ -3877,6 +3881,7 @@
|
||||
key,
|
||||
false,
|
||||
mode,
|
||||
pendingClone.cloneOptions,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user