Am 07.03.2012 um 19:16 schrieb Richard Heck: > On 03/07/2012 09:32 AM, Stephan Witt wrote: >> Am 07.03.2012 um 15:15 schrieb Pavel Sanda: >> >>> Stephan Witt wrote: >>>> I don't like hard-coding the knowledge how subversion developers organize >>>> their meta-data. >>> More thoughts - what about this proposal: >>> 1. We completely kill parsing of 1.6 metadata in .svn. >>> 2. If possible than write common routine for both 1.6/1.7 (I assume the >>> output of "svn --xml info" is consistent) >>> (that also means no detecting and caching for 1.7 being a special case) >>> 3. The only knowledge left about svn metadata would be checking for .svn in >>> parental directories >>> (which we later join with test for .git). This would avoid superfluous >>> execution of binaries. >>> >>> What do you think? >> 1. and 2. (minus --xml) is essentially my already existing patch. > On Linux, at least, we can simply check the return value of "svn info" and so > not need to parse anything. Probably also on OSX. Don't know about Windows. > Sames goes for git, but in that case one would want "git status" or something > of the sort.
Ok, here comes the patch. If anybody can give it a try - especially on Windows - I'm interested in the result. Otherwise I'll commit it on Sunday or so... I've introduced the FileName::parentPath() method to avoid the infinite loop when FileName::onlyPath() reaches the root of the file system. I don't want to compare strings here. Stephan
Index: src/support/FileName.h =================================================================== --- src/support/FileName.h (Revision 40885) +++ src/support/FileName.h (Arbeitskopie) @@ -194,6 +194,9 @@ 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; Index: src/support/FileName.cpp =================================================================== --- src/support/FileName.cpp (Revision 40885) +++ src/support/FileName.cpp (Arbeitskopie) @@ -367,6 +367,19 @@ } +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(); Index: src/VCBackend.h =================================================================== --- src/VCBackend.h (Revision 40885) +++ src/VCBackend.h (Arbeitskopie) @@ -87,6 +87,10 @@ 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; Index: src/VCBackend.cpp =================================================================== --- src/VCBackend.cpp (Revision 40885) +++ src/VCBackend.cpp (Arbeitskopie) @@ -97,8 +97,21 @@ 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; +} + - ///////////////////////////////////////////////////////////////////// // // RCS @@ -1039,27 +1052,26 @@ 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 @@ string line; bool ret = false; - while (ifs) { + while (ifs && !ret) { getline(ifs, line); LYXERR(Debug::LYXVC, line); if (contains(line, "svn:needs-lock"))