diff --git a/scripts/nix-restorerevision.sh b/scripts/nix-restorerevision.sh index bdf69673f..d12b3355b 100755 --- a/scripts/nix-restorerevision.sh +++ b/scripts/nix-restorerevision.sh @@ -10,6 +10,4 @@ if [ "$#" != 4 ] ; then exit 1; fi -cd $statepath -$svnbin merge -r HEAD:$torevision $repos -cd - +$svnbin merge -r HEAD:$torevision $repos $statepath diff --git a/scripts/nix-restorerevision.sh.in b/scripts/nix-restorerevision.sh.in index bdf69673f..d12b3355b 100755 --- a/scripts/nix-restorerevision.sh.in +++ b/scripts/nix-restorerevision.sh.in @@ -10,6 +10,4 @@ if [ "$#" != 4 ] ; then exit 1; fi -cd $statepath -$svnbin merge -r HEAD:$torevision $repos -cd - +$svnbin merge -r HEAD:$torevision $repos $statepath diff --git a/src/libstore/db.cc b/src/libstore/db.cc index a59850448..fe2fba06e 100644 --- a/src/libstore/db.cc +++ b/src/libstore/db.cc @@ -546,32 +546,35 @@ bool Database::queryStateReferences(const Transaction & txn, TableId table, Strings keys; enumTable(txn, table, keys); //get all revisions - string key; - if(revision == -1){ + //Check if this revision exists key in the table + string key = makeStatePathRevision(statePath, revision); + bool found = false; + for (Strings::const_iterator i = keys.begin(); i != keys.end(); ++i) { + if(key == *i) + found = true; + } + + key = ""; //reset + if(revision == -1 || (!found)){ bool foundsomething = lookupHighestRevivison(keys, statePath, key); if(!foundsomething) return false; } else key = makeStatePathRevision(statePath, revision); + + if(!found) + printMsg(lvlError, format("Warning: References for revision '%1%' not was not found, so taking the highest rev-key possible for statePath '%2%'") % revision % statePath); + return queryStrings(txn, table, key, references); //now that we have the key, we can query the references } bool Database::queryStateReferrers(const Transaction & txn, TableId table, const Path & statePath, Strings & referrers, int revision) { - //PathSet referrers; - Strings keys; - Path revisionedStatePath = makeStatePathRevision(statePath, revision); - - enumTable(txn, table, keys, revisionedStatePath + string(1, (char) 0)); - - for (Strings::iterator i = keys.begin(); i != keys.end(); ++i) - printMsg(lvlError, format("queryStateReferrers %1%") % *i); - //referrers.insert(stripPrefix(storePath, *i)); - - return false; + //Exactly the same as queryStateReferences + return queryStateReferences(txn, table, statePath, referrers, revision); } @@ -591,10 +594,8 @@ void Database::setStateRevisions(const Transaction & txn, TableId table, sorted_revisions.push_back(revisions.at(*i)); ////////////////// - for (vector::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i){ + for (vector::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i) printMsg(lvlError, format("Insert: %1% into %2%") % int2String(revisions.at(*i)) % *i); - - } ////////////////// //Convert the int's into Strings @@ -639,6 +640,9 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId table, revisions.push_back(getRevision); } + if(!succeed) + throw Error(format("Revision '%1%' not found of statePath '%2%'") % int2String(revision) % statePath); + return succeed; } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 570f7f530..b10e47273 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -446,7 +446,7 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath, if (references.size() > 0 && !isRealisableComponentOrStatePath(txn, store_or_statePath)) throw Error(format("cannot set references for path `%1%' which is invalid and has no substitutes") % store_or_statePath); - printMsg(lvlError, format("Setting references for %1%") % store_or_statePath); + printMsg(lvlError, format("Setting references for %1% (revision:%2%)") % store_or_statePath % int2String(revision)); for (PathSet::iterator i = references.begin(); i != references.end(); ++i) printMsg(lvlError, format("'%2%' has references: %1%") % *i % store_or_statePath); for (PathSet::iterator i = stateReferences.begin(); i != stateReferences.end(); ++i) @@ -1598,8 +1598,6 @@ PathSet mergeNewDerivationIntoList(const Path & storepath, const Path & newdrv, */ void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision) { - //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! - computeFSClosure(storeOrstatePath, paths, withComponents, withState, revision); if (includeOutputs) { @@ -1752,10 +1750,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa /* Register Valid again if neccesary - update the extra references in a new table??? why??? - (remember we need to keep the old as the basis, and things can change, the db is not consistent anymore then ....) - But we also dont want useless refereces ...... - + Update the 2 references tables: all state paths get: Path statepath --> List(int revnumber, List(References)) TODO EDIT TABLES references,references_state,referrers,referrers_state @@ -1783,9 +1778,9 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa Hash(), //emtpy hash state_references, state_stateReferences, - drvPath); - } - */ + drvPath + ); + }*/ } void LocalStore::scanAndUpdateAllReferences(const Path & statePath) diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index da176463b..27e3a4afa 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -260,36 +260,51 @@ static void revertToRevision(Strings opFlags, Strings opArgs) bool recursive = true; //TODO !!!!!!!!!!!!!!!!! - //Insert the direct statePath or all recursive statePaths into the list PathSet drvs; - if(recursive) + if(recursive) drvs = getAllStateDerivationsRecursively(componentPath, revision_arg); //get dependecies (if neccecary | recusively) of all state components that need to be updated else - drvs.insert(derivationPath); + drvs.insert(derivationPath); //Insert direct state path - //Revert each statePath in the list - for (PathSet::iterator d = drvs.begin(); d != drvs.end(); ++d) + //Get the revisions recursively to also roll them back + RevisionNumbers getRivisions; + bool b = store->queryStateRevisions(statePath, getRivisions, revision_arg); + + //Sort the statePaths from all drvs + map state_repos; + vector sorted_paths; + for (PathSet::iterator d = drvs.begin(); d != drvs.end(); ++d) { Path drvPath = *d; Derivation drv = derivationFromPath(drvPath); DerivationStateOutputs stateOutputs = drv.stateOutputs; Path statePath = stateOutputs.find("state")->second.statepath; - string drvName = drv.env.find("name")->second; - - RevisionNumbers getRivisions; - bool b = store->queryStateRevisions(statePath, getRivisions, revision_arg); - + string drvName = drv.env.find("name")->second; string repos = getStateReposPath("stateOutput:staterepospath", statePath, drvName, stateIdentifier); //this is a copy from store-state.cc + state_repos[statePath] = repos; + sorted_paths.push_back(statePath); + } + sort(sorted_paths.begin(), sorted_paths.end()); + + //Revert each statePath in the list + for (vector::iterator i = sorted_paths.begin(); i != sorted_paths.end(); ++i){ + Path statePath = *i; + string repos = state_repos[statePath]; + int revision = getRivisions.front(); + getRivisions.pop_front(); + + printMsg(lvlError, format("Reverting statePath '%1%' to revision: %2%") % statePath % int2String(revision)); Strings p_args; p_args.push_back(nixSVNPath + "/svn"); - p_args.push_back(int2String(revision_arg)); + p_args.push_back(int2String(revision)); p_args.push_back("file://" + repos); p_args.push_back(statePath); - string output = runProgram(nixLibexecDir + "/nix/nix-restorerevision.sh", true, p_args); //run + runProgram_AndPrintOutput(nixLibexecDir + "/nix/nix-restorerevision.sh", true, p_args, "svn"); //run - printMsg(lvlError, format("Reverted statePath '%1%' to revision: %2%") % statePath % int2String(revision_arg)); - } + //TODO !!!!!!!!!!!!!!!!!!!!! do a commit + //TODO !!!!!!!!!!!!!!!!!!!!! check if statePath is a working copy + } } static void opRunComponent(Strings opFlags, Strings opArgs) @@ -315,6 +330,7 @@ static void opRunComponent(Strings opFlags, Strings opArgs) //get all current dependecies (if neccecary | recusively) of all state components that need to be updated PathSet root_drvs = getAllStateDerivationsRecursively(root_componentPath, -1); + //TODO WHAT ABOUT YOURSELF?????????? //TODO maybe also scan the parameters for state or component hashes? //program_args @@ -430,10 +446,10 @@ static void opRunComponent(Strings opFlags, Strings opArgs) runProgram_AndPrintOutput(nixLibexecDir + "/nix/nix-statecommit.sh", true, p_args, "svn"); //Update the intervals again - //store->setStatePathsInterval(intervalPaths, intervals); //TODO!!!!!!!!!!!!!!!!!!!!!! + //store->setStatePathsInterval(intervalPaths, intervals); //TODO!!!!!!!!!!!!!!!!!!!!!! uncomment //TODO - //Scan if needed + //Scan if needed //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! needs a new revision number if(false) store->scanAndUpdateAllReferencesRecusively(statePath); diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 17aea359f..b01c37d84 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -246,6 +246,7 @@ static void opQuery(Strings opFlags, Strings opArgs) bool includeOutputs = false; bool forceRealise = false; string bindingName; + int revision = -1; //last revision for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ++i) @@ -274,6 +275,11 @@ static void opQuery(Strings opFlags, Strings opArgs) else if (*i == "--use-output" || *i == "-u") useOutput = true; else if (*i == "--force-realise" || *i == "-f") forceRealise = true; else if (*i == "--include-outputs") includeOutputs = true; + else if ((*i).substr(0,11) == "--revision="){ + bool succeed = string2Int((*i).substr(11,(*i).length()), revision); + if(!succeed) + throw UsageError("The given revision is not a valid number"); + } else throw UsageError(format("unknown flag `%1%'") % *i); switch (query) { @@ -304,15 +310,15 @@ static void opQuery(Strings opFlags, Strings opArgs) i != opArgs.end(); ++i) { Path path = maybeUseOutput(fixStoreOrStatePath(*i), useOutput, forceRealise); - if (query == qRequisites) store->storePathRequisites(path, includeOutputs, paths, true, false, -1); - else if (query == qRequisitesState) store->storePathRequisites(path, includeOutputs, paths, false, true, -1); - else if (query == qRequisitesFull) store->storePathRequisites(path, includeOutputs, paths, true, true, -1); - else if (query == qReferences) store->queryReferences(path, paths, -1); - else if (query == qStateReferences) store->queryStateReferences(path, paths, -1); //latest revision - else if (query == qReferrers) store->queryReferrers(path, paths, -1); - else if (query == qStateReferrers) store->queryStateReferrers(path, paths, -1); //latest revision - else if (query == qReferrersClosure) computeFSClosure(path, paths, true, false, -1, true); - else if (query == qReferrersClosureWithState) computeFSClosure(path, paths, true, true, -1, true); + if (query == qRequisites) store->storePathRequisites(path, includeOutputs, paths, true, false, revision); + else if (query == qRequisitesState) store->storePathRequisites(path, includeOutputs, paths, false, true, revision); + else if (query == qRequisitesFull) store->storePathRequisites(path, includeOutputs, paths, true, true, revision); + else if (query == qReferences) store->queryReferences(path, paths, revision); + else if (query == qStateReferences) store->queryStateReferences(path, paths, revision); + else if (query == qReferrers) store->queryReferrers(path, paths, revision); + else if (query == qStateReferrers) store->queryStateReferrers(path, paths, revision); + else if (query == qReferrersClosure) computeFSClosure(path, paths, true, false, revision, true); + else if (query == qReferrersClosureWithState) computeFSClosure(path, paths, true, true, revision, true); } Paths sorted = topoSortPaths(paths); for (Paths::reverse_iterator i = sorted.rbegin();