unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [#61071] New features: VC timemachine and BackupOnSave to RCS
@ 2023-01-26 12:06 John Yates
  2023-01-28  4:45 ` Richard Stallman
  0 siblings, 1 reply; 3+ messages in thread
From: John Yates @ 2023-01-26 12:06 UTC (permalink / raw)
  To: Emacs developers; +Cc: Peter Stiernström, Eric Raymond

New bug tracker issue #61071.  Here is [PATCH 0/3] cover letter:

This is a series of three bisectable (I hope :-) patches that culminate
in support of a new Emacs backup scheme:

* [PATCH 1/3] Refactor and document vc-find-revision caching
* [PATCH 2/3] Introduce VC timemachine capability
* [PATCH 3/3] Introduce vc-bos: backup on save (to an RCS file)

This Backup-On-Save scheme exploits a file system mirror scheme
introduced in the first patch.  By exploiting a little known aspect
of RCS's algorithm for locating a master file, backups are stored
completely removed from the work file (i.e. no local RCS directories)
and under exactly the same filename (i.e. no ',v' suffix or similar).

Accessing backed-ups exploits a new vc-timemachine capability,
introduced in the second patch.  Both the design and code owe much
to Peter Stiernström's original git-timemachine.el.  To sidestep any
copyright issues, Peter has graciously assigned git-timemachine.el's
copyright to the FSF.  With the submission timemachine functionality
is available in both vc-git and vc-rcs.

This backup scheme works equally well with files already under some
VCS as well as with files that are not currently version controlled.

For me (primarily a C++ programmer) this is:
  * My first significant bit of elisp
  * My first exposure to the VC codebase
  * My first Emacs / FSF submission

I welcome all nature of feedback:
  * Code criticism
  * Violations of pertinent standards
  * Bug reports
  * Suggested improvement
  * . . .



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [#61071] New features: VC timemachine and BackupOnSave to RCS
  2023-01-26 12:06 [#61071] New features: VC timemachine and BackupOnSave to RCS John Yates
@ 2023-01-28  4:45 ` Richard Stallman
  2023-01-28 14:35   ` John Yates
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Stallman @ 2023-01-28  4:45 UTC (permalink / raw)
  To: John Yates; +Cc: emacs-devel, peter, esr

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

I'd like to understand what the new feature is, and what it does.
Could you please post a description of just that?
To make it simple, plaese don't refer to _how_ it is implemented
or other related patches -- that discussion gets in the way
of "What does this feature do?"

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [#61071] New features: VC timemachine and BackupOnSave to RCS
  2023-01-28  4:45 ` Richard Stallman
@ 2023-01-28 14:35   ` John Yates
  0 siblings, 0 replies; 3+ messages in thread
From: John Yates @ 2023-01-28 14:35 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel, peter, esr

Richard,

Here are the commit messages from the three patches.  Each provides
independently useful functionality.

Following the commit messages I provide a discussion of some known
open issues.

If these descriptions are insufficient to understand the new features,
please suggest, relative to what I am already describing in these
messages, how the descriptions could be improved.

/john

=================

[PATCH 1/3] Refactor and document vc-find-revision caching

Previously there existed two helper functions for vc--revision-other-window:

* vc--revision-other-window-save
* vc--revision-other-window-no-save

The expectation seems to have been that when materializing a revision is
deemed costly (slow backend? remote? ...) it should be saved.  I believe
that, even though the word 'cache' is never used, this was intended to
be a caching mechanism.  That said, the logic provided only a single
save/no-save global toggle.  Aspects of this mechanism were discussed
in this email thread:

  https://lists.gnu.org/archive/html/emacs-devel/2022-10/msg01794.html

I have tried to address some of the concerns raised therein and to
provide some clearer abstractions:

* When a revision gets saved it is deemed a cache.  Thus it is imperative
  that the cached revision be protected and adequately validated before
  being reused.

* A cached revision may be saved as a sibling of the file that triggered its
  materialization or it may be saved in a mirror directory tree rooted at
  `vc-cache-root'.  The latter choice avoids cluttering work trees with
  historic revisions and enables caching across work trees.  `vc-cache-root'
  will also provide a location for the forthcoming vc-bos's backups.

* I have defined the concept of a revision buffer.  This is the form
  of buffer returned by vc's find-revision operation.  It is bound to
  a specific revision, it is read-only and it has a nil buffer-file-name.
  Thus it visits no saved nor cached file.  The rationale is twofold:

  - A revision is a materialization of immutable history

  - The only potential value for a revision buffer's buffer-file-name is a
    cache file which should likewise be regarded as immutable.  Further, if
    materializing revisions is not deemed costly, even that file may not
    exist.  So, in the interest of consistency, revision buffers do not
    visit files.

=================

[PATCH 2/3] Introduce VC timemachine capability

Introducing timemachine functionality into vc was discussed in this thread:

  https://lists.gnu.org/archive/html/emacs-devel/2022-10/msg01272.html

Where the previous commit introduced the concept of a revision buffer bound
to a unique revision, this commit introduces the concept of a timemachine
buffer, bound to the linear sequence of revisions on the branch from which
a work file was checked out.

`vc-tm-revision-head creates' a timemachine buffer, which then behaves as
a cursor over the linear sequence of revisions on a branch.  The buffer can
be repositioned along that branch via:

- `vc-tm-revision-next'
  "Show work file's next revision on checked-out branch."

- `vc-tm-revision-previous'
  "Show work file's previous revision on checked-out branch."

- `vc-tm-revision-nth'
  "Show work file's N'th most recent revision on checked-out branch
  (1 being HEAD)."

- `vc-tm-revision-complete-subject'
  "Show work file's revision via subject completion on checked-out branch."

A timemachine buffer is read-only and has a nil buffer-file-name (meaning
that it is not visiting any file).  The rationale is exactly the same as
for a revision buffer: a timemachine buffer displays immutable history.

To support timemachine functionality a backend needs to support the new
tm-revisions vc operation.  Optionally, it may support the tm-map-line
operation.  In this commit vc-rcs supports only tm-revisions while vc-git
supports both operations.

My implementation borrows design ideas and code from Peter Stiernström's
original git-timemachine.el.  In reality, my effort was little more than an
extended refactoring effort to fit git-timemachine into the vc framework.

=================

Subject: [PATCH 3/3] Introduce vc-bos: backup on save (to an RCS file)

The dream of this vc-bos capability was what first got me working on
vc-timemachine.  From vc-bos.el's front-matter:

    ;; Modern version control systems, such as git, are wonderful.  But they
    ;; have drawbacks when dealing with lightweight save operations:
    ;;
    ;; * Too invasive: new revisions are created only by explicitly action;
    ;;   this includes supplying a commit message (even if empty)
    ;; * Too coarse: a revision captures an entire "project"
    ;; * Too smart: even files listed in .gitignore (or equivalent) remain
    ;;   eligible for editing and hence deserve to get backed-up
    ;; * Requires setup: what about files that have no project?
    ;;
    ;; Enter vc-bos...
    ;;
    ;; vc-bos provides easy access to past revisions of edited files by
    ;; integrating with VC's timemachine functionality.  To do this it
    ;; requires that VC's vc-cache-root be set and that it have '/RCS' as
    ;; one of its directory components (typically the last).
    ;;
    ;; Given such a configuration, vc-bos maintains a mirror tree of RCS
    ;; control files below vc-cache-root.  A control file appears at the
    ;; same position and has exactly the same name as the file that it
    ;; tracks (meaning no ',v' suffix).  This works because RCS treats
    ;; *any* file *anywhere* beneath an RCS directory as a control file.
    ;;
    ;; On FIRST change and EVERY subsequent save cx-bos:
    ;;
    ;; * Qualifies the buffer's path
    ;; * Ensures existence of a mirror directory beneath vc-cache-root
    ;; * Records the newly saved file as the latest RCS revision with
    ;;   an empty commit message
    ;;
    ;; vc-bos's tracking is independent of whether a file is tracked by
    ;; any other VCS.

Thus, vc-bos is both a minimally invasive way to capture save history for
arbitrary files and a convenient way of accessing that history.

=================

Discussion:

When I started this work I already had BOSTR (my backup on save to
RCS) functionality working.  Creating those backups worked exactly as
I desired.  That included creating the backups in a shadow tree
structure.

The problem was recovering a backup.  Doing that required using VC or
RCS via the command-line on a history with no commit messages, only
time stamps.  That was not a happy user experience.  I was familiar
with git-timemachine and desired an equivalently light-weight means of
exploring my backups.

Thus my effort proceeded in three stages (to whit, the above three
patches):

* Integrate BOSTR's mirror directory tree with VC's notion of saving
  backups when retrieving a revision

* Refactor git-timemachine into a shared vc-timemachine component and
  a per backend pair of abstractions; implement those abstractions for
  git and RCS

* Move the remainder of BOSTR as vc-bos; in vc-prefix-map, bind ","
  to vc-tm-revision-head to open a timemachine on backed-up revisions
  of the current file

Open items:

* Eli has already pointed out that, to comply with Emacs conventions,
  vc-tm-revision-next and vc-tm-revision-previous need to accept a
  numeric argument.  This will be trivial to address.

* The greatest weakness is in the cache area.  Often revisions are
  opened using a symbolic name.  If caching is enabled (it is off by
  default) then the revision gets cached under that symbolic name, not
  using its canonical ID.



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-01-28 14:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-26 12:06 [#61071] New features: VC timemachine and BackupOnSave to RCS John Yates
2023-01-28  4:45 ` Richard Stallman
2023-01-28 14:35   ` John Yates

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).