diff --git a/src/VCBackend.cpp b/src/VCBackend.cpp index f0a5300..9f99f4d 100644 this patch is based on lyx's upstream git commit 4a6c23aad366bfa76d4fc30a5e424e2cff83b0c8 by Stephan Witt --- a/src/VCBackend.cpp +++ b/src/VCBackend.cpp @@ -97,7 +97,20 @@ bool VCS::makeRCSRevision(string const &version, string &revis) const 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)); + bool result = tocheck.exists(); + while ( !result && !dirname.empty() ) { + dirname = dirname.parentPath(); + tocheck = FileName(addName(dirname.absFileName(),pathname)); + result = tocheck.exists(); + } + return result; +} + ///////////////////////////////////////////////////////////////////// // @@ -1039,27 +1052,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(); } @@ -1096,7 +1108,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")) diff --git a/src/VCBackend.h b/src/VCBackend.h index 78ccbd4..abffaec 100644 --- a/src/VCBackend.h +++ b/src/VCBackend.h @@ -87,6 +87,10 @@ public: virtual bool prepareFileRevisionEnabled() = 0; + /// Check the directory of file and all parent directories + // for the existence of the given pathname + static bool checkparentdirs(support::FileName const & file, std::string const & pathname); + protected: /// parse information from the version file virtual void scanMaster() = 0; diff --git a/src/support/FileName.cpp b/src/support/FileName.cpp index f88e1eb..83fba29 100644 --- a/src/support/FileName.cpp +++ b/src/support/FileName.cpp @@ -367,6 +367,19 @@ FileName FileName::onlyPath() const } +FileName FileName::parentPath() const +{ + FileName path; + // return empty path for parent of root dir + // parent of empty path is empty too + if (empty() || d->fi.isRoot()) + return path; + path.d->fi.setFile(d->fi.path()); + path.d->name = fromqstr(path.d->fi.absoluteFilePath()); + return path; +} + + bool FileName::isReadableFile() const { return !empty() && d->fi.isFile() && d->fi.isReadable(); diff --git a/src/support/FileName.h b/src/support/FileName.h index 23e6fd0..3ced609 100644 --- a/src/support/FileName.h +++ b/src/support/FileName.h @@ -203,6 +203,9 @@ public: bool hasExtension(const std::string & ext); /// path without file name FileName onlyPath() const; + /// path of parent directory + /// returns empty path for root directory + FileName parentPath() const; /// used for display in the Gui docstring displayName(int threshold = 1000) const;