diff options
Diffstat (limited to 'src/libfetchers/git.cc')
-rw-r--r-- | src/libfetchers/git.cc | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 7c18cf67f..210e29193 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -79,6 +79,63 @@ struct GitInput : Input return attrs; } + void clone(const Path & destDir) const override + { + auto [isLocal, actualUrl] = getActualUrl(); + + Strings args = {"clone"}; + + args.push_back(actualUrl); + + if (ref) { + args.push_back("--branch"); + args.push_back(*ref); + } + + if (rev) throw Error("cloning a specific revision is not implemented"); + + args.push_back(destDir); + + runProgram("git", true, args); + } + + std::shared_ptr<const Input> applyOverrides( + std::optional<std::string> ref, + std::optional<Hash> rev) const override + { + if (!ref && !rev) return shared_from_this(); + + auto res = std::make_shared<GitInput>(*this); + + if (ref) res->ref = ref; + if (rev) res->rev = rev; + + if (!res->ref && res->rev) + throw Error("Git input '%s' has a commit hash but no branch/tag name", res->to_string()); + + return res; + } + + std::optional<Path> getSourcePath() const override + { + if (url.scheme == "file" && !ref && !rev) + return url.path; + return {}; + } + + void markChangedFile(std::string_view file, std::optional<std::string> commitMsg) const override + { + auto sourcePath = getSourcePath(); + assert(sourcePath); + + runProgram("git", true, + { "-C", *sourcePath, "add", "--force", "--intent-to-add", std::string(file) }); + + if (commitMsg) + runProgram("git", true, + { "-C", *sourcePath, "commit", std::string(file), "-m", *commitMsg }); + } + std::pair<bool, std::string> getActualUrl() const { // Don't clone file:// URIs (but otherwise treat them the |