X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FVCBackend.cpp;h=719c3c2a1f58241be6f70c50e63cffcdd5632b2e;hb=5170489b983c08c8be8d878996710eb0f6db2679;hp=9f065eb22157d04edfd9ec53a15b745e6fbe8b89;hpb=c9332413e5f40b7c53e4d7afdfb719f49b05e382;p=lyx.git diff --git a/src/VCBackend.cpp b/src/VCBackend.cpp index 9f065eb221..719c3c2a1f 100644 --- a/src/VCBackend.cpp +++ b/src/VCBackend.cpp @@ -43,7 +43,7 @@ int VCS::doVCCommandCall(string const & cmd, FileName const & path) LYXERR(Debug::LYXVC, "doVCCommandCall: " << cmd); Systemcall one; support::PathChanger p(path); - return one.startscript(Systemcall::Wait, cmd, false); + return one.startscript(Systemcall::Wait, cmd, string(), false); } @@ -65,6 +65,56 @@ int VCS::doVCCommand(string const & cmd, FileName const & path, bool reportError } +bool VCS::makeRCSRevision(string const &version, string &revis) const +{ + string rev = revis; + + if (isStrInt(rev)) { + int back = convert(rev); + // if positive use as the last number in the whole revision string + if (back > 0) { + string base; + rsplit(version, base , '.' ); + rev = base + "." + rev; + } + if (back == 0) + rev = version; + // we care about the last number from revision string + // in case of backward indexing + if (back < 0) { + string cur, base; + cur = rsplit(version, base , '.' ); + if (!isStrInt(cur)) + return false; + int want = convert(cur) + back; + if (want <= 0) + return false; + + rev = base + "." + convert(want); + } + } + + revis = rev; + return true; +} + +bool VCS::checkparentdirs(FileName const & file, std::string const & pathname) +{ + FileName dirname = file.onlyPath(); + FileName tocheck = FileName(addName(dirname.absFileName(),pathname)); + LYXERR(Debug::LYXVC, "check file: " << tocheck.absFileName()); + bool result = tocheck.exists(); + while ( !result && !dirname.empty() ) { + //this construct because of #8295 + dirname = FileName(dirname.absFileName()).parentPath(); + LYXERR(Debug::LYXVC, "check directory: " << dirname.absFileName()); + tocheck = FileName(addName(dirname.absFileName(),pathname)); + result = tocheck.exists(); + } + return result; +} + + ///////////////////////////////////////////////////////////////////// // // RCS @@ -267,13 +317,15 @@ bool RCS::lockingToggleEnabled() } -void RCS::revert() +bool RCS::revert() { - doVCCommand("co -f -u" + version_ + " " + if (doVCCommand("co -f -u" + version_ + " " + quoteName(onlyFileName(owner_->absFileName())), - FileName(owner_->filePath())); + FileName(owner_->filePath()))) + return false; // We ignore changes and just reload! owner_->markClean(); + return true; } @@ -316,47 +368,83 @@ bool RCS::toggleReadOnlyEnabled() return false; } + string RCS::revisionInfo(LyXVC::RevisionInfo const info) { if (info == LyXVC::File) return version_; + // fill the rest of the attributes for a single file + if (rev_date_cache_.empty()) + if (!getRevisionInfo()) + return string(); + + switch (info) { + case LyXVC::Author: + return rev_author_cache_; + case LyXVC::Date: + return rev_date_cache_; + case LyXVC::Time: + return rev_time_cache_; + default: ; + } + return string(); } -bool RCS::prepareFileRevision(string const &revis, string & f) +bool RCS::getRevisionInfo() { - string rev = revis; + FileName tmpf = FileName::tempName("lyxvcout"); + if (tmpf.empty()) { + LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); + return false; + } + doVCCommand("rlog -r " + quoteName(onlyFileName(owner_->absFileName())) + + " > " + quoteName(tmpf.toFilesystemEncoding()), + FileName(owner_->filePath())); - if (isStrInt(rev)) { - int back = convert(rev); - // if positive use as the last number in the whole revision string - if (back > 0) { - string base; - rsplit(version_, base , '.' ); - rev = base + "." + rev; - } - if (back == 0) - rev = version_; - // we care about the last number from revision string - // in case of backward indexing - if (back < 0) { - string cur, base; - cur = rsplit(version_, base , '.' ); - if (!isStrInt(cur)) - return false; - int want = convert(cur) + back; - if (want <= 0) - return false; + if (tmpf.empty()) + return false; - rev = base + "." + convert(want); + ifstream ifs(tmpf.toFilesystemEncoding().c_str()); + string line; + + // we reached to the entry, i.e. after initial log message + bool entry=false; + // line with critical info, e.g: + //"date: 2011/07/02 11:02:54; author: sanda; state: Exp; lines: +17 -2" + string result; + + while (ifs) { + getline(ifs, line); + LYXERR(Debug::LYXVC, line); + if (entry && prefixIs(line, "date:")) { + result = line; + break; } + if (prefixIs(line, "revision")) + entry = true; } + if (result.empty()) + return false; + + rev_date_cache_ = token(result, ' ', 1); + rev_time_cache_ = rtrim(token(result, ' ', 2), ";"); + rev_author_cache_ = trim(token(token(result, ';', 1), ':', 1)); + + return !rev_author_cache_.empty(); +} + +bool RCS::prepareFileRevision(string const &revis, string & f) +{ + string rev = revis; + if (!VCS::makeRCSRevision(version_, rev)) + return false; FileName tmpf = FileName::tempName("lyxvcrev_" + rev + "_"); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); - return N_("Error: Could not generate logfile."); + return false; } doVCCommand("co -p" + rev + " " @@ -767,8 +855,8 @@ string CVS::repoUpdate() docstring const file = from_utf8(owner_->filePath()); docstring text = bformat(_("There were detected changes " "in the working directory:\n%1$s\n\n" - "In case of file conflict you have to resolve them " - "manually or revert to repository version later."), file); + "Possible file conflicts must be then resolved manually " + "or you will need to revert back to the repository version."), file); int ret = frontend::Alert::prompt(_("Changes detected"), text, 0, 1, _("&Continue"), _("&Abort"), _("View &Log ...")); if (ret == 2 ) { @@ -831,7 +919,7 @@ bool CVS::isRevertWithConfirmation() } -void CVS::revert() +bool CVS::revert() { // Reverts to the version in CVS repository and // gets the updated version from the repository. @@ -839,7 +927,7 @@ void CVS::revert() switch (status) { case UpToDate: if (vcstatus != NOLOCKING) - unedit(); + return 0 == unedit(); break; case NeedsMerge: case NeedsCheckout: @@ -856,7 +944,7 @@ void CVS::revert() bformat(_("The document %1$s is not in repository.\n" "You have to check in the first revision before you can revert."), file)) ; - break; + return false; } default: { docstring const file = owner_->fileName().displayName(20); @@ -864,9 +952,10 @@ void CVS::revert() bformat(_("Cannot revert document %1$s to repository version.\n" "The status '%2$s' is unexpected."), file, toString(status))); - break; + return false; } } + return true; } @@ -919,15 +1008,32 @@ string CVS::revisionInfo(LyXVC::RevisionInfo const info) } -bool CVS::prepareFileRevision(string const &, string &) +bool CVS::prepareFileRevision(string const & revis, string & f) { - return false; + string rev = revis; + if (!VCS::makeRCSRevision(version_, rev)) + return false; + + FileName tmpf = FileName::tempName("lyxvcrev_" + rev + "_"); + if (tmpf.empty()) { + LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); + return false; + } + + doVCCommandWithOutput("cvs update -p -r" + rev + " " + + getTarget(File), + FileName(owner_->filePath()), tmpf); + if (tmpf.isFileEmpty()) + return false; + + f = tmpf.absFileName(); + return true; } bool CVS::prepareFileRevisionEnabled() { - return false; + return true; } @@ -949,27 +1055,26 @@ SVN::SVN(FileName const & m, FileName const & f) FileName const SVN::findFile(FileName const & file) { - // First we look for the .svn/entries in the same dir - // where we have file. - FileName const entries(onlyPath(file.absFileName()) + "/.svn/entries"); - string const tmpf = onlyFileName(file.absFileName()); - LYXERR(Debug::LYXVC, "LyXVC: Checking if file is under svn in `" << entries - << "' for `" << tmpf << '\''); - if (entries.isReadableFile()) { - // Ok we are at least in a SVN dir. Parse the .svn/entries - // and see if we can find this file. We do a fast and - // dirty parse here. - ifstream ifs(entries.toFilesystemEncoding().c_str()); - string line, oldline; - while (getline(ifs, line)) { - if (line == "dir" || line == "file") - LYXERR(Debug::LYXVC, "\tEntries: " << oldline); - if (oldline == tmpf && line == "file") - return entries; - oldline = line; - } + // First we check the existence of repository meta data. + if (!VCS::checkparentdirs(file, ".svn")) { + LYXERR(Debug::LYXVC, "Cannot find SVN meta data for " << file); + return FileName(); } - return FileName(); + + // Now we check the status of the file. + FileName tmpf = FileName::tempName("lyxvcout"); + if (tmpf.empty()) { + LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); + return FileName(); + } + + string const fname = onlyFileName(file.absFileName()); + LYXERR(Debug::LYXVC, "LyXVC: Checking if file is under svn control for `" << fname << '\''); + bool found = 0 == doVCCommandCall("svn info " + quoteName(fname) + + " > " + quoteName(tmpf.toFilesystemEncoding()), + file.onlyPath()); + LYXERR(Debug::LYXVC, "SVN control: " << (found ? "enabled" : "disabled")); + return found ? file : FileName(); } @@ -993,7 +1098,7 @@ bool SVN::checkLockMode() FileName tmpf = FileName::tempName("lyxvcout"); if (tmpf.empty()){ LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); - return N_("Error: Could not generate logfile."); + return false; } LYXERR(Debug::LYXVC, "Detecting locking mode..."); @@ -1006,7 +1111,7 @@ bool SVN::checkLockMode() string line; bool ret = false; - while (ifs) { + while (ifs && !ret) { getline(ifs, line); LYXERR(Debug::LYXVC, line); if (contains(line, "svn:needs-lock")) @@ -1294,15 +1399,17 @@ bool SVN::lockingToggleEnabled() } -void SVN::revert() +bool SVN::revert() { // Reverts to the version in SVN repository and // gets the updated version from the repository. string const fil = quoteName(onlyFileName(owner_->absFileName())); - doVCCommand("svn revert -q " + fil, - FileName(owner_->filePath())); + if (doVCCommand("svn revert -q " + fil, + FileName(owner_->filePath()))) + return false; owner_->markClean(); + return true; } @@ -1369,7 +1476,7 @@ bool SVN::getFileRevisionInfo() FileName tmpf = FileName::tempName("lyxvcout"); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); - return N_("Error: Could not generate logfile."); + return false; } doVCCommand("svn info --xml " + quoteName(onlyFileName(owner_->absFileName())) @@ -1422,7 +1529,7 @@ bool SVN::getTreeRevisionInfo() FileName tmpf = FileName::tempName("lyxvcout"); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); - return N_("Error: Could not generate logfile."); + return false; } doVCCommand("svnversion -n . > " + quoteName(tmpf.toFilesystemEncoding()), @@ -1473,7 +1580,7 @@ bool SVN::prepareFileRevision(string const & revis, string & f) FileName tmpf = FileName::tempName("lyxvcrev_" + revname + "_"); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); - return N_("Error: Could not generate logfile."); + return false; } doVCCommand("svn cat -r " + revname + " "