diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index e40afb865eb..0d423a7a39f 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -69,7 +69,7 @@ std::optional readHead(const Path & path) std::string_view line = output; line = line.substr(0, line.find("\n")); - if (const auto parseResult = git::parseLsRemoteLine(line)) { + if (const auto parseResult = git::parseLsRemoteLine(line); parseResult && parseResult->reference == "HEAD") { switch (parseResult->kind) { case git::LsRemoteRefLine::Kind::Symbolic: debug("resolved HEAD ref '%s' for repo '%s'", parseResult->target, path); @@ -459,8 +459,14 @@ struct GitInputScheme : InputScheme url); } repoInfo.location = std::filesystem::absolute(url.path); - } else + } else { + if (url.scheme == "file") + /* Query parameters are meaningless for file://, but + Git interprets them as part of the file name. So get + rid of them. */ + url.query.clear(); repoInfo.location = url; + } // If this is a local directory and no ref or revision is // given, then allow the use of an unclean working tree. @@ -605,16 +611,16 @@ struct GitInputScheme : InputScheme try { auto fetchRef = getAllRefsAttr(input) - ? "refs/*" + ? "refs/*:refs/*" : input.getRev() ? input.getRev()->gitRev() : ref.compare(0, 5, "refs/") == 0 - ? ref + ? fmt("%1%:%1%", ref) : ref == "HEAD" ? ref - : "refs/heads/" + ref; + : fmt("%1%:%1%", "refs/heads/" + ref); - repo->fetch(repoUrl.to_string(), fmt("%s:%s", fetchRef, fetchRef), getShallowAttr(input)); + repo->fetch(repoUrl.to_string(), fetchRef, getShallowAttr(input)); } catch (Error & e) { if (!std::filesystem::exists(localRefFile)) throw; logError(e.info());