mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-18 21:45:24 +00:00
Backport svn locking
http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg147723.html git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_6_X@28817 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
cd088e64f3
commit
e211a71471
@ -17024,7 +17024,7 @@ When you are finished editing a file, you commit your changes.
|
||||
\begin_layout Standard
|
||||
CVS command:
|
||||
\family typewriter
|
||||
cvs -q commit -m"<description>" <file-name>
|
||||
cvs -q commit -m"<description>" "<file-name>"
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
@ -17172,6 +17172,24 @@ When you are finished editing a file, you commit your changes.
|
||||
|
||||
\begin_layout Standard
|
||||
SVN command:
|
||||
\begin_inset Foot
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
In case locking is not enabled.
|
||||
See Section
|
||||
\begin_inset CommandInset ref
|
||||
LatexCommand ref
|
||||
reference "subsec:SVN-File-Locking"
|
||||
|
||||
\end_inset
|
||||
|
||||
.
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\family typewriter
|
||||
svn commit -q -m"<description>" <file-name>
|
||||
\end_layout
|
||||
@ -17190,6 +17208,16 @@ Updates the changes of this file from the repository.
|
||||
|
||||
\begin_layout Standard
|
||||
SVN command:
|
||||
\begin_inset Foot
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
Ditto.
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\family typewriter
|
||||
svn update
|
||||
\begin_inset Quotes eld
|
||||
@ -17252,6 +17280,116 @@ svn log
|
||||
is shown in a browser.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
File Locking
|
||||
\begin_inset CommandInset label
|
||||
LatexCommand label
|
||||
name "subsec:SVN-File-Locking"
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
The file exchange through various revision control systems brings the problem
|
||||
of merge conflicts in case two different users try to edit the same (parts
|
||||
of) document.
|
||||
When such conflict happens it needs manual resolving and one reasonable
|
||||
alternative is to provide some kind of locking mechanism, which guarantees
|
||||
that only one user is allowed to edit file at the given time.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
SVN has two mechanisms to provide such kind of mutual exclusivity for file
|
||||
access - locks and automatical setting of write permissions based on
|
||||
\begin_inset Flex CharStyle:Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
svn:needs-lock
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
file svn property
|
||||
\begin_inset Foot
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
http://svnbook.red-bean.com/en/1.2/svn.advanced.locking.html
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
.
|
||||
In a case this property is detected for a given document LyX starts to
|
||||
use SVN locks for document editing automatically and the whole check-in/out
|
||||
mechanism switches to the same regimen as for RCS.
|
||||
This in particular means there are two different modes how file is used
|
||||
in LyX:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Unlocked state.
|
||||
The loaded file is in the read-only mode.
|
||||
For editation on needs to check-out.
|
||||
|
||||
\emph on
|
||||
Check-out
|
||||
\emph default
|
||||
consists of update from repository and gaining write lock.
|
||||
If the lock is not possible to obtain, we remain in unlocked state.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Locked state.
|
||||
The loaded file is in the 'normal' edit mode.
|
||||
No other user is allowed to edit the file.
|
||||
|
||||
\emph on
|
||||
Check-in
|
||||
\emph default
|
||||
consists of commiting changes and releasing write-lock.
|
||||
If no changes have been made to the document, no commit will be produced
|
||||
\begin_inset Foot
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
Don't be puzzled by the fact that you will be asked for commit message anyway.
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
and only the write-lock will be released.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
SVN commands:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
Check-in:
|
||||
\family typewriter
|
||||
svn commit -q -m"<description>" "<file-name>"
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
svn unlock "<file-name>"
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
Check-out:
|
||||
\family typewriter
|
||||
svn update "<file-name>"
|
||||
\begin_inset Newline newline
|
||||
\end_inset
|
||||
|
||||
svn lock "<file-name>"
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
SVN and Windows Environment
|
||||
\end_layout
|
||||
|
@ -205,6 +205,8 @@ void LyXVC::toggleReadOnly()
|
||||
LYXERR(Debug::LYXVC, "LyXVC: toggle to unlocked");
|
||||
checkIn();
|
||||
break;
|
||||
case VCS::NOLOCKING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,12 @@ int VCS::doVCCommandCall(string const & cmd, FileName const & path){
|
||||
|
||||
int VCS::doVCCommand(string const & cmd, FileName const & path)
|
||||
{
|
||||
if (owner_)
|
||||
owner_->setBusy(true);
|
||||
|
||||
int const ret = doVCCommandCall(cmd, path);
|
||||
|
||||
if (owner_)
|
||||
owner_->setBusy(false);
|
||||
if (ret)
|
||||
frontend::Alert::error(_("Revision control error."),
|
||||
@ -415,8 +419,10 @@ bool CVS::toggleReadOnlyEnabled()
|
||||
|
||||
SVN::SVN(FileName const & m, FileName const & f)
|
||||
{
|
||||
owner_ = 0;
|
||||
master_ = m;
|
||||
file_ = f;
|
||||
locked_mode_ = 0;
|
||||
scanMaster();
|
||||
}
|
||||
|
||||
@ -449,10 +455,57 @@ FileName const SVN::findFile(FileName const & file)
|
||||
|
||||
void SVN::scanMaster()
|
||||
{
|
||||
// if we want some locking under svn
|
||||
// we need different infrastructure around
|
||||
locker_.clear();
|
||||
vcstatus = NOLOCKING;
|
||||
if (checkLockMode()) {
|
||||
if (isLocked()) {
|
||||
locker_ = "Locked";
|
||||
vcstatus = LOCKED;
|
||||
} else {
|
||||
locker_ = "Unlocked";
|
||||
vcstatus = UNLOCKED;
|
||||
vcstatus = LOCKED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
LYXERR(Debug::LYXVC, "Detecting locking mode...");
|
||||
if (doVCCommandCall("svn proplist " + quoteName(file_.onlyFileName())
|
||||
+ " > " + quoteName(tmpf.toFilesystemEncoding()),
|
||||
file_.onlyPath()))
|
||||
return false;
|
||||
|
||||
ifstream ifs(tmpf.toFilesystemEncoding().c_str());
|
||||
string line;
|
||||
bool ret = false;
|
||||
|
||||
while (ifs) {
|
||||
getline(ifs, line);
|
||||
LYXERR(Debug::LYXVC, line);
|
||||
if (contains(line, "svn:needs-lock"))
|
||||
ret = true;
|
||||
}
|
||||
LYXERR(Debug::LYXVC, "Locking enabled: " << ret);
|
||||
ifs.close();
|
||||
locked_mode_ = ret;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool SVN::isLocked() const
|
||||
{
|
||||
//refresh file info
|
||||
FileName file(file_.absFilename());
|
||||
return !file.isReadOnly();
|
||||
}
|
||||
|
||||
|
||||
@ -483,6 +536,9 @@ string SVN::checkIn(string const & msg)
|
||||
_("Error when commiting to repository.\n"
|
||||
"You have to manually resolve the problem.\n"
|
||||
"After pressing OK, LyX will reopen the document."));
|
||||
else
|
||||
fileLock(false, tmpf, log);
|
||||
|
||||
tmpf.erase();
|
||||
return "SVN: " + log;
|
||||
}
|
||||
@ -490,9 +546,13 @@ string SVN::checkIn(string const & msg)
|
||||
|
||||
bool SVN::checkInEnabled()
|
||||
{
|
||||
if (locked_mode_)
|
||||
return isLocked();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// FIXME Correctly return code should be checked instead of this.
|
||||
// This would need another solution than just plain startscript.
|
||||
// Hint from Andre': QProcess::readAllStandardError()...
|
||||
@ -515,6 +575,36 @@ string SVN::scanLogFile(FileName const & f, string & status)
|
||||
}
|
||||
|
||||
|
||||
void SVN::fileLock(bool lock, FileName const & tmpf, string &status)
|
||||
{
|
||||
if (!locked_mode_ || (isLocked() == lock))
|
||||
return;
|
||||
|
||||
string arg = lock ? "lock " : "unlock ";
|
||||
doVCCommand("svn "+ arg + quoteName(onlyFilename(owner_->absFileName()))
|
||||
+ " > " + quoteName(tmpf.toFilesystemEncoding()),
|
||||
FileName(owner_->filePath()));
|
||||
|
||||
ifstream ifs(tmpf.toFilesystemEncoding().c_str());
|
||||
string line;
|
||||
while (ifs) {
|
||||
getline(ifs, line);
|
||||
if (!line.empty()) status += line + "; ";
|
||||
}
|
||||
ifs.close();
|
||||
|
||||
if (!isLocked() && lock)
|
||||
frontend::Alert::error(_("Revision control error."),
|
||||
_("Error when acquiring write lock.\n"
|
||||
"Most probably some other user edit the current document now!\n"
|
||||
"Check also the access to the repository."));
|
||||
if (isLocked() && !lock)
|
||||
frontend::Alert::error(_("Revision control error."),
|
||||
_("Error when releasing write lock.\n"
|
||||
"Check the access to the repository."));
|
||||
}
|
||||
|
||||
|
||||
string SVN::checkOut()
|
||||
{
|
||||
FileName tmpf = FileName::tempName("lyxvcout");
|
||||
@ -535,6 +625,9 @@ string SVN::checkOut()
|
||||
"You have to manually resolve the conflicts NOW!\n'%1$s'.\n\n"
|
||||
"After pressing OK, LyX will try to reopen resolved document."),
|
||||
from_local8bit(res)));
|
||||
|
||||
fileLock(true, tmpf, log);
|
||||
|
||||
tmpf.erase();
|
||||
return "SVN: " + log;
|
||||
}
|
||||
@ -542,6 +635,9 @@ string SVN::checkOut()
|
||||
|
||||
bool SVN::checkOutEnabled()
|
||||
{
|
||||
if (locked_mode_)
|
||||
return !isLocked();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,8 @@ public:
|
||||
/// the status of the managed file
|
||||
enum VCStatus {
|
||||
UNLOCKED,
|
||||
LOCKED
|
||||
LOCKED,
|
||||
NOLOCKING
|
||||
};
|
||||
|
||||
virtual ~VCS() {}
|
||||
@ -225,9 +226,17 @@ protected:
|
||||
virtual void scanMaster();
|
||||
/// Check for messages in svn output. Returns error.
|
||||
std::string scanLogFile(support::FileName const & f, std::string & status);
|
||||
/// checks locking policy and setup locked_mode_
|
||||
bool checkLockMode();
|
||||
/// is the loaded file locked?
|
||||
bool isLocked() const;
|
||||
/// acquire/release write lock for the current file
|
||||
void fileLock(bool lock, support::FileName const & tmpf, std::string & status);
|
||||
|
||||
private:
|
||||
support::FileName file_;
|
||||
/// is the loaded file under locking policy?
|
||||
bool locked_mode_;
|
||||
};
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -1129,8 +1129,12 @@ void GuiWorkArea::updateWindowTitle()
|
||||
if (!fileName.empty()) {
|
||||
maximize_title = fileName.displayName(30);
|
||||
minimize_title = from_utf8(fileName.onlyFileName());
|
||||
if (buf.lyxvc().inUse())
|
||||
if (buf.lyxvc().inUse()) {
|
||||
if (buf.lyxvc().locker().empty())
|
||||
maximize_title += _(" (version control)");
|
||||
else
|
||||
maximize_title += _(" (version control, locking)");
|
||||
}
|
||||
if (!buf.isClean()) {
|
||||
maximize_title += _(" (changed)");
|
||||
minimize_title += char_type('*');
|
||||
|
@ -37,6 +37,8 @@ What's new
|
||||
- Store the command buffer history in the session file and show it in
|
||||
a pop-up list in the command buffer.
|
||||
|
||||
- Added locking capabilities for SVN version control support.
|
||||
Read Extended manual for details.
|
||||
|
||||
* WINDOWS INSTALLER
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user