diff --git a/src/Commands/Add.cs b/src/Commands/Add.cs index 210eb4b28..9bd576359 100644 --- a/src/Commands/Add.cs +++ b/src/Commands/Add.cs @@ -13,14 +13,14 @@ public Add(string repo, Models.Change change) { WorkingDirectory = repo; Context = repo; - Args = $"add -- \"{change.Path}\""; + Args = $"add -- {change.Path.Quoted()}"; } public Add(string repo, string pathspecFromFile) { WorkingDirectory = repo; Context = repo; - Args = $"add --pathspec-from-file=\"{pathspecFromFile}\""; + Args = $"add --pathspec-from-file={pathspecFromFile.Quoted()}"; } } } diff --git a/src/Commands/Apply.cs b/src/Commands/Apply.cs index d1c9ffbcc..189d43359 100644 --- a/src/Commands/Apply.cs +++ b/src/Commands/Apply.cs @@ -13,7 +13,7 @@ public Apply(string repo, string file, bool ignoreWhitespace, string whitespaceM Args += $"--whitespace={whitespaceMode} "; if (!string.IsNullOrEmpty(extra)) Args += $"{extra} "; - Args += $"\"{file}\""; + Args += $"{file.Quoted()}"; } } } diff --git a/src/Commands/Archive.cs b/src/Commands/Archive.cs index 5e0919f7d..e2214aac8 100644 --- a/src/Commands/Archive.cs +++ b/src/Commands/Archive.cs @@ -6,7 +6,7 @@ public Archive(string repo, string revision, string saveTo) { WorkingDirectory = repo; Context = repo; - Args = $"archive --format=zip --verbose --output=\"{saveTo}\" {revision}"; + Args = $"archive --format=zip --verbose --output={saveTo.Quoted()} {revision}"; } } } diff --git a/src/Commands/AssumeUnchanged.cs b/src/Commands/AssumeUnchanged.cs index 28f782807..2ddaa3c33 100644 --- a/src/Commands/AssumeUnchanged.cs +++ b/src/Commands/AssumeUnchanged.cs @@ -8,7 +8,7 @@ public AssumeUnchanged(string repo, string file, bool bAdd) WorkingDirectory = repo; Context = repo; - Args = $"update-index {mode} -- \"{file}\""; + Args = $"update-index {mode} -- {file.Quoted()}"; } } } diff --git a/src/Commands/Blame.cs b/src/Commands/Blame.cs index bd2c6df84..92753ac18 100644 --- a/src/Commands/Blame.cs +++ b/src/Commands/Blame.cs @@ -14,7 +14,7 @@ public Blame(string repo, string file, string revision) { WorkingDirectory = repo; Context = repo; - Args = $"blame -t {revision} -- \"{file}\""; + Args = $"blame -t {revision} -- {file.Quoted()}"; RaiseError = false; _result.File = file; diff --git a/src/Commands/Checkout.cs b/src/Commands/Checkout.cs index 1aeff8706..23cbd413b 100644 --- a/src/Commands/Checkout.cs +++ b/src/Commands/Checkout.cs @@ -51,11 +51,7 @@ public async Task UseTheirsAsync(List files) var builder = new StringBuilder(); builder.Append("checkout --theirs --"); foreach (var f in files) - { - builder.Append(" \""); - builder.Append(f); - builder.Append("\""); - } + builder.Append(' ').Append(f.Quoted()); Args = builder.ToString(); return await ExecAsync().ConfigureAwait(false); } @@ -65,11 +61,7 @@ public async Task UseMineAsync(List files) var builder = new StringBuilder(); builder.Append("checkout --ours --"); foreach (var f in files) - { - builder.Append(" \""); - builder.Append(f); - builder.Append("\""); - } + builder.Append(' ').Append(f.Quoted()); Args = builder.ToString(); return await ExecAsync().ConfigureAwait(false); @@ -77,7 +69,7 @@ public async Task UseMineAsync(List files) public async Task FileWithRevisionAsync(string file, string revision) { - Args = $"checkout --no-overlay {revision} -- \"{file}\""; + Args = $"checkout --no-overlay {revision} -- {file.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } } diff --git a/src/Commands/Command.cs b/src/Commands/Command.cs index f54d24b22..b933af86f 100644 --- a/src/Commands/Command.cs +++ b/src/Commands/Command.cs @@ -187,8 +187,8 @@ private ProcessStartInfo CreateGitStartInfo(bool redirect) // Force using this app as git editor. start.Arguments += Editor switch { - EditorType.CoreEditor => $"""-c core.editor="\"{selfExecFile}\" --core-editor" """, - EditorType.RebaseEditor => $"""-c core.editor="\"{selfExecFile}\" --rebase-message-editor" -c sequence.editor="\"{selfExecFile}\" --rebase-todo-editor" -c rebase.abbreviateCommands=true """, + EditorType.CoreEditor => $"""-c core.editor="{selfExecFile.Quoted()} --core-editor" """, + EditorType.RebaseEditor => $"""-c core.editor="{selfExecFile.Quoted()} --rebase-message-editor" -c sequence.editor="{selfExecFile.Quoted()} --rebase-todo-editor" -c rebase.abbreviateCommands=true """, _ => "-c core.editor=true ", }; diff --git a/src/Commands/Commit.cs b/src/Commands/Commit.cs index 02c4ba899..41d650f76 100644 --- a/src/Commands/Commit.cs +++ b/src/Commands/Commit.cs @@ -12,7 +12,7 @@ public Commit(string repo, string message, bool signOff, bool amend, bool resetA WorkingDirectory = repo; Context = repo; - Args = $"commit --allow-empty --file=\"{_tmpFile}\""; + Args = $"commit --allow-empty --file={_tmpFile.Quoted()}"; if (signOff) Args += " --signoff"; if (amend) diff --git a/src/Commands/CompareRevisions.cs b/src/Commands/CompareRevisions.cs index 634d98c91..7951e6adf 100644 --- a/src/Commands/CompareRevisions.cs +++ b/src/Commands/CompareRevisions.cs @@ -27,7 +27,7 @@ public CompareRevisions(string repo, string start, string end, string path) Context = repo; var based = string.IsNullOrEmpty(start) ? "-R" : start; - Args = $"diff --name-status {based} {end} -- \"{path}\""; + Args = $"diff --name-status {based} {end} -- {path.Quoted()}"; } public async Task> ReadAsync() diff --git a/src/Commands/Config.cs b/src/Commands/Config.cs index 84858454a..0348c5109 100644 --- a/src/Commands/Config.cs +++ b/src/Commands/Config.cs @@ -55,7 +55,7 @@ public async Task SetAsync(string key, string value, bool allowEmpty = fal if (!allowEmpty && string.IsNullOrWhiteSpace(value)) Args = $"config {scope} --unset {key}"; else - Args = $"config {scope} {key} \"{value}\""; + Args = $"config {scope} {key} {value.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } diff --git a/src/Commands/DiffTool.cs b/src/Commands/DiffTool.cs index abed00b00..b80f55959 100644 --- a/src/Commands/DiffTool.cs +++ b/src/Commands/DiffTool.cs @@ -28,7 +28,8 @@ public void Open() } else if (File.Exists(_exec)) { - Args = $"-c difftool.sourcegit.cmd=\"\\\"{_exec}\\\" {_merger.DiffCmd}\" difftool --tool=sourcegit --no-prompt {_option}"; + var cmd = $"{_exec.Quoted()} {_merger.DiffCmd}"; + Args = $"-c difftool.sourcegit.cmd={cmd.Quoted()} difftool --tool=sourcegit --no-prompt {_option}"; } else { diff --git a/src/Commands/FormatPatch.cs b/src/Commands/FormatPatch.cs index bf850d60a..cf97f8b07 100644 --- a/src/Commands/FormatPatch.cs +++ b/src/Commands/FormatPatch.cs @@ -7,7 +7,7 @@ public FormatPatch(string repo, string commit, string saveTo) WorkingDirectory = repo; Context = repo; Editor = EditorType.None; - Args = $"format-patch {commit} -1 --output=\"{saveTo}\""; + Args = $"format-patch {commit} -1 --output={saveTo.Quoted()}"; } } } diff --git a/src/Commands/IsBinary.cs b/src/Commands/IsBinary.cs index 5c3e5673e..0e60f38c6 100644 --- a/src/Commands/IsBinary.cs +++ b/src/Commands/IsBinary.cs @@ -12,7 +12,7 @@ public IsBinary(string repo, string commit, string path) { WorkingDirectory = repo; Context = repo; - Args = $"diff {Models.Commit.EmptyTreeSHA1} {commit} --numstat -- \"{path}\""; + Args = $"diff {Models.Commit.EmptyTreeSHA1} {commit} --numstat -- {path.Quoted()}"; RaiseError = false; } diff --git a/src/Commands/IsLFSFiltered.cs b/src/Commands/IsLFSFiltered.cs index ee716761c..e8e5513ca 100644 --- a/src/Commands/IsLFSFiltered.cs +++ b/src/Commands/IsLFSFiltered.cs @@ -8,7 +8,7 @@ public IsLFSFiltered(string repo, string path) { WorkingDirectory = repo; Context = repo; - Args = $"check-attr -z filter \"{path}\""; + Args = $"check-attr -z filter {path.Quoted()}"; RaiseError = false; } @@ -16,7 +16,7 @@ public IsLFSFiltered(string repo, string sha, string path) { WorkingDirectory = repo; Context = repo; - Args = $"check-attr --source {sha} -z filter \"{path}\""; + Args = $"check-attr --source {sha} -z filter {path.Quoted()}"; RaiseError = false; } diff --git a/src/Commands/LFS.cs b/src/Commands/LFS.cs index 30f06e5f0..098f1207e 100644 --- a/src/Commands/LFS.cs +++ b/src/Commands/LFS.cs @@ -50,7 +50,7 @@ public async Task InstallAsync(Models.ICommandLog log) public async Task TrackAsync(string pattern, bool isFilenameMode, Models.ICommandLog log) { var opt = isFilenameMode ? "--filename" : ""; - return await new SubCmd(_repo, $"lfs track {opt} \"{pattern}\"", log).ExecAsync().ConfigureAwait(false); + return await new SubCmd(_repo, $"lfs track {opt} {pattern.Quoted()}", log).ExecAsync().ConfigureAwait(false); } public async Task FetchAsync(string remote, Models.ICommandLog log) @@ -101,13 +101,13 @@ public async Task PruneAsync(Models.ICommandLog log) public async Task LockAsync(string remote, string file, Models.ICommandLog log) { - return await new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", log).ExecAsync().ConfigureAwait(false); + return await new SubCmd(_repo, $"lfs lock --remote={remote} {file.Quoted()}", log).ExecAsync().ConfigureAwait(false); } public async Task UnlockAsync(string remote, string file, bool force, Models.ICommandLog log) { var opt = force ? "-f" : ""; - return await new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", log).ExecAsync().ConfigureAwait(false); + return await new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} {file.Quoted()}", log).ExecAsync().ConfigureAwait(false); } public async Task UnlockAsync(string remote, long id, bool force, Models.ICommandLog log) diff --git a/src/Commands/Merge.cs b/src/Commands/Merge.cs index 328985935..bd11b5779 100644 --- a/src/Commands/Merge.cs +++ b/src/Commands/Merge.cs @@ -29,7 +29,7 @@ public Merge(string repo, List targets, bool autoCommit, string strategy var builder = new StringBuilder(); builder.Append("merge --progress "); if (!string.IsNullOrEmpty(strategy)) - builder.Append($"--strategy={strategy} "); + builder.Append("--strategy=").Append(strategy).Append(' '); if (!autoCommit) builder.Append("--no-commit "); diff --git a/src/Commands/MergeTool.cs b/src/Commands/MergeTool.cs index f46883179..e99d02cab 100644 --- a/src/Commands/MergeTool.cs +++ b/src/Commands/MergeTool.cs @@ -12,7 +12,7 @@ public MergeTool(string repo, int type, string exec, string file) _merger = Models.ExternalMerger.Supported.Find(x => x.Type == type); _exec = exec; - _file = string.IsNullOrEmpty(file) ? "" : $"\"{file}\""; + _file = string.IsNullOrEmpty(file) ? "" : $"{file.Quoted()}"; } public async Task OpenAsync() @@ -29,7 +29,8 @@ public async Task OpenAsync() } else if (File.Exists(_exec)) { - Args = $"-c mergetool.sourcegit.cmd=\"\\\"{_exec}\\\" {_merger.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {_file}"; + var cmd = $"{_exec.Quoted()} {_merger.Cmd}"; + Args = $"-c mergetool.sourcegit.cmd={cmd.Quoted()} -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {_file}"; } else { diff --git a/src/Commands/Move.cs b/src/Commands/Move.cs index ca719cd73..566f984f9 100644 --- a/src/Commands/Move.cs +++ b/src/Commands/Move.cs @@ -13,11 +13,9 @@ public Move(string repo, string oldPath, string newPath, bool force) builder.Append("mv -v "); if (force) builder.Append("-f "); - builder.Append('"'); - builder.Append(oldPath); - builder.Append("\" \""); - builder.Append(newPath); - builder.Append('"'); + builder.Append(oldPath.Quoted()); + builder.Append(' '); + builder.Append(newPath.Quoted()); Args = builder.ToString(); } diff --git a/src/Commands/QueryCommits.cs b/src/Commands/QueryCommits.cs index 9493b3399..311406bdc 100644 --- a/src/Commands/QueryCommits.cs +++ b/src/Commands/QueryCommits.cs @@ -21,11 +21,11 @@ public QueryCommits(string repo, string filter, Models.CommitSearchMethod method if (method == Models.CommitSearchMethod.ByAuthor) { - search += $"-i --author=\"{filter}\""; + search += $"-i --author={filter.Quoted()}"; } else if (method == Models.CommitSearchMethod.ByCommitter) { - search += $"-i --committer=\"{filter}\""; + search += $"-i --committer={filter.Quoted()}"; } else if (method == Models.CommitSearchMethod.ByMessage) { @@ -34,21 +34,18 @@ public QueryCommits(string repo, string filter, Models.CommitSearchMethod method var words = filter.Split([' ', '\t', '\r'], StringSplitOptions.RemoveEmptyEntries); foreach (var word in words) - { - var escaped = word.Trim().Replace("\"", "\\\"", StringComparison.Ordinal); - argsBuilder.Append($"--grep=\"{escaped}\" "); - } + argsBuilder.Append("--grep=").Append(word.Trim().Quoted()).Append(' '); argsBuilder.Append("--all-match -i"); search = argsBuilder.ToString(); } else if (method == Models.CommitSearchMethod.ByPath) { - search += $"-- \"{filter}\""; + search += $"-- {filter.Quoted()}"; } else { - search = $"-G\"{filter}\""; + search = $"-G{filter.Quoted()}"; } WorkingDirectory = repo; @@ -126,7 +123,7 @@ private void ParseParent(string data) private async Task MarkFirstMergedAsync() { - Args = $"log --since=\"{_commits[^1].CommitterTimeStr}\" --format=\"%H\""; + Args = $"log --since={_commits[^1].CommitterTimeStr.Quoted()} --format=\"%H\""; var rs = await ReadToEndAsync().ConfigureAwait(false); var shas = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); diff --git a/src/Commands/QueryFileContent.cs b/src/Commands/QueryFileContent.cs index 0bb8605ae..41cf63836 100644 --- a/src/Commands/QueryFileContent.cs +++ b/src/Commands/QueryFileContent.cs @@ -12,7 +12,7 @@ public static async Task RunAsync(string repo, string revision, string f var starter = new ProcessStartInfo(); starter.WorkingDirectory = repo; starter.FileName = Native.OS.GitExecutable; - starter.Arguments = $"show {revision}:\"{file}\""; + starter.Arguments = $"show {revision}:{file.Quoted()}"; starter.UseShellExecute = false; starter.CreateNoWindow = true; starter.WindowStyle = ProcessWindowStyle.Hidden; diff --git a/src/Commands/QueryFileSize.cs b/src/Commands/QueryFileSize.cs index 1371df8b4..c1ad51dfe 100644 --- a/src/Commands/QueryFileSize.cs +++ b/src/Commands/QueryFileSize.cs @@ -12,7 +12,7 @@ public QueryFileSize(string repo, string file, string revision) { WorkingDirectory = repo; Context = repo; - Args = $"ls-tree {revision} -l -- \"{file}\""; + Args = $"ls-tree {revision} -l -- {file.Quoted()}"; } public async Task GetResultAsync() diff --git a/src/Commands/QueryRevisionObjects.cs b/src/Commands/QueryRevisionObjects.cs index d963d8b9f..9657c7c7e 100644 --- a/src/Commands/QueryRevisionObjects.cs +++ b/src/Commands/QueryRevisionObjects.cs @@ -17,7 +17,7 @@ public QueryRevisionObjects(string repo, string sha, string parentFolder) Args = $"ls-tree {sha}"; if (!string.IsNullOrEmpty(parentFolder)) - Args += $" -- \"{parentFolder}\""; + Args += $" -- {parentFolder.Quoted()}"; } public async Task> GetResultAsync() diff --git a/src/Commands/QueryStagedFileBlobGuid.cs b/src/Commands/QueryStagedFileBlobGuid.cs index b69100340..54ecd2ac7 100644 --- a/src/Commands/QueryStagedFileBlobGuid.cs +++ b/src/Commands/QueryStagedFileBlobGuid.cs @@ -12,7 +12,7 @@ public QueryStagedFileBlobGuid(string repo, string file) { WorkingDirectory = repo; Context = repo; - Args = $"ls-files -s -- \"{file}\""; + Args = $"ls-files -s -- {file.Quoted()}"; } public async Task GetResultAsync() diff --git a/src/Commands/QuerySubmodules.cs b/src/Commands/QuerySubmodules.cs index d17efb971..6063b3cf8 100644 --- a/src/Commands/QuerySubmodules.cs +++ b/src/Commands/QuerySubmodules.cs @@ -125,11 +125,7 @@ public QuerySubmodules(string repo) foreach (var kv in map) { if (kv.Value.Status == Models.SubmoduleStatus.Normal) - { - builder.Append('"'); - builder.Append(kv.Key); - builder.Append("\" "); - } + builder.Append(kv.Key.Quoted()).Append(' '); } Args = $"--no-optional-locks status --porcelain -- {builder}"; diff --git a/src/Commands/Restore.cs b/src/Commands/Restore.cs index 663ea975a..e2f9aa09a 100644 --- a/src/Commands/Restore.cs +++ b/src/Commands/Restore.cs @@ -15,16 +15,10 @@ public Restore(string repo, Models.Change stagedChange) Context = repo; var builder = new StringBuilder(); - builder.Append("restore --staged -- \""); - builder.Append(stagedChange.Path); - builder.Append('"'); + builder.Append("restore --staged -- ").Append(stagedChange.Path.Quoted()); if (stagedChange.Index == Models.ChangeState.Renamed) - { - builder.Append(" \""); - builder.Append(stagedChange.OriginalPath); - builder.Append('"'); - } + builder.Append(' ').Append(stagedChange.OriginalPath.Quoted()); Args = builder.ToString(); } @@ -43,9 +37,7 @@ public Restore(string repo, string pathspecFile, bool isStaged) var builder = new StringBuilder(); builder.Append("restore "); builder.Append(isStaged ? "--staged " : "--worktree --recurse-submodules "); - builder.Append("--pathspec-from-file=\""); - builder.Append(pathspecFile); - builder.Append('"'); + builder.Append("--pathspec-from-file=").Append(pathspecFile.Quoted()); Args = builder.ToString(); } diff --git a/src/Commands/SaveRevisionFile.cs b/src/Commands/SaveRevisionFile.cs index 86b4d4268..a3ca373f8 100644 --- a/src/Commands/SaveRevisionFile.cs +++ b/src/Commands/SaveRevisionFile.cs @@ -21,7 +21,7 @@ public static async Task RunAsync(string repo, string revision, string file, str } else { - await ExecCmdAsync(repo, $"show {revision}:\"{file}\"", saveTo).ConfigureAwait(false); + await ExecCmdAsync(repo, $"show {revision}:{file.Quoted()}", saveTo).ConfigureAwait(false); } } diff --git a/src/Commands/Stash.cs b/src/Commands/Stash.cs index 9774ed563..ef8bbe087 100644 --- a/src/Commands/Stash.cs +++ b/src/Commands/Stash.cs @@ -20,9 +20,7 @@ public async Task PushAsync(string message, bool includeUntracked = true, builder.Append("--include-untracked "); if (keepIndex) builder.Append("--keep-index "); - builder.Append("-m \""); - builder.Append(message); - builder.Append("\""); + builder.Append("-m ").Append(message.Quoted()); Args = builder.ToString(); return await ExecAsync().ConfigureAwait(false); @@ -34,12 +32,10 @@ public async Task PushAsync(string message, List changes, b builder.Append("stash push --include-untracked "); if (keepIndex) builder.Append("--keep-index "); - builder.Append("-m \""); - builder.Append(message); - builder.Append("\" -- "); + builder.Append("-m ").Append(message).Append(" -- "); foreach (var c in changes) - builder.Append($"\"{c.Path}\" "); + builder.Append(c.Path.Quoted()).Append(' '); Args = builder.ToString(); return await ExecAsync().ConfigureAwait(false); @@ -48,14 +44,10 @@ public async Task PushAsync(string message, List changes, b public async Task PushAsync(string message, string pathspecFromFile, bool keepIndex) { var builder = new StringBuilder(); - builder.Append("stash push --include-untracked --pathspec-from-file=\""); - builder.Append(pathspecFromFile); - builder.Append("\" "); + builder.Append("stash push --include-untracked --pathspec-from-file=").Append(pathspecFromFile.Quoted()).Append(" "); if (keepIndex) builder.Append("--keep-index "); - builder.Append("-m \""); - builder.Append(message); - builder.Append("\""); + builder.Append("-m ").Append(message.Quoted()); Args = builder.ToString(); return await ExecAsync().ConfigureAwait(false); @@ -67,9 +59,7 @@ public async Task PushOnlyStagedAsync(string message, bool keepIndex) builder.Append("stash push --staged "); if (keepIndex) builder.Append("--keep-index "); - builder.Append("-m \""); - builder.Append(message); - builder.Append("\""); + builder.Append("-m ").Append(message.Quoted()); Args = builder.ToString(); return await ExecAsync().ConfigureAwait(false); } @@ -77,19 +67,19 @@ public async Task PushOnlyStagedAsync(string message, bool keepIndex) public async Task ApplyAsync(string name, bool restoreIndex) { var opts = restoreIndex ? "--index" : string.Empty; - Args = $"stash apply -q {opts} \"{name}\""; + Args = $"stash apply -q {opts} {name.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } public async Task PopAsync(string name) { - Args = $"stash pop -q --index \"{name}\""; + Args = $"stash pop -q --index {name.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } public async Task DropAsync(string name) { - Args = $"stash drop -q \"{name}\""; + Args = $"stash drop -q {name.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } diff --git a/src/Commands/StringExtensions.cs b/src/Commands/StringExtensions.cs new file mode 100644 index 000000000..f2cf37288 --- /dev/null +++ b/src/Commands/StringExtensions.cs @@ -0,0 +1,17 @@ +using System; + +namespace SourceGit.Commands +{ + public static class StringExtensions + { + public static string Quoted(this string value) + { + return $"\"{Escaped(value)}\""; + } + + public static string Escaped(this string value) + { + return value.Replace("\"", "\\\"", StringComparison.Ordinal); + } + } +} diff --git a/src/Commands/Submodule.cs b/src/Commands/Submodule.cs index ce93e0179..bb8d884ac 100644 --- a/src/Commands/Submodule.cs +++ b/src/Commands/Submodule.cs @@ -14,31 +14,31 @@ public Submodule(string repo) public async Task AddAsync(string url, string relativePath, bool recursive) { - Args = $"-c protocol.file.allow=always submodule add \"{url}\" \"{relativePath}\""; + Args = $"-c protocol.file.allow=always submodule add {url.Quoted()} {relativePath.Quoted()}"; var succ = await ExecAsync().ConfigureAwait(false); if (!succ) return false; if (recursive) - Args = $"submodule update --init --recursive -- \"{relativePath}\""; + Args = $"submodule update --init --recursive -- {relativePath.Quoted()}"; else - Args = $"submodule update --init -- \"{relativePath}\""; + Args = $"submodule update --init -- {relativePath.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } public async Task SetURLAsync(string path, string url) { - Args = $"submodule set-url -- \"{path}\" \"{url}\""; + Args = $"submodule set-url -- {path.Quoted()} {url.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } public async Task SetBranchAsync(string path, string branch) { if (string.IsNullOrEmpty(branch)) - Args = $"submodule set-branch -d -- \"{path}\""; + Args = $"submodule set-branch -d -- {path.Quoted()}"; else - Args = $"submodule set-branch -b \"{branch}\" -- \"{path}\""; + Args = $"submodule set-branch -b {branch.Quoted()} -- {path.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } @@ -58,7 +58,7 @@ public async Task UpdateAsync(List modules, bool init, bool recurs { builder.Append(" --"); foreach (var module in modules) - builder.Append($" \"{module}\""); + builder.Append(' ').Append(module.Quoted()); } Args = builder.ToString(); @@ -67,13 +67,13 @@ public async Task UpdateAsync(List modules, bool init, bool recurs public async Task DeinitAsync(string module, bool force) { - Args = force ? $"submodule deinit -f -- \"{module}\"" : $"submodule deinit -- \"{module}\""; + Args = force ? $"submodule deinit -f -- {module.Quoted()}" : $"submodule deinit -- {module.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } public async Task DeleteAsync(string module) { - Args = $"rm -rf \"{module}\""; + Args = $"rm -rf {module.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } } diff --git a/src/Commands/Tag.cs b/src/Commands/Tag.cs index d372573af..4ccfc03b9 100644 --- a/src/Commands/Tag.cs +++ b/src/Commands/Tag.cs @@ -28,7 +28,7 @@ public static async Task AddAsync(string repo, string name, string basedOn { string tmp = Path.GetTempFileName(); await File.WriteAllTextAsync(tmp, message); - cmd.Args += $"-F \"{tmp}\""; + cmd.Args += $"-F {tmp.Quoted()}"; var succ = await cmd.ExecAsync().ConfigureAwait(false); File.Delete(tmp); diff --git a/src/Commands/Worktree.cs b/src/Commands/Worktree.cs index 4e6bc4e44..af03029f6 100644 --- a/src/Commands/Worktree.cs +++ b/src/Commands/Worktree.cs @@ -72,7 +72,7 @@ public async Task AddAsync(string fullpath, string name, bool createNew, s Args += $"-B {name} "; } - Args += $"\"{fullpath}\" "; + Args += $"{fullpath.Quoted()} "; if (!string.IsNullOrEmpty(tracking)) Args += tracking; @@ -90,22 +90,22 @@ public async Task PruneAsync() public async Task LockAsync(string fullpath) { - Args = $"worktree lock \"{fullpath}\""; + Args = $"worktree lock {fullpath.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } public async Task UnlockAsync(string fullpath) { - Args = $"worktree unlock \"{fullpath}\""; + Args = $"worktree unlock {fullpath.Quoted()}"; return await ExecAsync().ConfigureAwait(false); } public async Task RemoveAsync(string fullpath, bool force) { if (force) - Args = $"worktree remove -f \"{fullpath}\""; + Args = $"worktree remove -f {fullpath.Quoted()}"; else - Args = $"worktree remove \"{fullpath}\""; + Args = $"worktree remove {fullpath.Quoted()}"; return await ExecAsync().ConfigureAwait(false); }