<commit_before>    Oh Most Noble and Virile Emacs, please be in -*- outline -*- mode!

     Inversion: A Version Control System You Actually Want To Use
     ------------------------------------------------------------
              ($Revision: 1.7 $ of this document.)

* Introduction

This document describes Inversion, a replacement for CVS.  We may
sometimes call it "Ivn", to save space.  It will be described largely
in terms of how it differs, or doesn't differ, from CVS; if you don't
already know CVS, this document will be pretty unreadable.

Where you see the word "version", it means the same thing "revision"
does in the CVS documentation.  Everyone always ends up saying
"version" anyway, then correcting themselves, so let's just give up
already.  Besides, it's shorter to type.

"Project" and "Repository" also mean what you think they do -- a
repository is a place where multiple projects are stored.  Sometimes I
might slip and say "repository" where I should have said "project",
because CVS uses the r-word for both.  Bear with me.

* Requirements

** All CVS features are supported.

Everything CVS has, we want.  Versioning, folding of non-conflicting
changes, detection of conflicting changes, branching, merging,
historical diffs, log messages, line-by-line history ("cvs annotate"),
the works.

Generally, Inversion's conceptual interface to a particular feature
will be as similar to CVS's as possible, except when there's a
compelling reason to do otherwise.

** Version numbers are project-wide and atomic.

Unlike CVS, each Inversion commit results in a single new version
number, which applies to the project as a whole (i.e., it applies to
every object in the project, whether changed or not).  There are no
longer separate per-file version numbers, at least not user-visible
ones.

Commits are atomic -- either the entire commit succeeded, or the
entire commit failed.  No one can ever retrieve a project tree in an
inconsistent state.

Lock-time is kept to a minimum.  A commit may block on another commit,
but only briefly, and only when absolutely necessary -- that is, when
the same files would be affected.  Readers neither cause nor wait for
locks.

** Directories, renames, and file meta-data are versioned.

Naturally!

By the way, rename support means you can trace through ancestry by
name *or* by entity.  For example, if you say "Give me version 12
of foo.c", you might mean version 12 of the file whose name is
*now* foo.c (but perhaps it was named bar.c back at version 12),
or you might mean the file whose name was foo.c in version 12 (perhaps
that file no longer exists, or has a different name now).  Inversion
offers a way to specify which interpretation you want, while
defaulting to the most reasonable interpretation in context.  We
haven't decided what "reasonable" means yet, but we're working on
that.

** Binary files are handled just like anything else.

That's right, no more "-kb" flag. :-)

Whether Inversion is able to merge changes into a file gracefully, or
show diffs, depends on whether diffing and/or merging tools are
defined for that type of file.  Right now, we know that text files are
supported.  (How does Inversion know whether something's text file or
not?  Well, you can tell it the type explicitly, or ask it to deduce
on the fly.)

Also, for text files, Inversion can do platform-specific end-of-line
conversion (CRLF vs LF, etc), just like CVS.

Regarding keyword expansion: Inversion does support it, but only on
request.  By default, keyword expansion is off -- if you do not ask
for expansion for a given file or group of files, Inversion will not
modify content.

** I18N/Multilingual support: non-ASCII encodings can be treated as text.

Inversion does not assume that anything not 7-bit ASCII must therefore
be opaque binary -- it tries very hard to treat things as UTF-* text,
for purposes of diffing and annotation, whenever possible.

** Branching and tagging are constant-time operations in Inversion.

CVS makes an unnecessary distinction between branches and tags, and
then goes on to implement them in an inefficient way.

Inversion supports them both with one efficient operation: `copy'.  To
copy a project is to create another project exactly like it, except
that the new project "knows" that the old project is its ancestor.
Version numbers in the new project start at the ancestor's version
number.

Clearly, at the moment of creation, a copy requires only a tiny amount
of constant space -- the copy is like an "alias" for the old project.
And if you never commit anything on the copy, then it's just like a
CVS tag.

If you start committing on the copy, then it's a branch.  Voila!

By default, inversion uses per-project namespaces for copies, to avoid
cross-project name conflicts.<commit_msg>Correct/expand I18N section (I mean I2N, I mean I1N...)<commit_after>    Oh Most Noble and Virile Emacs, please be in -*- outline -*- mode!

     Inversion: A Version Control System You Actually Want To Use
     ------------------------------------------------------------
              ($Revision: 1.8 $ of this document.)

* Introduction

This document describes Inversion, a replacement for CVS.  We may
sometimes call it "Ivn", to save space.  It will be described largely
in terms of how it differs, or doesn't differ, from CVS; if you don't
already know CVS, this document will be pretty unreadable.

Where you see the word "version", it means the same thing "revision"
does in the CVS documentation.  Everyone always ends up saying
"version" anyway, then correcting themselves, so let's just give up
already.  Besides, it's shorter to type.

"Project" and "Repository" also mean what you think they do -- a
repository is a place where multiple projects are stored.  Sometimes I
might slip and say "repository" where I should have said "project",
because CVS uses the r-word for both.  Bear with me.

* Requirements

** All CVS features are supported.

Everything CVS has, we want.  Versioning, folding of non-conflicting
changes, detection of conflicting changes, branching, merging,
historical diffs, log messages, line-by-line history ("cvs annotate"),
the works.

Generally, Inversion's conceptual interface to a particular feature
will be as similar to CVS's as possible, except when there's a
compelling reason to do otherwise.

** Version numbers are project-wide and atomic.

Unlike CVS, each Inversion commit results in a single new version
number, which applies to the project as a whole (i.e., it applies to
every object in the project, whether changed or not).  There are no
longer separate per-file version numbers, at least not user-visible
ones.

Commits are atomic -- either the entire commit succeeded, or the
entire commit failed.  No one can ever retrieve a project tree in an
inconsistent state.

Lock-time is kept to a minimum.  A commit may block on another commit,
but only briefly, and only when absolutely necessary -- that is, when
the same files would be affected.  Readers neither cause nor wait for
locks.

** Directories, renames, and file meta-data are versioned.

Naturally!

By the way, rename support means you can trace through ancestry by
name *or* by entity.  For example, if you say "Give me version 12
of foo.c", you might mean version 12 of the file whose name is
*now* foo.c (but perhaps it was named bar.c back at version 12),
or you might mean the file whose name was foo.c in version 12 (perhaps
that file no longer exists, or has a different name now).  Inversion
offers a way to specify which interpretation you want, while
defaulting to the most reasonable interpretation in context.  We
haven't decided what "reasonable" means yet, but we're working on
that.

** Binary files are handled just like anything else.

That's right, no more "-kb" flag. :-)

Whether Inversion is able to merge changes into a file gracefully, or
show diffs, depends on whether diffing and/or merging tools are
defined for that type of file.  Right now, we know that text files are
supported.  (How does Inversion know whether something's text file or
not?  Well, you can tell it the type explicitly, or ask it to deduce
on the fly.)

Also, for text files, Inversion can do platform-specific end-of-line
conversion (CRLF vs LF, etc), just like CVS.

Regarding keyword expansion: Inversion does support it, but only on
request.  By default, keyword expansion is off -- if you do not ask
for expansion for a given file or group of files, Inversion will not
modify content.

** I18N/Multilingual support: non-ASCII encodings can be treated as text.

*** User-visible messages

Inversion can be localized so that its messages print out in a
build-time-configured language.

*** Text vs non-text data

In situations where Inversion needs to make an educated guess as to
whether a file is text or not, its takes into account the possibility
of non-ASCII text.  Furthermore, any textual operations on file data
(such as diffing, annotation, and keyword expansion) obey the
conventions of whatever UTF-* encoding the file appears to be.

The user will have a way of signalling to Inversion that a file is to
be treated as a particular encoding, so that users are not dependent
on Inversion's guessing capability.

** Branching and tagging are constant-time operations in Inversion.

CVS makes an unnecessary distinction between branches and tags, and
then goes on to implement them in an inefficient way.

Inversion supports them both with one efficient operation: `copy'.  To
copy a project is to create another project exactly like it, except
that the new project "knows" that the old project is its ancestor.
Version numbers in the new project start at the ancestor's version
number.

Clearly, at the moment of creation, a copy requires only a tiny amount
of constant space -- the copy is like an "alias" for the old project.
And if you never commit anything on the copy, then it's just like a
CVS tag.

If you start committing on the copy, then it's a branch.  Voila!

By default, inversion uses per-project namespaces for copies, to avoid
cross-project name conflicts.
{'fraction_non_alphanumeric': 0.06382556987115956, 'fraction_numerical': 0.0028741328047571855, 'mean_word_length': 3.8259206121472977, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5789250', 'n_tokens_mistral': 2690, 'n_tokens_neox': 2525, 'n_words': 1584}