X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FVCBackend.cpp;h=957c69f585b48890ed38fdcfa1730da82f1dbf4c;hb=ce2e1554908785d7accba292985017fb961b1450;hp=bc78d761d1e3bfc47657bd5e1e77395529e93a89;hpb=f7d47a803da80fe67aaa83103a05d9b5aac41b65;p=lyx.git diff --git a/src/VCBackend.cpp b/src/VCBackend.cpp index bc78d761d1..957c69f585 100644 --- a/src/VCBackend.cpp +++ b/src/VCBackend.cpp @@ -13,6 +13,7 @@ #include "VCBackend.h" #include "Buffer.h" +#include "DispatchResult.h" #include "LyX.h" #include "FuncRequest.h" @@ -27,14 +28,16 @@ #include "support/PathChanger.h" #include "support/Systemcall.h" #include "support/regex.h" +#include "support/TempFile.h" #include +#include +#include using namespace std; using namespace lyx::support; - namespace lyx { @@ -43,7 +46,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, string(), false); + return one.startscript(Systemcall::Wait, cmd, string(), string(), false); } @@ -58,7 +61,7 @@ int VCS::doVCCommand(string const & cmd, FileName const & path, bool reportError owner_->setBusy(false); if (ret && reportError) frontend::Alert::error(_("Revision control error."), - bformat(_("Some problem occured while running the command:\n" + bformat(_("Some problem occurred while running the command:\n" "'%1$s'."), from_utf8(cmd))); return ret; @@ -68,14 +71,14 @@ 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; + rsplit(version, base , '.'); + rev = base + '.' + rev; } if (back == 0) rev = version; @@ -83,14 +86,14 @@ bool VCS::makeRCSRevision(string const &version, string &revis) const // in case of backward indexing if (back < 0) { string cur, base; - cur = rsplit(version, base , '.' ); + cur = rsplit(version, base , '.'); if (!isStrInt(cur)) return false; int want = convert(cur) + back; if (want <= 0) return false; - - rev = base + "." + convert(want); + + rev = base + '.' + convert(want); } } @@ -99,23 +102,21 @@ bool VCS::makeRCSRevision(string const &version, string &revis) const } -bool VCS::checkparentdirs(FileName const & file, std::string const & pathname) +bool VCS::checkparentdirs(FileName const & file, std::string const & vcsdir) { 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() ) { + do { + FileName tocheck = FileName(addName(dirname.absFileName(), vcsdir)); + LYXERR(Debug::LYXVC, "check file: " << tocheck.absFileName()); + if (tocheck.exists()) + return true; //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; + } while (!dirname.empty()); + return false; } - + ///////////////////////////////////////////////////////////////////// // // RCS @@ -124,6 +125,8 @@ bool VCS::checkparentdirs(FileName const & file, std::string const & pathname) RCS::RCS(FileName const & m, Buffer * b) : VCS(b) { + // Here we know that the buffer file is either already in RCS or + // about to be registered master_ = m; scanMaster(); } @@ -168,6 +171,8 @@ void RCS::scanMaster() LYXERR(Debug::LYXVC, "LyXVC::RCS: scanMaster: " << master_); ifstream ifs(master_.toFilesystemEncoding().c_str()); + // limit the size of strings we read to avoid memory problems + ifs >> setw(65636); string token; bool read_enough = false; @@ -276,13 +281,13 @@ LyXVC::CommandResult RCS::checkIn(string const & msg, string & log) if (ret) return LyXVC::ErrorCommand; log = "RCS: Proceeded"; - return LyXVC::Success; + return LyXVC::VCSuccess; } bool RCS::checkInEnabled() { - return owner_ && !owner_->isReadonly(); + return owner_ && !owner_->hasReadonlyFlag(); } @@ -293,7 +298,8 @@ bool RCS::isCheckInWithConfirmation() // if (getDiff(file, diff) && diff.empty()) // return false; - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return true; @@ -304,7 +310,6 @@ bool RCS::isCheckInWithConfirmation() FileName(owner_->filePath())); docstring diff = tmpf.fileContents("UTF-8"); - tmpf.removeFile(); if (diff.empty()) return false; @@ -324,7 +329,7 @@ string RCS::checkOut() bool RCS::checkOutEnabled() { - return owner_ && owner_->isReadonly(); + return owner_ && owner_->hasReadonlyFlag(); } @@ -359,7 +364,7 @@ bool RCS::lockingToggleEnabled() bool RCS::revert() { - if (doVCCommand("co -f -u" + version_ + " " + if (doVCCommand("co -f -u" + version_ + ' ' + quoteName(onlyFileName(owner_->absFileName())), FileName(owner_->filePath()))) return false; @@ -379,7 +384,7 @@ bool RCS::isRevertWithConfirmation() void RCS::undoLast() { LYXERR(Debug::LYXVC, "LyXVC: undoLast"); - doVCCommand("rcs -o" + version_ + " " + doVCCommand("rcs -o" + version_ + ' ' + quoteName(onlyFileName(owner_->absFileName())), FileName(owner_->filePath())); } @@ -387,7 +392,7 @@ void RCS::undoLast() bool RCS::undoLastEnabled() { - return true; + return owner_->hasReadonlyFlag(); } @@ -404,7 +409,7 @@ bool RCS::toggleReadOnlyEnabled() // This got broken somewhere along lfuns dispatch reorganization. // reloadBuffer would be needed after this, but thats problematic // since we are inside Buffer::dispatch. - // return return status() != UNVERSIONED; + // return true; return false; } @@ -425,7 +430,8 @@ string RCS::revisionInfo(LyXVC::RevisionInfo const info) return rev_date_cache_; case LyXVC::Time: return rev_time_cache_; - default: ; + default: + break; } return string(); @@ -434,7 +440,8 @@ string RCS::revisionInfo(LyXVC::RevisionInfo const info) bool RCS::getRevisionInfo() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; @@ -481,16 +488,19 @@ bool RCS::prepareFileRevision(string const &revis, string & f) if (!VCS::makeRCSRevision(version_, rev)) return false; - FileName tmpf = FileName::tempName("lyxvcrev_" + rev + "_"); + TempFile tempfile("lyxvcrev_" + rev + '_'); + tempfile.setAutoRemove(false); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; } - doVCCommand("co -p" + rev + " " + doVCCommand("co -p" + rev + ' ' + quoteName(onlyFileName(owner_->absFileName())) + " > " + quoteName(tmpf.toFilesystemEncoding()), FileName(owner_->filePath())); + tmpf.refresh(); if (tmpf.isFileEmpty()) return false; @@ -513,6 +523,8 @@ bool RCS::prepareFileRevisionEnabled() CVS::CVS(FileName const & m, Buffer * b) : VCS(b) { + // Here we know that the buffer file is either already in CVS or + // about to be registered master_ = m; have_rev_info_ = false; scanMaster(); @@ -553,14 +565,15 @@ void CVS::scanMaster() LYXERR(Debug::LYXVC, "\tlooking for `" << tmpf << '\''); string line; static regex const reg("/(.*)/(.*)/(.*)/(.*)/(.*)"); - vcstatus = UNVERSIONED; while (getline(ifs, line)) { LYXERR(Debug::LYXVC, "\t line: " << line); if (contains(line, tmpf)) { // Ok extract the fields. smatch sm; - - regex_match(line, sm, reg); + if (!regex_match(line, sm, reg)) { + LYXERR(Debug::LYXVC, "\t Cannot parse line. Skipping."); + continue; + } //sm[0]; // whole matched string //sm[1]; // filename @@ -634,7 +647,7 @@ docstring CVS::toString(CvsStatus status) const case StatusError: return _("Cannot retrieve CVS status"); } - return 0; + return docstring(); } @@ -657,7 +670,8 @@ int CVS::doVCCommandCallWithOutput(std::string const & cmd, CVS::CvsStatus CVS::getStatus() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return StatusError; @@ -665,7 +679,6 @@ CVS::CvsStatus CVS::getStatus() if (doVCCommandCallWithOutput("cvs status " + getTarget(File), FileName(owner_->filePath()), tmpf)) { - tmpf.removeFile(); return StatusError; } @@ -675,7 +688,7 @@ CVS::CvsStatus CVS::getStatus() while (ifs) { string line; getline(ifs, line); - LYXERR(Debug::LYXVC, line << "\n"); + LYXERR(Debug::LYXVC, line << '\n'); if (prefixIs(line, "File:")) { if (contains(line, "Up-to-date")) status = UpToDate; @@ -689,7 +702,6 @@ CVS::CvsStatus CVS::getStatus() status = NeedsCheckout; } } - tmpf.removeFile(); return status; } @@ -698,28 +710,28 @@ void CVS::getRevisionInfo() if (have_rev_info_) return; have_rev_info_ = true; - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return; } - - int rc = doVCCommandCallWithOutput("cvs log -r" + version_ - + " " + getTarget(File), + + int rc = doVCCommandCallWithOutput("cvs log -r" + version_ + + ' ' + getTarget(File), FileName(owner_->filePath()), tmpf); if (rc) { - tmpf.removeFile(); LYXERR(Debug::LYXVC, "cvs log failed with exit code " << rc); return; } - + ifstream ifs(tmpf.toFilesystemEncoding().c_str()); static regex const reg("date: (.*) (.*) (.*); author: (.*); state: (.*);(.*)"); while (ifs) { string line; getline(ifs, line); - LYXERR(Debug::LYXVC, line << "\n"); + LYXERR(Debug::LYXVC, line << '\n'); if (prefixIs(line, "date:")) { smatch sm; regex_match(line, sm, reg); @@ -731,7 +743,6 @@ void CVS::getRevisionInfo() break; } } - tmpf.removeFile(); if (rev_author_cache_.empty()) LYXERR(Debug::LYXVC, "Could not retrieve revision info for " << version_ << @@ -824,7 +835,7 @@ string CVS::scanLogFile(FileName const & f, string & status) while (ifs) { string line; getline(ifs, line); - LYXERR(Debug::LYXVC, line << "\n"); + LYXERR(Debug::LYXVC, line << '\n'); if (!line.empty()) status += line + "; "; if (prefixIs(line, "C ")) { @@ -846,7 +857,7 @@ LyXVC::CommandResult CVS::checkIn(string const & msg, string & log) if (unedit()) return LyXVC::ErrorCommand; log = "CVS: Proceeded"; - return LyXVC::Success; + return LyXVC::VCSuccess; case LocallyModified: case LocallyAdded: { int rc = doVCCommand("cvs -q commit -m \"" + msg + "\" " @@ -855,7 +866,7 @@ LyXVC::CommandResult CVS::checkIn(string const & msg, string & log) if (rc) return LyXVC::ErrorCommand; log = "CVS: Proceeded"; - return LyXVC::Success; + return LyXVC::VCSuccess; } case NeedsMerge: case NeedsCheckout: @@ -902,12 +913,13 @@ string CVS::checkOut() { if (vcstatus != NOLOCKING && edit()) return string(); - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return string(); } - + int rc = update(File, tmpf); string log; string const res = scanLogFile(tmpf, log); @@ -919,8 +931,7 @@ string CVS::checkOut() from_local8bit(res))); rc = 0; } - - tmpf.removeFile(); + return rc ? string() : log.empty() ? "CVS: Proceeded" : "CVS: " + log; } @@ -936,12 +947,13 @@ bool CVS::checkOutEnabled() string CVS::repoUpdate() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return string(); } - + getDiff(Directory, tmpf); docstring res = tmpf.fileContents("UTF-8"); if (!res.empty()) { @@ -953,16 +965,14 @@ string CVS::repoUpdate() "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 ) { + if (ret == 2) { dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + tmpf.absFileName())); ret = frontend::Alert::prompt(_("Changes detected"), text, 0, 1, _("&Continue"), _("&Abort")); hideDialogs("file", 0); } - if (ret == 1 ) { - tmpf.removeFile(); + if (ret == 1) return string(); - } } int rc = update(Directory, tmpf); @@ -980,8 +990,6 @@ string CVS::repoUpdate() file, from_local8bit(sres))); rc = 0; } - - tmpf.removeFile(); return rc ? string() : log.empty() ? "CVS: Proceeded" : "CVS: " + log; } @@ -1095,7 +1103,8 @@ string CVS::revisionInfo(LyXVC::RevisionInfo const info) return rev_date_cache_; case LyXVC::Time: return rev_time_cache_; - default: ; + default: + break; } } return string(); @@ -1108,15 +1117,18 @@ bool CVS::prepareFileRevision(string const & revis, string & f) if (!VCS::makeRCSRevision(version_, rev)) return false; - FileName tmpf = FileName::tempName("lyxvcrev_" + rev + "_"); + TempFile tempfile("lyxvcrev_" + rev + '_'); + tempfile.setAutoRemove(false); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; } - doVCCommandWithOutput("cvs update -p -r" + rev + " " + doVCCommandWithOutput("cvs update -p -r" + rev + ' ' + getTarget(File), FileName(owner_->filePath()), tmpf); + tmpf.refresh(); if (tmpf.isFileEmpty()) return false; @@ -1139,6 +1151,8 @@ bool CVS::prepareFileRevisionEnabled() SVN::SVN(FileName const & m, Buffer * b) : VCS(b) { + // Here we know that the buffer file is either already in SVN or + // about to be registered master_ = m; locked_mode_ = 0; scanMaster(); @@ -1154,7 +1168,8 @@ FileName const SVN::findFile(FileName const & file) } // Now we check the status of the file. - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return FileName(); @@ -1165,7 +1180,6 @@ FileName const SVN::findFile(FileName const & file) bool found = 0 == doVCCommandCall("svn info " + quoteName(fname) + " > " + quoteName(tmpf.toFilesystemEncoding()), file.onlyPath()); - tmpf.removeFile(); LYXERR(Debug::LYXVC, "SVN control: " << (found ? "enabled" : "disabled")); return found ? file : FileName(); } @@ -1173,26 +1187,22 @@ FileName const SVN::findFile(FileName const & file) void SVN::scanMaster() { - // vcstatus code other than UNVERSIONED is somewhat superflous, + // vcstatus code is somewhat superflous, // until we want to implement read-only toggle for svn. - FileName f = findFile(owner_->fileName()); - if (f.empty()) { - vcstatus = UNVERSIONED; - } else { - vcstatus = NOLOCKING; - if (checkLockMode()) { - if (isLocked()) - vcstatus = LOCKED; - else - vcstatus = UNLOCKED; - } + vcstatus = NOLOCKING; + if (checkLockMode()) { + if (isLocked()) + vcstatus = LOCKED; + else + vcstatus = UNLOCKED; } } bool SVN::checkLockMode() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()){ LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; @@ -1274,7 +1284,7 @@ string SVN::rename(support::FileName const & newFile, string const & msg) f.push_back(owner_->fileName()); f.push_back(newFile); string log; - if (checkIn(f, msg, log) != LyXVC::Success) { + if (checkIn(f, msg, log) != LyXVC::VCSuccess) { cmd = "svn revert -q " + quoteName(onlyFileName(owner_->absFileName())) + ' ' + quoteName(relFile); @@ -1306,7 +1316,7 @@ string SVN::copy(support::FileName const & newFile, string const & msg) return string(); vector f(1, newFile); string log; - if (checkIn(f, msg, log) == LyXVC::Success) + if (checkIn(f, msg, log) == LyXVC::VCSuccess) return log; return string(); } @@ -1322,7 +1332,8 @@ LyXVC::CommandResult SVN::checkIn(string const & msg, string & log) LyXVC::CommandResult SVN::checkIn(vector const & f, string const & msg, string & log) { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()){ LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); log = N_("Error: Could not generate logfile."); @@ -1336,7 +1347,7 @@ SVN::checkIn(vector const & f, string const & msg, string & l os << " > " << quoteName(tmpf.toFilesystemEncoding()); LyXVC::CommandResult ret = doVCCommand(os.str(), FileName(owner_->filePath())) ? - LyXVC::ErrorCommand : LyXVC::Success; + LyXVC::ErrorCommand : LyXVC::VCSuccess; string res = scanLogFile(tmpf, log); if (!res.empty()) { @@ -1350,10 +1361,9 @@ SVN::checkIn(vector const & f, string const & msg, string & l if (!fileLock(false, tmpf, log)) ret = LyXVC::ErrorCommand; - tmpf.removeFile(); if (!log.empty()) log.insert(0, "SVN: "); - if (ret == LyXVC::Success && log.empty()) + if (ret == LyXVC::VCSuccess && log.empty()) log = "SVN: Proceeded"; return ret; } @@ -1372,7 +1382,8 @@ bool SVN::isCheckInWithConfirmation() { // FIXME one day common getDiff and perhaps OpMode for all backends - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return true; @@ -1383,7 +1394,6 @@ bool SVN::isCheckInWithConfirmation() FileName(owner_->filePath())); docstring diff = tmpf.fileContents("UTF-8"); - tmpf.removeFile(); if (diff.empty()) return false; @@ -1402,8 +1412,8 @@ string SVN::scanLogFile(FileName const & f, string & status) while (ifs) { getline(ifs, line); - LYXERR(Debug::LYXVC, line << "\n"); - if (!line.empty()) + LYXERR(Debug::LYXVC, line << '\n'); + if (!line.empty()) status += line + "; "; if (prefixIs(line, "C ") || prefixIs(line, "CU ") || contains(line, "Commit failed")) { @@ -1430,7 +1440,7 @@ bool SVN::fileLock(bool lock, FileName const & tmpf, string &status) + " > " + quoteName(tmpf.toFilesystemEncoding()), FileName(owner_->filePath())); - // Lock error messages go unfortunately on stderr and are unreachible this way. + // Lock error messages go unfortunately on stderr and are unreachable this way. ifstream ifs(tmpf.toFilesystemEncoding().c_str()); string line; while (ifs) { @@ -1458,7 +1468,8 @@ bool SVN::fileLock(bool lock, FileName const & tmpf, string &status) string SVN::checkOut() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return N_("Error: Could not generate logfile."); @@ -1479,7 +1490,6 @@ string SVN::checkOut() fileLock(true, tmpf, log); - tmpf.removeFile(); return log.empty() ? string() : "SVN: " + log; } @@ -1495,7 +1505,8 @@ bool SVN::checkOutEnabled() string SVN::repoUpdate() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return N_("Error: Could not generate logfile."); @@ -1515,16 +1526,14 @@ string SVN::repoUpdate() "\n\nContinue?"), file); int ret = frontend::Alert::prompt(_("Changes detected"), text, 0, 1, _("&Yes"), _("&No"), _("View &Log ...")); - if (ret == 2 ) { + if (ret == 2) { dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + tmpf.absFileName())); ret = frontend::Alert::prompt(_("Changes detected"), text, 0, 1, _("&Yes"), _("&No")); hideDialogs("file", 0); } - if (ret == 1 ) { - tmpf.removeFile(); + if (ret == 1) return string(); - } } // Reverting looks too harsh, see bug #6255. @@ -1538,7 +1547,6 @@ string SVN::repoUpdate() res += "Update log:\n" + tmpf.fileContents("UTF-8"); LYXERR(Debug::LYXVC, res); - tmpf.removeFile(); return to_utf8(res); } @@ -1551,7 +1559,8 @@ bool SVN::repoUpdateEnabled() string SVN::lockingToggle() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return N_("Error: Could not generate logfile."); @@ -1579,9 +1588,8 @@ string SVN::lockingToggle() if (ret) return string(); - tmpf.removeFile(); frontend::Alert::warning(_("SVN File Locking"), - (locking ? _("Locking property unset.") : _("Locking property set.")) + "\n" + (locking ? _("Locking property unset.") : _("Locking property set.")) + '\n' + _("Do not forget to commit the locking property into the repository."), true); @@ -1660,8 +1668,8 @@ string SVN::revisionInfo(LyXVC::RevisionInfo const info) return rev_date_cache_; case LyXVC::Time: return rev_time_cache_; - default: ; - + default: + break; } return string(); @@ -1670,7 +1678,8 @@ string SVN::revisionInfo(LyXVC::RevisionInfo const info) bool SVN::getFileRevisionInfo() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; @@ -1716,14 +1725,14 @@ bool SVN::getFileRevisionInfo() } ifs.close(); - tmpf.removeFile(); return !rev.empty(); } bool SVN::getTreeRevisionInfo() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; @@ -1740,7 +1749,6 @@ bool SVN::getTreeRevisionInfo() string line; getline(ifs, line); ifs.close(); - tmpf.removeFile(); rev_tree_cache_ = line; return !line.empty(); @@ -1774,16 +1782,19 @@ bool SVN::prepareFileRevision(string const & revis, string & f) } string revname = convert(rev); - FileName tmpf = FileName::tempName("lyxvcrev_" + revname + "_"); + TempFile tempfile("lyxvcrev_" + revname + '_'); + tempfile.setAutoRemove(false); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; } - doVCCommand("svn cat -r " + revname + " " + doVCCommand("svn cat -r " + revname + ' ' + quoteName(onlyFileName(owner_->absFileName())) + " > " + quoteName(tmpf.toFilesystemEncoding()), FileName(owner_->filePath())); + tmpf.refresh(); if (tmpf.isFileEmpty()) return false; @@ -1813,6 +1824,8 @@ bool SVN::toggleReadOnlyEnabled() GIT::GIT(FileName const & m, Buffer * b) : VCS(b) { + // Here we know that the buffer file is either already in GIT or + // about to be registered master_ = m; scanMaster(); } @@ -1827,34 +1840,22 @@ FileName const GIT::findFile(FileName const & file) } // Now we check the status of the file. - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return FileName(); } - // --porcelain selects a format that is supposed to be stable across - // git versions string const fname = onlyFileName(file.absFileName()); LYXERR(Debug::LYXVC, "LyXVC: Checking if file is under git control for `" << fname << '\''); - bool found = 0 == doVCCommandCall("git status --porcelain " + - quoteName(fname) + " > " + - quoteName(tmpf.toFilesystemEncoding()), + doVCCommandCall("git ls-files " + + quoteName(fname) + " > " + + quoteName(tmpf.toFilesystemEncoding()), file.onlyPath()); - if (found) - { - // The output contains a line starting with "??" for unknown - // files, no line for known unmodified files and a line - // starting with "M" or something else for modified/deleted - // etc. files. - ifstream ifs(tmpf.toFilesystemEncoding().c_str()); - string test; - if ((ifs >> test)) - found = (test != "??"); - // else is no error - } - tmpf.removeFile(); + tmpf.refresh(); + bool found = !tmpf.isFileEmpty(); LYXERR(Debug::LYXVC, "GIT control: " << (found ? "enabled" : "disabled")); return found ? file : FileName(); } @@ -1862,13 +1863,9 @@ FileName const GIT::findFile(FileName const & file) void GIT::scanMaster() { - // vcstatus code other than UNVERSIONED is somewhat superflous, + // vcstatus code is somewhat superflous, // until we want to implement read-only toggle for git. - FileName f = findFile(owner_->fileName()); - if (f.empty()) - vcstatus = UNVERSIONED; - else - vcstatus = NOLOCKING; + vcstatus = NOLOCKING; } @@ -1916,7 +1913,7 @@ string GIT::rename(support::FileName const & newFile, string const & msg) f.push_back(owner_->fileName()); f.push_back(newFile); string log; - if (checkIn(f, msg, log) != LyXVC::Success) { + if (checkIn(f, msg, log) != LyXVC::VCSuccess) { cmd = "git checkout -q " + quoteName(onlyFileName(owner_->absFileName())) + ' ' + quoteName(relFile); @@ -1952,7 +1949,8 @@ LyXVC::CommandResult GIT::checkIn(string const & msg, string & log) LyXVC::CommandResult GIT::checkIn(vector const & f, string const & msg, string & log) { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()){ LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); log = N_("Error: Could not generate logfile."); @@ -1966,7 +1964,7 @@ GIT::checkIn(vector const & f, string const & msg, string & l os << " > " << quoteName(tmpf.toFilesystemEncoding()); LyXVC::CommandResult ret = doVCCommand(os.str(), FileName(owner_->filePath())) ? - LyXVC::ErrorCommand : LyXVC::Success; + LyXVC::ErrorCommand : LyXVC::VCSuccess; string res = scanLogFile(tmpf, log); if (!res.empty()) { @@ -1977,10 +1975,9 @@ GIT::checkIn(vector const & f, string const & msg, string & l ret = LyXVC::ErrorCommand; } - tmpf.removeFile(); if (!log.empty()) log.insert(0, "GIT: "); - if (ret == LyXVC::Success && log.empty()) + if (ret == LyXVC::VCSuccess && log.empty()) log = "GIT: Proceeded"; return ret; } @@ -1996,7 +1993,8 @@ bool GIT::isCheckInWithConfirmation() { // FIXME one day common getDiff and perhaps OpMode for all backends - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return true; @@ -2007,7 +2005,6 @@ bool GIT::isCheckInWithConfirmation() FileName(owner_->filePath())); docstring diff = tmpf.fileContents("UTF-8"); - tmpf.removeFile(); if (diff.empty()) return false; @@ -2027,7 +2024,7 @@ string GIT::scanLogFile(FileName const & f, string & status) while (ifs) { getline(ifs, line); LYXERR(Debug::LYXVC, line << "\n"); - if (!line.empty()) + if (!line.empty()) status += line + "; "; if (prefixIs(line, "C ") || prefixIs(line, "CU ") || contains(line, "Commit failed")) { @@ -2140,8 +2137,8 @@ string GIT::revisionInfo(LyXVC::RevisionInfo const info) return rev_date_cache_; case LyXVC::Time: return rev_time_cache_; - default: ; - + default: + break; } return string(); @@ -2150,7 +2147,8 @@ string GIT::revisionInfo(LyXVC::RevisionInfo const info) bool GIT::getFileRevisionInfo() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; @@ -2176,14 +2174,14 @@ bool GIT::getFileRevisionInfo() } ifs.close(); - tmpf.removeFile(); return !rev_file_cache_.empty(); } bool GIT::getTreeRevisionInfo() { - FileName tmpf = FileName::tempName("lyxvcout"); + TempFile tempfile("lyxvcout"); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; @@ -2199,7 +2197,6 @@ bool GIT::getTreeRevisionInfo() ifstream ifs(tmpf.toFilesystemEncoding().c_str()); getline(ifs, rev_tree_cache_); ifs.close(); - tmpf.removeFile(); return !rev_tree_cache_.empty(); } @@ -2234,9 +2231,11 @@ bool GIT::prepareFileRevision(string const & revis, string & f) else pointer = revis; - pointer += ":"; + pointer += ':'; - FileName tmpf = FileName::tempName("lyxvcrev_" + revis + "_"); + TempFile tempfile("lyxvcrev_" + revis + '_'); + tempfile.setAutoRemove(false); + FileName tmpf = tempfile.name(); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return false; @@ -2246,6 +2245,7 @@ bool GIT::prepareFileRevision(string const & revis, string & f) + quoteName(onlyFileName(owner_->absFileName())) + " > " + quoteName(tmpf.toFilesystemEncoding()), FileName(owner_->filePath())); + tmpf.refresh(); if (tmpf.isFileEmpty()) return false; @@ -2262,7 +2262,7 @@ bool GIT::prepareFileRevisionEnabled() bool GIT::toggleReadOnlyEnabled() { - return false; + return true; }