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