Skip to content

Commit 530c34c

Browse files
authored
Merge pull request #242 from DeterminateSystems/sync-2.32.2
Sync with upstream 2.32.2
2 parents 7f46b90 + 9862432 commit 530c34c

File tree

12 files changed

+114
-78
lines changed

12 files changed

+114
-78
lines changed

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.32.1
1+
2.32.2

src/libfetchers-tests/git-utils.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ TEST_F(GitUtilsTest, peel_reference)
176176

177177
TEST(GitUtils, isLegalRefName)
178178
{
179+
ASSERT_TRUE(isLegalRefName("A/b"));
180+
ASSERT_TRUE(isLegalRefName("AaA/b"));
181+
ASSERT_TRUE(isLegalRefName("FOO/BAR/BAZ"));
182+
ASSERT_TRUE(isLegalRefName("HEAD"));
183+
ASSERT_TRUE(isLegalRefName("refs/tags/1.2.3"));
184+
ASSERT_TRUE(isLegalRefName("refs/heads/master"));
179185
ASSERT_TRUE(isLegalRefName("foox"));
180186
ASSERT_TRUE(isLegalRefName("1337"));
181187
ASSERT_TRUE(isLegalRefName("foo.baz"));

src/libfetchers/git-utils.cc

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <git2/attr.h>
1717
#include <git2/blob.h>
18+
#include <git2/branch.h>
1819
#include <git2/commit.h>
1920
#include <git2/config.h>
2021
#include <git2/describe.h>
@@ -31,6 +32,7 @@
3132
#include <git2/submodule.h>
3233
#include <git2/sys/odb_backend.h>
3334
#include <git2/sys/mempack.h>
35+
#include <git2/tag.h>
3436
#include <git2/tree.h>
3537

3638
#include <boost/unordered/concurrent_flat_set.hpp>
@@ -1413,63 +1415,33 @@ GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path &
14131415
return workdirInfo;
14141416
}
14151417

1416-
/**
1417-
* Checks that the git reference is valid and normalizes slash '/' sequences.
1418-
*
1419-
* Accepts shorthand references (one-level refnames are allowed).
1420-
*/
1421-
bool isValidRefNameAllowNormalizations(const std::string & refName)
1422-
{
1423-
/* Unfortunately libgit2 doesn't expose the limit in headers, but its internal
1424-
limit is also 1024. */
1425-
std::array<char, 1024> normalizedRefBuffer;
1426-
1427-
/* It would be nice to have a better API like git_reference_name_is_valid, but
1428-
* with GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND flag. libgit2 uses it internally
1429-
* but doesn't expose it in public headers [1].
1430-
* [1]:
1431-
* https://github.com/libgit2/libgit2/blob/9d5f1bacc23594c2ba324c8f0d41b88bf0e9ef04/src/libgit2/refs.c#L1362-L1365
1432-
*/
1433-
1434-
auto res = git_reference_normalize_name(
1435-
normalizedRefBuffer.data(),
1436-
normalizedRefBuffer.size(),
1437-
refName.c_str(),
1438-
GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL | GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND);
1439-
1440-
return res == 0;
1441-
}
1442-
14431418
bool isLegalRefName(const std::string & refName)
14441419
{
14451420
initLibGit2();
14461421

1447-
/* Since `git_reference_normalize_name` is the best API libgit2 has for verifying
1448-
* reference names with shorthands (see comment in normalizeRefName), we need to
1449-
* ensure that exceptions to the validity checks imposed by normalization [1] are checked
1450-
* explicitly.
1451-
* [1]: https://git-scm.com/docs/git-check-ref-format#Documentation/git-check-ref-format.txt---normalize
1452-
*/
1453-
14541422
/* Check for cases that don't get rejected by libgit2.
14551423
* FIXME: libgit2 should reject this. */
14561424
if (refName == "@")
14571425
return false;
14581426

1459-
/* Leading slashes and consecutive slashes are stripped during normalizatiton. */
1460-
if (refName.starts_with('/') || refName.find("//") != refName.npos)
1461-
return false;
1462-
1463-
/* Refer to libgit2. */
1464-
if (!isValidRefNameAllowNormalizations(refName))
1465-
return false;
1466-
14671427
/* libgit2 doesn't barf on DEL symbol.
14681428
* FIXME: libgit2 should reject this. */
14691429
if (refName.find('\177') != refName.npos)
14701430
return false;
14711431

1472-
return true;
1432+
for (auto * func : {
1433+
git_reference_name_is_valid,
1434+
git_branch_name_is_valid,
1435+
git_tag_name_is_valid,
1436+
}) {
1437+
int valid = 0;
1438+
if (func(&valid, refName.c_str()))
1439+
throw Error("checking git reference '%s': %s", refName, git_error_last()->message);
1440+
if (valid)
1441+
return true;
1442+
}
1443+
1444+
return false;
14731445
}
14741446

14751447
} // namespace nix

src/libfetchers/git.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,36 @@ struct GitInputScheme : InputScheme
498498
Git interprets them as part of the file name. So get
499499
rid of them. */
500500
url.query.clear();
501+
/* Backward compatibility hack: In old versions of Nix, if you had
502+
a flake input like
503+
504+
inputs.foo.url = "git+https://foo/bar?dir=subdir";
505+
506+
it would result in a lock file entry like
507+
508+
"original": {
509+
"dir": "subdir",
510+
"type": "git",
511+
"url": "https://foo/bar?dir=subdir"
512+
}
513+
514+
New versions of Nix remove `?dir=subdir` from the `url` field,
515+
since the subdirectory is intended for `FlakeRef`, not the
516+
fetcher (and specifically the remote server), that is, the
517+
flakeref is parsed into
518+
519+
"original": {
520+
"dir": "subdir",
521+
"type": "git",
522+
"url": "https://foo/bar"
523+
}
524+
525+
However, new versions of nix parsing old flake.lock files would pass the dir=
526+
query parameter in the "url" attribute to git, which will then complain.
527+
528+
For this reason, we are filtering the `dir` query parameter from the URL
529+
before passing it to git. */
530+
url.query.erase("dir");
501531
repoInfo.location = url;
502532
}
503533

src/libfetchers/include/nix/fetchers/git-utils.hh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,12 @@ struct Setter
156156
};
157157

158158
/**
159-
* Checks that the git reference is valid and normalized.
159+
* Checks that the string can be a valid git reference, branch or tag name.
160+
* Accepts shorthand references (one-level refnames are allowed), pseudorefs
161+
* like `HEAD`.
160162
*
161-
* Accepts shorthand references (one-level refnames are allowed).
163+
* @note This is a coarse test to make sure that the refname is at least something
164+
* that Git can make sense of.
162165
*/
163166
bool isLegalRefName(const std::string & refName);
164167

src/libmain/shared.cc

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -325,34 +325,29 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
325325
std::string error = ANSI_RED "error:" ANSI_NORMAL " ";
326326
try {
327327
try {
328-
try {
329-
fun();
330-
} catch (...) {
331-
/* Subtle: we have to make sure that any `interrupted'
332-
condition is discharged before we reach printMsg()
333-
below, since otherwise it will throw an (uncaught)
334-
exception. */
335-
setInterruptThrown();
336-
throw;
337-
}
338-
} catch (Exit & e) {
339-
return e.status;
340-
} catch (UsageError & e) {
341-
logError(e.info());
342-
printError("\nTry '%1% --help' for more information.", programName);
343-
return 1;
344-
} catch (BaseError & e) {
345-
logError(e.info());
346-
return e.info().status;
347-
} catch (std::bad_alloc & e) {
348-
printError(error + "out of memory");
349-
return 1;
350-
} catch (std::exception & e) {
351-
printError(error + e.what());
352-
return 1;
328+
fun();
329+
} catch (...) {
330+
/* Subtle: we have to make sure that any `interrupted'
331+
condition is discharged before we reach printMsg()
332+
below, since otherwise it will throw an (uncaught)
333+
exception. */
334+
setInterruptThrown();
335+
throw;
353336
}
354-
} catch (...) {
355-
/* In case logger also throws just give up. */
337+
} catch (Exit & e) {
338+
return e.status;
339+
} catch (UsageError & e) {
340+
logError(e.info());
341+
printError("\nTry '%1% --help' for more information.", programName);
342+
return 1;
343+
} catch (BaseError & e) {
344+
logError(e.info());
345+
return e.info().status;
346+
} catch (std::bad_alloc & e) {
347+
printError(error + "out of memory");
348+
return 1;
349+
} catch (std::exception & e) {
350+
printError(error + e.what());
356351
return 1;
357352
}
358353

src/libstore/include/nix/store/serve-protocol-connection.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ struct ServeProto::BasicClientConnection
8282
BuildResult getBuildDerivationResponse(const StoreDirConfig & store);
8383

8484
void narFromPath(const StoreDirConfig & store, const StorePath & path, std::function<void(Source &)> fun);
85+
86+
void importPaths(const StoreDirConfig & store, std::function<void(Sink &)> fun);
8587
};
8688

8789
struct ServeProto::BasicServerConnection

src/libstore/include/nix/store/serve-protocol.hh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,13 @@ enum struct ServeProto::Command : uint64_t {
108108
QueryValidPaths = 1,
109109
QueryPathInfos = 2,
110110
DumpStorePath = 3,
111-
// ImportPaths = 4, // removed
112-
// ExportPaths = 5, // removed
111+
/**
112+
* @note This is no longer used by Nix (as a client), but it is used
113+
* by Hydra. We should therefore not remove it until Hydra no longer
114+
* uses it either.
115+
*/
116+
ImportPaths = 4,
117+
// ExportPaths = 5,
113118
BuildPaths = 6,
114119
QueryClosure = 7,
115120
BuildDerivation = 8,

src/libstore/serve-protocol-connection.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,14 @@ void ServeProto::BasicClientConnection::narFromPath(
9393
fun(from);
9494
}
9595

96+
void ServeProto::BasicClientConnection::importPaths(const StoreDirConfig & store, std::function<void(Sink &)> fun)
97+
{
98+
to << ServeProto::Command::ImportPaths;
99+
fun(to);
100+
to.flush();
101+
102+
if (readInt(from) != 1)
103+
throw Error("remote machine failed to import closure");
104+
}
105+
96106
} // namespace nix

src/libstore/unix/build/derivation-builder.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,7 +1722,6 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
17221722
if (buildMode == bmRepair) {
17231723
/* Path already exists, need to replace it */
17241724
replaceValidPath(store.toRealPath(finalDestPath), actualPath);
1725-
actualPath = store.toRealPath(finalDestPath);
17261725
} else if (buildMode == bmCheck) {
17271726
/* Path already exists, and we want to compare, so we leave out
17281727
new path in place. */
@@ -1736,7 +1735,6 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
17361735
auto destPath = store.toRealPath(finalDestPath);
17371736
deletePath(destPath);
17381737
movePath(actualPath, destPath);
1739-
actualPath = destPath;
17401738
}
17411739
}
17421740

@@ -1789,7 +1787,9 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
17891787
debug("unreferenced input: '%1%'", store.printStorePath(i));
17901788
}
17911789

1792-
store.optimisePath(actualPath, NoRepair); // FIXME: combine with scanForReferences()
1790+
if (!store.isValidPath(newInfo.path))
1791+
store.optimisePath(
1792+
store.toRealPath(finalDestPath), NoRepair); // FIXME: combine with scanForReferences()
17931793

17941794
newInfo.deriver = drvPath;
17951795
newInfo.ultimate = true;

0 commit comments

Comments
 (0)