mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
Fixed bugs in revertToRevision and getSharedWithPathSetRecTxn. Users can now also revert to older revisions.
This commit is contained in:
parent
094c69ad19
commit
68cb244c90
10 changed files with 69 additions and 31 deletions
|
|
@ -664,6 +664,13 @@ void Database::setStateRevisions(const Transaction & txn, TableId revisions_tabl
|
||||||
|
|
||||||
//get all paths that point to the same state (using shareing) and check if one of them equals the rootStatePath
|
//get all paths that point to the same state (using shareing) and check if one of them equals the rootStatePath
|
||||||
PathSet sharedWith = getSharedWithPathSetRecTxn(txn, statePath);
|
PathSet sharedWith = getSharedWithPathSetRecTxn(txn, statePath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
printMsg(lvlError, format("SP RootSP '%1%' - '%2%'") % statePath % rootStatePath);
|
||||||
|
for (PathSet::const_iterator j = sharedWith.begin(); j != sharedWith.end(); ++j)
|
||||||
|
printMsg(lvlError, format("SP SW '%1%'") % *j);
|
||||||
|
*/
|
||||||
|
|
||||||
if(statePath == rootStatePath || sharedWith.find(rootStatePath) != sharedWith.end())
|
if(statePath == rootStatePath || sharedWith.find(rootStatePath) != sharedWith.end())
|
||||||
metadata.push_back(comment);
|
metadata.push_back(comment);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1791,7 +1791,7 @@ void setStateStateReferencesTxn(const Transaction & txn, const Path & statePath,
|
||||||
}
|
}
|
||||||
|
|
||||||
//Lookups which statePaths directy share (point to) statePath
|
//Lookups which statePaths directy share (point to) statePath
|
||||||
PathSet getSharedWithPathSetTxn(const Transaction & txn, const Path & statePath)
|
PathSet getDirectlySharedWithPathSetTxn(const Transaction & txn, const Path & statePath)
|
||||||
{
|
{
|
||||||
PathSet statePaths;
|
PathSet statePaths;
|
||||||
|
|
||||||
|
|
@ -1812,31 +1812,51 @@ PathSet getSharedWithPathSetTxn(const Transaction & txn, const Path & statePath)
|
||||||
PathSet getSharedWithPathSetRecTxn_private(const Transaction & txn, const Path & statePath, PathSet & statePaths)
|
PathSet getSharedWithPathSetRecTxn_private(const Transaction & txn, const Path & statePath, PathSet & statePaths)
|
||||||
{
|
{
|
||||||
//Get all paths pointing to statePath
|
//Get all paths pointing to statePath
|
||||||
PathSet newStatePaths = getSharedWithPathSetTxn(txn, statePath);
|
PathSet newStatePaths = getDirectlySharedWithPathSetTxn(txn, statePath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
printMsg(lvlError, format("getSharedWithPathSetRecTxn_private: '%1%'") % statePath);
|
||||||
|
for (PathSet::const_iterator j = newStatePaths.begin(); j != newStatePaths.end(); ++j)
|
||||||
|
printMsg(lvlError, format("newStatePaths '%1%'") % *j);
|
||||||
|
*/
|
||||||
|
|
||||||
//go into recursion to see if there are more paths indirectly pointing to statePath
|
//go into recursion to see if there are more paths indirectly pointing to statePath
|
||||||
for (PathSet::iterator i = newStatePaths.begin(); i != newStatePaths.end(); ++i)
|
for (PathSet::iterator i = newStatePaths.begin(); i != newStatePaths.end(); ++i){
|
||||||
//Only recurse on the really new statePaths to prevent infinite recursion
|
//Only recurse on the really new statePaths to prevent infinite recursion
|
||||||
if(statePaths.find(*i) == statePaths.end())
|
if(statePaths.find(*i) == statePaths.end())
|
||||||
statePaths = pathSets_union(statePaths, getSharedWithPathSetRecTxn_private(txn, *i, statePaths));
|
{
|
||||||
|
statePaths.insert(*i);
|
||||||
|
statePaths = pathSets_union(statePaths, getSharedWithPathSetRecTxn_private(txn, *i, statePaths)); //TODO !!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return statePaths;
|
return statePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Note: Also returns statePath in the PathSet
|
|
||||||
PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath)
|
PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath)
|
||||||
{
|
{
|
||||||
//To no shared state path
|
//To no shared state path
|
||||||
Path statePath_ns = toNonSharedPathTxn(txn, statePath);
|
Path statePath_ns = toNonSharedPathTxn(txn, statePath);
|
||||||
PathSet empty;
|
|
||||||
return getSharedWithPathSetRecTxn_private(txn, statePath_ns, empty);
|
//Also insert non-shared state path if it doenst equal statePath
|
||||||
|
PathSet statePaths;
|
||||||
|
if(statePath_ns != statePath)
|
||||||
|
statePaths.insert(statePath_ns);
|
||||||
|
|
||||||
|
//Make the call to get all shared with paths
|
||||||
|
PathSet result = getSharedWithPathSetRecTxn_private(txn, statePath_ns, statePaths);
|
||||||
|
|
||||||
|
//Remove yourself from the list eventually
|
||||||
|
result.erase(statePath);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LocalStore::revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive)
|
void LocalStore::revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive)
|
||||||
{
|
{
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
revertToRevisionTxn(txn, componentPath, derivationPath, statePath, revision_arg, recursive);
|
revertToRevisionTxn(txn, statePath, revision_arg, recursive);
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ public:
|
||||||
|
|
||||||
PathSet toNonSharedPathSet(const PathSet & statePaths);
|
PathSet toNonSharedPathSet(const PathSet & statePaths);
|
||||||
|
|
||||||
void revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive);
|
void revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive);
|
||||||
|
|
||||||
void setSharedState(const Path & fromExisting, const Path & toNew);
|
void setSharedState(const Path & fromExisting, const Path & toNew);
|
||||||
};
|
};
|
||||||
|
|
@ -243,6 +243,10 @@ bool querySolidStateReferencesTxn(const Transaction & txn, const Path & statePat
|
||||||
void setSharedStateTxn(const Transaction & txn, const Path & fromExisting, const Path & toNew);
|
void setSharedStateTxn(const Transaction & txn, const Path & fromExisting, const Path & toNew);
|
||||||
PathSet toNonSharedPathSetTxn(const Transaction & txn, const PathSet & statePaths);
|
PathSet toNonSharedPathSetTxn(const Transaction & txn, const PathSet & statePaths);
|
||||||
Path toNonSharedPathTxn(const Transaction & txn, const Path & statePath);
|
Path toNonSharedPathTxn(const Transaction & txn, const Path & statePath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a pathset with all paths (including itself) that eventually share the same statePath
|
||||||
|
*/
|
||||||
PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath);
|
PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath);
|
||||||
|
|
||||||
void ensurePathTxn(const Transaction & txn, const Path & path);
|
void ensurePathTxn(const Transaction & txn, const Path & path);
|
||||||
|
|
|
||||||
|
|
@ -513,11 +513,9 @@ PathSet RemoteStore::toNonSharedPathSet(const PathSet & statePaths)
|
||||||
return readStringSet(from); //TODO !!!!!!!!!!!!!!! create a readStatePaths just like readStorePaths
|
return readStringSet(from); //TODO !!!!!!!!!!!!!!! create a readStatePaths just like readStorePaths
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteStore::revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive)
|
void RemoteStore::revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive)
|
||||||
{
|
{
|
||||||
writeInt(wopRevertToRevision, to);
|
writeInt(wopRevertToRevision, to);
|
||||||
writeString(componentPath, to);
|
|
||||||
writeString(derivationPath, to);
|
|
||||||
writeString(statePath, to);
|
writeString(statePath, to);
|
||||||
writeBigUnsignedInt(revision_arg, to);
|
writeBigUnsignedInt(revision_arg, to);
|
||||||
writeInt(recursive ? 1 : 0, to);
|
writeInt(recursive ? 1 : 0, to);
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ public:
|
||||||
|
|
||||||
PathSet toNonSharedPathSet(const PathSet & statePaths);
|
PathSet toNonSharedPathSet(const PathSet & statePaths);
|
||||||
|
|
||||||
void revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive);
|
void revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive);
|
||||||
|
|
||||||
void setSharedState(const Path & fromExisting, const Path & toNew);
|
void setSharedState(const Path & fromExisting, const Path & toNew);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ public:
|
||||||
virtual PathSet toNonSharedPathSet(const PathSet & statePaths) = 0;
|
virtual PathSet toNonSharedPathSet(const PathSet & statePaths) = 0;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
virtual void revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive) = 0;
|
virtual void revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive) = 0;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
virtual void setSharedState(const Path & fromExisting, const Path & toNew) = 0;
|
virtual void setSharedState(const Path & fromExisting, const Path & toNew) = 0;
|
||||||
|
|
|
||||||
|
|
@ -93,14 +93,10 @@ PathSet getAllStateDerivationsRecursivelyTxn(const Transaction & txn, const Path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void revertToRevisionTxn(const Transaction & txn, const Path & componentPath, const Path & derivationPath, const Path & statePath, const int revision_arg, const bool recursive)
|
void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const int revision_arg, const bool recursive)
|
||||||
{
|
{
|
||||||
|
//Unshare the path
|
||||||
PathSet statePaths;
|
Path statePath_ns = toNonSharedPathTxn(txn, statePath);
|
||||||
if(recursive)
|
|
||||||
PathSet statePaths = getAllStateDerivationsRecursivelyTxn(txn, componentPath, revision_arg); //get dependecies (if neccecary | recusively) of all state components that need to be updated
|
|
||||||
else
|
|
||||||
statePaths.insert(derivationPath); //Insert direct state path
|
|
||||||
|
|
||||||
//get a new timestamp for the references update
|
//get a new timestamp for the references update
|
||||||
unsigned int newTimestamp = getTimeStamp();
|
unsigned int newTimestamp = getTimeStamp();
|
||||||
|
|
@ -108,7 +104,7 @@ void revertToRevisionTxn(const Transaction & txn, const Path & componentPath, co
|
||||||
//Get the revisions recursively to also roll them back
|
//Get the revisions recursively to also roll them back
|
||||||
RevisionClosure getRivisions;
|
RevisionClosure getRivisions;
|
||||||
RevisionClosureTS getTimestamps;
|
RevisionClosureTS getTimestamps;
|
||||||
queryStateRevisionsTxn(txn, statePath, getRivisions, getTimestamps, revision_arg);
|
queryStateRevisionsTxn(txn, statePath_ns, getRivisions, getTimestamps, revision_arg);
|
||||||
|
|
||||||
//Revert each statePath in the list
|
//Revert each statePath in the list
|
||||||
for (RevisionClosure::iterator i = getRivisions.begin(); i != getRivisions.end(); ++i){
|
for (RevisionClosure::iterator i = getRivisions.begin(); i != getRivisions.end(); ++i){
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa
|
||||||
|
|
||||||
void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path & statePath);
|
void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path & statePath);
|
||||||
|
|
||||||
void revertToRevisionTxn(const Transaction & txn, const Path & componentPath, const Path & derivationPath, const Path & statePath, const int revision_arg, const bool recursive);
|
void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const int revision_arg, const bool recursive);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ static void revertToRevision(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
bool recursive = revert_recursively;
|
bool recursive = revert_recursively;
|
||||||
|
|
||||||
store->revertToRevision(componentPath, derivationPath, statePath, revision_arg, recursive);
|
store->revertToRevision(statePath, revision_arg, recursive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -486,8 +486,23 @@ void run(Strings args)
|
||||||
RevisionClosureTS timestamps;
|
RevisionClosureTS timestamps;
|
||||||
bool b = store->queryStateRevisions("/nix/state/aacs4qpi9jzg4vmhj09d0ichframh22x-hellohardcodedstateworld-1.0-test", revisions, timestamps, 0);
|
bool b = store->queryStateRevisions("/nix/state/aacs4qpi9jzg4vmhj09d0ichframh22x-hellohardcodedstateworld-1.0-test", revisions, timestamps, 0);
|
||||||
|
|
||||||
return;
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
store = openStore();
|
||||||
|
|
||||||
|
/*
|
||||||
|
PathSet sharedWith = getSharedWithPathSetRecTxn(noTxn, "/nix/state/1kjxymaxf0i6qp5k8ggacc06bzbi4b82-hellohardcodedstateworld-1.0-test");
|
||||||
|
for (PathSet::const_iterator j = sharedWith.begin(); j != sharedWith.end(); ++j)
|
||||||
|
printMsg(lvlError, format("RootSP SW '%1%'") % *j);
|
||||||
|
printMsg(lvlError, format("------------"));
|
||||||
|
sharedWith = getSharedWithPathSetRecTxn(noTxn, "/nix/state/7c9azkk6qfk18hsvw4a5d8vk1p6qryk0-hellohardcodedstateworld-1.0-test");
|
||||||
|
for (PathSet::const_iterator j = sharedWith.begin(); j != sharedWith.end(); ++j)
|
||||||
|
printMsg(lvlError, format("RootSP SW '%1%'") % *j);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/* test */
|
/* test */
|
||||||
|
|
||||||
for (Strings::iterator i = args.begin(); i != args.end(); ) {
|
for (Strings::iterator i = args.begin(); i != args.end(); ) {
|
||||||
|
|
|
||||||
|
|
@ -579,13 +579,11 @@ static void performOp(Source & from, Sink & to, unsigned int op)
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopRevertToRevision: {
|
case wopRevertToRevision: {
|
||||||
Path componentPath = readString(from);
|
|
||||||
Path derivationPath = readString(from);
|
|
||||||
Path statePath = readString(from);
|
Path statePath = readString(from);
|
||||||
unsigned int revision_arg = readBigUnsignedInt(from);
|
unsigned int revision_arg = readBigUnsignedInt(from);
|
||||||
bool recursive = readInt(from) == 1;
|
bool recursive = readInt(from) == 1;
|
||||||
startWork();
|
startWork();
|
||||||
store->revertToRevision(componentPath, derivationPath, statePath, revision_arg, recursive);
|
store->revertToRevision(statePath, revision_arg, recursive);
|
||||||
stopWork();
|
stopWork();
|
||||||
writeInt(1, to);
|
writeInt(1, to);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue