[LyX/master] Fix bug with registering files for VC when they are in repo subdirs.

Richard Kimberly Heck rikiheck at lyx.org
Fri Dec 18 20:31:40 UTC 2020


commit fdbbddecb7f208692923c36f1fa7edf0dc17b40d
Author: Richard Kimberly Heck <rikiheck at lyx.org>
Date:   Fri Dec 18 15:48:51 2020 -0500

    Fix bug with registering files for VC when they are in repo subdirs.
---
 src/LyXVC.cpp             |   46 ++++++++++++++++++++++++++------------------
 src/VCBackend.cpp         |   17 ++++++++-------
 src/VCBackend.h           |   12 ++++++++--
 src/support/filetools.cpp |   13 ++++++++++++
 src/support/filetools.h   |    6 ++++-
 5 files changed, 63 insertions(+), 31 deletions(-)

diff --git a/src/LyXVC.cpp b/src/LyXVC.cpp
index fa4d4c8..ed0a799 100644
--- a/src/LyXVC.cpp
+++ b/src/LyXVC.cpp
@@ -153,30 +153,36 @@ bool LyXVC::registrer()
 
 	// it is very likely here that the vcs is not created yet...
 	if (!vcs_) {
-		//check in the root directory of the document
-		FileName const cvs_entries(onlyPath(filename.absFileName()) + "/CVS/Entries");
-		FileName const svn_entries(onlyPath(filename.absFileName()) + "/.svn/entries");
-		FileName const git_index(onlyPath(filename.absFileName()) + "/.git/index");
+		FileName found = VCS::checkParentDirs(filename, ".git/index");
 
-		if (git_index.isReadableFile()) {
+		if (!found.empty()) {
 			LYXERR(Debug::LYXVC, "LyXVC: registering "
 				<< to_utf8(filename.displayName()) << " with GIT");
-			vcs_.reset(new GIT(git_index, owner_));
-
-		} else if (svn_entries.isReadableFile()) {
-			LYXERR(Debug::LYXVC, "LyXVC: registering "
-				<< to_utf8(filename.displayName()) << " with SVN");
-			vcs_.reset(new SVN(svn_entries, owner_));
-
-		} else if (cvs_entries.isReadableFile()) {
-			LYXERR(Debug::LYXVC, "LyXVC: registering "
-				<< to_utf8(filename.displayName()) << " with CVS");
-			vcs_.reset(new CVS(cvs_entries, owner_));
+			vcs_.reset(new GIT(found, owner_));
 
 		} else {
-			LYXERR(Debug::LYXVC, "LyXVC: registering "
-				<< to_utf8(filename.displayName()) << " with RCS");
-			vcs_.reset(new RCS(FileName(), owner_));
+			found = VCS::checkParentDirs(filename, ".svn/entries");
+			if (!found.empty()) {
+				LYXERR(Debug::LYXVC, "LyXVC: registering "
+					<< to_utf8(filename.displayName()) << " with SVN");
+				vcs_.reset(new SVN(found, owner_));
+
+			} else {
+				// We only need to check the current directory, since CVS meta-data
+				// is in every sub-directory.
+				FileName const cvs_entries(onlyPath(filename.absFileName()) + "/CVS/Entries");
+				if (cvs_entries.isReadableFile()) {
+					LYXERR(Debug::LYXVC, "LyXVC: registering "
+						<< to_utf8(filename.displayName()) << " with CVS");
+					vcs_.reset(new CVS(cvs_entries, owner_));
+
+				} else {
+					// If all else fails, use RCS
+					LYXERR(Debug::LYXVC, "LyXVC: registering "
+						<< to_utf8(filename.displayName()) << " with RCS");
+					vcs_.reset(new RCS(FileName(), owner_));
+				}
+			}
 		}
 	}
 
@@ -191,6 +197,8 @@ bool LyXVC::registrer()
 	}
 	if (response.empty())
 		response = _("(no initial description)");
+	// FIXME This will fail with svn if the current directory has not
+	// itself been added.
 	vcs_->registrer(to_utf8(response));
 	return true;
 }
diff --git a/src/VCBackend.cpp b/src/VCBackend.cpp
index 26ac809..680af81 100644
--- a/src/VCBackend.cpp
+++ b/src/VCBackend.cpp
@@ -105,18 +105,19 @@ bool VCS::makeRCSRevision(string const &version, string &revis) const
 }
 
 
-bool VCS::checkParentDirs(FileName const & file, std::string const & vcsdir)
+FileName VCS::checkParentDirs(FileName const & start, std::string const & file)
 {
-	FileName dirname = file.onlyPath();
+	static FileName empty;
+	FileName dirname = start.onlyPath();
 	do {
-		FileName tocheck = FileName(addName(dirname.absFileName(), vcsdir));
+		FileName tocheck = FileName(addPathName(dirname.absFileName(), file));
 		LYXERR(Debug::LYXVC, "check file: " << tocheck.absFileName());
 		if (tocheck.exists())
-			return true;
-		//this construct because of #8295
+			return tocheck;
+		// this construct because of #8295
 		dirname = FileName(dirname.absFileName()).parentPath();
 	} while (!dirname.empty());
-	return false;
+	return empty;
 }
 
 
@@ -1169,7 +1170,7 @@ SVN::SVN(FileName const & m, Buffer * b) : VCS(b)
 FileName const SVN::findFile(FileName const & file)
 {
 	// First we check the existence of repository meta data.
-	if (!VCS::checkParentDirs(file, ".svn")) {
+	if (VCS::checkParentDirs(file, ".svn").empty()) {
 		LYXERR(Debug::LYXVC, "Cannot find SVN meta data for " << file);
 		return FileName();
 	}
@@ -1833,7 +1834,7 @@ GIT::GIT(FileName const & m, Buffer * b) : VCS(b)
 FileName const GIT::findFile(FileName const & file)
 {
 	// First we check the existence of repository meta data.
-	if (!VCS::checkParentDirs(file, ".git")) {
+	if (VCS::checkParentDirs(file, ".git").empty()) {
 		LYXERR(Debug::LYXVC, "Cannot find GIT meta data for " << file);
 		return FileName();
 	}
diff --git a/src/VCBackend.h b/src/VCBackend.h
index e914f78..24758d7 100644
--- a/src/VCBackend.h
+++ b/src/VCBackend.h
@@ -103,9 +103,15 @@ public:
 	/// can this operation be processed in the current VCS?
 	virtual bool prepareFileRevisionEnabled() = 0;
 
-	/// Check the directory of file and all parent directories
-	/// for the existence of repository-info like .git or .svn
-	static bool checkParentDirs(support::FileName const & file, std::string const & vcsdir);
+	/// Check the directory given in start and all parent directories
+	/// for the existence of some other file
+	/// \param start : where we start looking (we will strip the filename if given
+	///			and just use the directory
+	/// \param file : the directory or file for which to look
+	///			Note that this can be e.g. ".git/index", so we will look for the .git
+	///			directory and also for an index file in it.
+	/// Returns a FileName object for the found file or else an empty FileName
+	static support::FileName checkParentDirs(support::FileName const & start, std::string const & file);
 
 protected:
 	/// parse information from the version file
diff --git a/src/support/filetools.cpp b/src/support/filetools.cpp
index 2bcfbc6..88b8be1 100644
--- a/src/support/filetools.cpp
+++ b/src/support/filetools.cpp
@@ -654,6 +654,19 @@ string const addName(string const & path, string const & fname)
 }
 
 
+string const addPathName(std::string const & path, std::string const & fname)
+{
+	string const pathpart = onlyPath(fname);
+	string const namepart = onlyFileName(fname);
+	string newpath = path;
+	if (!pathpart.empty())
+		newpath = addPath(newpath, pathpart);
+	if (!namepart.empty())
+		newpath = addName(newpath, namepart);
+	return newpath;
+}
+
+
 // Strips path from filename
 string const onlyFileName(string const & fname)
 {
diff --git a/src/support/filetools.h b/src/support/filetools.h
index 24adf30..6cb3019 100644
--- a/src/support/filetools.h
+++ b/src/support/filetools.h
@@ -210,7 +210,11 @@ std::string const quoteName(std::string const & file, quote_style style = quote_
 /// Add a filename to a path. Any path from filename is stripped first.
 std::string const addName(std::string const & path, std::string const & fname);
 
-/// Append sub-directory(ies) to path in an intelligent way
+/// Add a relative path to a path. Does not strip the pathname
+std::string const addPathName(std::string const & path, std::string const & fname);
+
+/// Append sub-directory(ies) to path in an intelligent way. Will append the
+/// trailing directory separator if that is not provided.
 std::string const addPath(std::string const & path, std::string const & path2);
 
 /** Change extension of oldname to extension.


More information about the lyx-cvs mailing list