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