]> git.lyx.org Git - lyx.git/blob - src/VCBackend.h
570c4a295f2ccfe3c91c1c4be68a5cba29f7401f
[lyx.git] / src / VCBackend.h
1 // -*- C++ -*-
2 /**
3  * \file VCBackend.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  * \author Pavel Sanda
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #ifndef VC_BACKEND_H
14 #define VC_BACKEND_H
15
16 #include "support/FileName.h"
17
18 #include <string>
19 #include <vector>
20
21 #include "LyXVC.h"
22
23
24 namespace lyx {
25
26 class Buffer;
27
28 /// A simple version control system interface
29 class VCS {
30 public:
31         /// the status of the managed file
32         enum VCStatus {
33                 UNLOCKED,
34                 LOCKED,
35                 NOLOCKING,
36         };
37
38         VCS(Buffer * b) : vcstatus(NOLOCKING), owner_(b) {}
39         virtual ~VCS() {}
40
41         /// the name of the vc backend
42         virtual std::string vcname() const = 0;
43         /// register a file for version control
44         virtual void registrer(std::string const & msg) = 0;
45         /// can this operation be processed in the current VCS?
46         virtual bool renameEnabled() = 0;
47         /// rename a file. Return non-empty log on success, empty log on failure.
48         virtual std::string rename(support::FileName const &, std::string const &) = 0;
49         /// can this operation be processed in the current VCS?
50         virtual bool copyEnabled() = 0;
51         /// copy a file. Return non-empty log on success, empty log on failure.
52         virtual std::string copy(support::FileName const &, std::string const &) = 0;
53         /// check in the current revision.
54         /// \p log is non-empty on success and may be empty on failure.
55         virtual LyXVC::CommandResult
56         checkIn(std::string const & msg, std::string & log) = 0;
57         /// can this operation be processed in the current VCS?
58         virtual bool checkInEnabled() = 0;
59         /// should a log message provided for next checkin?
60         virtual bool isCheckInWithConfirmation() = 0;
61         /// check out for editing, returns log
62         virtual std::string checkOut() = 0;
63         /// can this operation be processed in the current VCS?
64         virtual bool checkOutEnabled() = 0;
65         /// synchronize with repository, returns log
66         virtual std::string repoUpdate() = 0;
67         /// can this operation be processed in the current VCS?
68         virtual bool repoUpdateEnabled() = 0;
69         /// toggle locking property of the file
70         virtual std::string lockingToggle() = 0;
71         /// can this operation be processed in the current VCS?
72         virtual bool lockingToggleEnabled() = 0;
73         /// revert current edits
74         virtual bool revert() = 0;
75         /// should a confirmation before revert requested?
76         virtual bool isRevertWithConfirmation() = 0;
77         /**
78          * Merge the current with the previous version
79          * in a reverse patch kind of way, so that the
80          * result is to revert the last changes.
81          */
82         virtual void undoLast() = 0;
83         /// can this operation be processed in the current VCS?
84         virtual bool undoLastEnabled() = 0;
85         /**
86          * getLog - read the revision log into the given file
87          * @param fname file name to read into
88          */
89         virtual void getLog(support::FileName const &) = 0;
90         /// return the current version description
91         virtual std::string const versionString() const = 0;
92         /// return the owning buffer
93         Buffer * owner() const { return owner_; }
94         /// return the lock status of this file
95         VCStatus status() const { return vcstatus; }
96         /// do we need special handling for read-only toggling?
97         /// (also used for check-out operation)
98         virtual bool toggleReadOnlyEnabled() = 0;
99         /// Return revision info specified by the argument.
100         virtual std::string revisionInfo(LyXVC::RevisionInfo const info) = 0;
101         /// can this operation be processed in the current VCS?
102         virtual bool prepareFileRevision(std::string const & rev, std::string & f) = 0;
103         /// can this operation be processed in the current VCS?
104         virtual bool prepareFileRevisionEnabled() = 0;
105
106         /// Check the directory of file and all parent directories
107         /// for the existence of repository-info like .git or .svn
108         static bool checkparentdirs(support::FileName const & file, std::string const & vcsdir);
109
110 protected:
111         /// parse information from the version file
112         virtual void scanMaster() = 0;
113
114         /// Prepare a version identifier suitable for RCS and CVS.
115         /// If needed converts last or relative number to the absolute revision.
116         bool makeRCSRevision(std::string const &version, std::string &revis) const;
117
118         /// GUI container for doVCCommandCall
119         int doVCCommand(std::string const & cmd, support::FileName const & path, bool reportError = true);
120         /**
121          * doVCCommandCall - call out to the version control utility
122          * @param cmd the command to execute
123          * @param path the path from which to execute
124          * @return exit status
125          */
126         static int doVCCommandCall(std::string const & cmd, support::FileName const & path);
127
128         /**
129          * The master VC file. For RCS this is *,v or RCS/ *,v. master should
130          * have full path.
131          */
132         support::FileName master_;
133
134         /// The status of the VC controlled file.
135         VCStatus vcstatus;
136
137         /// The buffer using this VC
138         Buffer * const owner_;
139 };
140
141
142 ///
143 class RCS : public VCS {
144 public:
145
146         explicit
147         RCS(support::FileName const & m, Buffer * b);
148
149         /// return the revision file for the given file, if found
150         static support::FileName const findFile(support::FileName const & file);
151
152         /// get file from repo, the caller must ensure that it does not exist locally
153         static bool retrieve(support::FileName const & file);
154
155         virtual std::string vcname() const { return "RCS"; };
156
157         virtual void registrer(std::string const & msg);
158
159         virtual bool renameEnabled();
160
161         virtual std::string rename(support::FileName const &, std::string const &);
162
163         virtual bool copyEnabled();
164
165         virtual std::string copy(support::FileName const &, std::string const &);
166
167         virtual LyXVC::CommandResult
168         checkIn(std::string const & msg, std::string & log);
169
170         virtual bool checkInEnabled();
171
172         virtual bool isCheckInWithConfirmation();
173
174         virtual std::string checkOut();
175
176         virtual bool checkOutEnabled();
177
178         virtual std::string repoUpdate();
179
180         virtual bool repoUpdateEnabled();
181
182         virtual std::string lockingToggle();
183
184         virtual bool lockingToggleEnabled();
185
186         virtual bool revert();
187
188         virtual bool isRevertWithConfirmation();
189
190         virtual void undoLast();
191
192         virtual bool undoLastEnabled();
193
194         virtual void getLog(support::FileName const &);
195
196         virtual std::string const versionString() const {
197                 return "RCS: " + version_;
198         }
199
200         virtual bool toggleReadOnlyEnabled();
201
202         virtual std::string revisionInfo(LyXVC::RevisionInfo const info);
203
204         virtual bool prepareFileRevision(std::string const & rev, std::string & f);
205
206         virtual bool prepareFileRevisionEnabled();
207
208 protected:
209         virtual void scanMaster();
210 private:
211         bool getRevisionInfo();
212         /**
213          * The version of the VC file. I am not sure if this can be a
214          * string or if it must be a float/int.
215          */
216         std::string version_;
217         /// The user currently keeping the lock on the VC file (or "Unlocked").
218         std::string locker_;
219         /// Cache for revision info.
220         std::string rev_date_cache_;
221         ///
222         std::string rev_time_cache_;
223         ///
224         std::string rev_author_cache_;
225 };
226
227
228 ///
229 class CVS : public VCS {
230 public:
231         ///
232         explicit
233         CVS(support::FileName const & m, Buffer * b);
234
235         /// return the revision file for the given file, if found
236         static support::FileName const findFile(support::FileName const & file);
237
238         /// get file from repo, the caller must ensure that it does not exist locally
239         static bool retrieve(support::FileName const & file);
240
241         virtual std::string vcname() const { return "CVS"; };
242
243         virtual void registrer(std::string const & msg);
244
245         virtual bool renameEnabled();
246
247         virtual std::string rename(support::FileName const &, std::string const &);
248
249         virtual bool copyEnabled();
250
251         virtual std::string copy(support::FileName const &, std::string const &);
252
253         virtual LyXVC::CommandResult
254         checkIn(std::string const & msg, std::string & log);
255
256         virtual bool checkInEnabled();
257
258         virtual bool isCheckInWithConfirmation();
259
260         virtual std::string checkOut();
261
262         virtual bool checkOutEnabled();
263
264         virtual std::string repoUpdate();
265
266         virtual bool repoUpdateEnabled();
267
268         virtual std::string lockingToggle();
269
270         virtual bool lockingToggleEnabled();
271
272         virtual bool isRevertWithConfirmation();
273
274         virtual bool revert();
275
276         virtual void undoLast();
277
278         virtual bool undoLastEnabled();
279
280         virtual void getLog(support::FileName const &);
281
282         /// Check for messages in cvs output.
283         /// Returns conflict line.
284         std::string scanLogFile(support::FileName const & f, std::string & status);
285
286         virtual std::string const versionString() const {
287                 return "CVS: " + version_;
288         }
289
290         virtual bool toggleReadOnlyEnabled();
291
292         virtual std::string revisionInfo(LyXVC::RevisionInfo const info);
293
294         virtual bool prepareFileRevision(std::string const & rev, std::string & f);
295
296         virtual bool prepareFileRevisionEnabled();
297
298 protected:
299         virtual void scanMaster();
300         /// the mode of operation for some VC commands
301         enum OperationMode {
302                 Directory = 0,
303                 File = 1
304         };
305         /// possible status values of file
306         enum CvsStatus {
307                 UpToDate = 0,
308                 LocallyModified = 1,
309                 LocallyAdded = 2,
310                 NeedsMerge = 3,
311                 NeedsCheckout = 4,
312                 NoCvsFile = 5,
313                 StatusError = 6
314         };
315
316 private:
317         // revision number from scanMaster
318         std::string version_;
319
320         /**
321          * doVCCommandWithOutput
322          * - call out to the version control utility
323          * - it is able to collect output in a file
324          * @param cmd the command to execute
325          * @param path the path from which to execute
326          * @param output the path where to store output
327          * @param reportError display of low level error message dialog
328          * @return exit status
329          */
330         int doVCCommandWithOutput(std::string const & cmd,
331                         support::FileName const & path,
332                         support::FileName const & output,
333                         bool reportError = true);
334         static int doVCCommandCallWithOutput(std::string const & cmd,
335                         support::FileName const & path,
336                         support::FileName const & output);
337
338         /// return the quoted pathname if Directory or filename if File
339         virtual std::string const getTarget(OperationMode opmode) const;
340         /// collect the diff of file or directory against repository
341         /// result is placed in temporary file
342         void getDiff(OperationMode opmode, support::FileName const & tmpf);
343         /// make the file ready for editing:
344         /// save a copy in CVS/Base and change file permissions to rw if needed
345         virtual int edit();
346         /// revert the edit operation
347         virtual int unedit();
348         /// retrieve repository changes into working copy
349         virtual int update(OperationMode opmode, support::FileName const & tmpf);
350         /// check readonly state for file
351         /// assume true when file is writable
352         virtual bool isLocked() const;
353         /// query and parse the cvs status of file
354         virtual CvsStatus getStatus();
355         /// convert enum to string
356         virtual docstring toString(CvsStatus status) const;
357
358         /// cache the info values of current file revision
359         /// author, date and time of commit
360         std::string rev_author_cache_;
361         std::string rev_date_cache_;
362         std::string rev_time_cache_;
363         /// fills the cache values, returns true if successfull.
364         void getRevisionInfo();
365         bool have_rev_info_;
366 };
367
368
369 ///
370 class SVN : public VCS {
371 public:
372         ///
373         explicit
374         SVN(support::FileName const & m, Buffer * b);
375
376         /// return the revision file for the given file, if found
377         static support::FileName const findFile(support::FileName const & file);
378
379         /// get file from repo, the caller must ensure that it does not exist locally
380         static bool retrieve(support::FileName const & file);
381
382         virtual std::string vcname() const { return "SVN"; };
383
384         virtual void registrer(std::string const & msg);
385
386         virtual bool renameEnabled();
387
388         virtual std::string rename(support::FileName const &, std::string const &);
389
390         virtual bool copyEnabled();
391
392         virtual std::string copy(support::FileName const &, std::string const &);
393
394         virtual LyXVC::CommandResult
395         checkIn(std::string const & msg, std::string & log);
396
397         virtual bool checkInEnabled();
398
399         virtual bool isCheckInWithConfirmation();
400
401         virtual std::string checkOut();
402
403         virtual bool checkOutEnabled();
404
405         virtual std::string repoUpdate();
406
407         virtual bool repoUpdateEnabled();
408
409         virtual std::string lockingToggle();
410
411         virtual bool lockingToggleEnabled();
412
413         virtual bool revert();
414
415         virtual bool isRevertWithConfirmation();
416
417         virtual void undoLast();
418
419         virtual bool undoLastEnabled();
420
421         virtual void getLog(support::FileName const &);
422
423         virtual std::string const versionString() const {
424                 return "SVN: " + rev_file_cache_;
425         }
426
427         virtual bool toggleReadOnlyEnabled();
428
429         virtual std::string revisionInfo(LyXVC::RevisionInfo const info);
430
431         virtual bool prepareFileRevision(std::string const & rev, std::string & f);
432
433         virtual bool prepareFileRevisionEnabled();
434
435 protected:
436         virtual void scanMaster();
437         /// Check for messages in svn output. Returns error.
438         std::string scanLogFile(support::FileName const & f, std::string & status);
439         /// checks locking policy and setup locked_mode_
440         bool checkLockMode();
441         /// is the loaded file locked?
442         bool isLocked() const;
443         /// acquire/release write lock for the current file
444         bool fileLock(bool lock, support::FileName const & tmpf, std::string & status);
445         /// Check in files \p f with log \p msg
446         LyXVC::CommandResult checkIn(std::vector<support::FileName> const & f,
447                                      std::string const & msg, std::string & log);
448
449 private:
450         /// is the loaded file under locking policy?
451         bool locked_mode_;
452         /**
453          * Real code for obtaining file revision info. Fills all file-related caches
454          * and returns true if successfull.
455          * "?" is stored in rev_file_cache_ as a signal if request for obtaining info
456          * was already unsuccessful.
457          */
458         bool getFileRevisionInfo();
459         /// cache for file revision number, "?" if already unsuccessful, isNumber==true
460         std::string rev_file_cache_;
461         /// cache for author of last commit
462         std::string rev_author_cache_;
463         /// cache for date of last commit
464         std::string rev_date_cache_;
465         /// cache for time of last commit
466         std::string rev_time_cache_;
467         /// fills rev_tree_cache_, returns true if successfull.
468         bool getTreeRevisionInfo();
469         /// cache for tree revision number, "?" if already unsuccessful
470         std::string rev_tree_cache_;
471 };
472
473
474 /**
475  * Very basic git support:
476  * Remote repos are completely ignored, only the local tree is considered.
477  * How push and pull could be integrated with the LyX VCS interface needs
478  * to be discussed.
479  */
480 class GIT : public VCS {
481 public:
482         ///
483         explicit
484         GIT(support::FileName const & m, Buffer * b);
485
486         /// return the revision file for the given file, if found
487         static support::FileName const findFile(support::FileName const & file);
488
489         /// get file from repo, the caller must ensure that it does not exist locally
490         static bool retrieve(support::FileName const & file);
491
492         virtual std::string vcname() const { return "GIT"; };
493
494         virtual void registrer(std::string const & msg);
495
496         virtual bool renameEnabled();
497
498         virtual std::string rename(support::FileName const &, std::string const &);
499
500         virtual bool copyEnabled();
501
502         virtual std::string copy(support::FileName const &, std::string const &);
503
504         virtual LyXVC::CommandResult
505         checkIn(std::string const & msg, std::string & log);
506
507         virtual bool checkInEnabled();
508
509         virtual bool isCheckInWithConfirmation();
510
511         virtual std::string checkOut();
512
513         virtual bool checkOutEnabled();
514
515         virtual std::string repoUpdate();
516
517         virtual bool repoUpdateEnabled();
518
519         virtual std::string lockingToggle();
520
521         virtual bool lockingToggleEnabled();
522
523         virtual bool revert();
524
525         virtual bool isRevertWithConfirmation();
526
527         virtual void undoLast();
528
529         virtual bool undoLastEnabled();
530
531         virtual void getLog(support::FileName const &);
532
533         virtual std::string const versionString() const {
534                 return "GIT: ?";
535         }
536
537         virtual bool toggleReadOnlyEnabled();
538
539         virtual std::string revisionInfo(LyXVC::RevisionInfo const info);
540
541         virtual bool prepareFileRevision(std::string const & rev, std::string & f);
542
543         virtual bool prepareFileRevisionEnabled();
544
545 protected:
546         virtual void scanMaster();
547         /// Check for messages in svn output. Returns error.
548         std::string scanLogFile(support::FileName const & f, std::string & status);
549         /// Check in files \p f with log \p msg
550         LyXVC::CommandResult checkIn(std::vector<support::FileName> const & f,
551                                      std::string const & msg, std::string & log);
552
553 private:
554         /**
555          * Real code for obtaining file revision info. Fills all file-related caches
556          * and returns true if successfull.
557          * "?" is stored in rev_file_cache_ as a signal if request for obtaining info
558          * was already unsuccessful.
559          */
560         bool getFileRevisionInfo();
561         /// cache for file revision number, "?" if already unsuccessful, isNumber==true
562         std::string rev_file_cache_;
563         /// cache for author of last commit
564         std::string rev_author_cache_;
565         /// cache for date of last commit
566         std::string rev_date_cache_;
567         /// cache for time of last commit
568         std::string rev_time_cache_;
569         /// fills rev_tree_cache_, returns true if successfull.
570         bool getTreeRevisionInfo();
571         /// cache for tree revision number, "?" if already unsuccessful
572         std::string rev_tree_cache_;
573 };
574
575 } // namespace lyx
576
577 #endif // VCBACKEND_H