2 years agoOpen files in binary mode master
Giuseppe Bilotta [Fri, 22 Dec 2017 09:07:37 +0000 (10:07 +0100)] 
Open files in binary mode

This should fix GitHub issue #4.

Additionally, opening in binary mode already forces the ASCII-8BIT
encoding, so there's no need to specify it anymore.

3 years agoEscape filename when passing it to RCS 0.7.3
Giuseppe Bilotta [Fri, 31 Mar 2017 20:23:41 +0000 (22:23 +0200)] 
Escape filename when passing it to RCS

Passing the unquoted filename to `co` when expanding keywords would fail
for filenames containing spaces, quotes or other odds and ends. Use the
escape function provided by the Shellwords module to quote it.

5 years agoTranscode non-UTF-8 log messages
Giuseppe Bilotta [Sun, 17 Aug 2014 14:30:45 +0000 (16:30 +0200)] 
Transcode non-UTF-8 log messages

git fast-import assumes that the log messages are in UTF-8, and if this
is not the case strange things can happen (such as truncated log message
and whatnot). Allow the user to specify the encoding of log messages,
and in this case transcode all logs from the specified encoding to

6 years agopatch from Jonathan Neider, with one fixup - the emit_committer function has
Thomas Dickey [Sun, 3 Jun 2012 00:39:09 +0000 (00:39 +0000)] 
patch from Jonathan Neider, with one fixup - the emit_committer function has
to be outside the class-functions.


6 years agoadd a to-do for symbolic revisions. I label releases, and omit files from
Thomas Dickey [Sun, 22 Jan 2012 21:52:13 +0000 (21:52 +0000)] 
add a to-do for symbolic revisions.  I label releases, and omit files from
a label when the files have been deleted.

6 years agoMinor tweaks for expand_keywords
Giuseppe Bilotta [Sat, 25 Jan 2014 12:27:09 +0000 (13:27 +0100)] 
Minor tweaks for expand_keywords

6 years agoimplement --expand-keywords option, which replaces the head/diff text that
Thomas Dickey [Sun, 22 Jan 2012 21:48:05 +0000 (21:48 +0000)] 
implement --expand-keywords option, which replaces the head/diff text that
was read from the archive file with the output from "co -p", thereby expanding
all of the rcs keywords.

6 years agoWarn about missing authors in map
Giuseppe Bilotta [Sat, 25 Jan 2014 11:57:45 +0000 (12:57 +0100)] 
Warn about missing authors in map

Warn (once) for each RCS username that has no corresponding map entry.
The warning can be disabled.

Inspired by a Thomas Dickey <dickey@his.com> patch.

6 years agoFramework to ignore files
Giuseppe Bilotta [Sat, 25 Jan 2014 11:32:12 +0000 (12:32 +0100)] 
Framework to ignore files

Feature inspired by a Thomas Dickey <dickey@his.com> patch to ignore
files named `RCS` (managed by `permit`).

6 years agomake that change a little less ugly by using a procedure.
Thomas Dickey [Tue, 10 Jan 2012 21:39:09 +0000 (21:39 +0000)] 
make that change a little less ugly by using a procedure.
I considered using
$stdout.flush if $stdout.tty?
but that doesn't help in vile, since both stderr/stdout are non-tty's

6 years agoflush stdout before stderr writes, avoiding confusion when debugging.
Thomas Dickey [Tue, 10 Jan 2012 21:26:42 +0000 (21:26 +0000)] 
flush stdout before stderr writes, avoiding confusion when debugging.

6 years agoTypo in comment
Giuseppe Bilotta [Sat, 25 Jan 2014 10:41:43 +0000 (11:41 +0100)] 
Typo in comment

6 years agoAlso search hidden directories for RCS files.
Simon Ruderich [Wed, 20 Nov 2013 14:35:51 +0000 (15:35 +0100)] 
Also search hidden directories for RCS files.

Useful when converting configuration files managed with RCS.

6 years agoWe have no --usage flag, it's called help
Giuseppe Bilotta [Wed, 20 Nov 2013 20:21:37 +0000 (21:21 +0100)] 
We have no --usage flag, it's called help

7 years agoFix date parsing for Ruby 1.9
Giuseppe Bilotta [Mon, 27 May 2013 05:37:31 +0000 (07:37 +0200)] 
Fix date parsing for Ruby 1.9

7 years agoOnly check for empty first diff line if there are diff lines
Giuseppe Bilotta [Wed, 10 Oct 2012 08:06:31 +0000 (10:06 +0200)] 
Only check for empty first diff line if there are diff lines

When an RCS commit is forced, the diff will be empty (no diff lines),
so chomping the first (non-existant) line to check if it's empty will
raise an exception.

Fix by not checking for the emptiness of the first line if there aren't
any lines in the diff.

7 years agoSet standard output in binary mode
Giuseppe Bilotta [Tue, 9 Oct 2012 12:18:04 +0000 (14:18 +0200)] 
Set standard output in binary mode

This ensures that in Windows the lines are terminated by a single 0x0a
line ending instead of the DOS/Windows 0x0d 0x0a line ending, which is
not appreciated by git fast-import.

7 years agoFind the location when the executable is not a symlink
Giuseppe Bilotta [Tue, 9 Oct 2012 09:13:40 +0000 (11:13 +0200)] 
Find the location when the executable is not a symlink

When finding the path to the real `rcs-fast-export.rb`, we can't use
`File.readlink` on its own because it will fail with `Errno::EINVAL` if
`__FILE__` is not a symlink. Rescue with `__FILE__` to catch this case.

7 years agoCope with empty initial diff lines
Giuseppe Bilotta [Thu, 27 Sep 2012 12:49:31 +0000 (14:49 +0200)] 
Cope with empty initial diff lines

Some malformed RCS files can have an inital empty line in the text block
for diffs, e.g.

    d1 1

instead of

    @d1 1

Survive this by skipping an initial empty line, but alert the user so
they know something fishy is going on.

7 years agoauxiliary function to alert of (recoverable) errors
Giuseppe Bilotta [Thu, 27 Sep 2012 12:49:14 +0000 (14:49 +0200)] 
auxiliary function to alert of (recoverable) errors

7 years agoVerboser error on malformed diffs
Giuseppe Bilotta [Thu, 27 Sep 2012 08:12:13 +0000 (10:12 +0200)] 
Verboser error on malformed diffs

7 years agoSmall introductory blurb on top 0.2.7
Giuseppe Bilotta [Tue, 25 Sep 2012 17:47:38 +0000 (19:47 +0200)] 
Small introductory blurb on top

7 years agoAdd --version
Giuseppe Bilotta [Tue, 25 Sep 2012 17:40:47 +0000 (19:40 +0200)] 
Add --version

Add a minimal versioning infrastructure to the script, to assist both
bug reporters (it's easier to report the development version being used,
it's just the output of `rcs-fast-export.rb --version`) and packagers
(which are assumed to set the RFE_VERSION constant to a meaningful
string based on tagged released and whatever else they may feel

7 years agoThere can be multiple branches per line, obviously
Giuseppe Bilotta [Fri, 21 Sep 2012 10:40:54 +0000 (12:40 +0200)] 
There can be multiple branches per line, obviously

7 years agoDon't misinterpret `branches`
Giuseppe Bilotta [Thu, 20 Sep 2012 17:48:54 +0000 (19:48 +0200)] 
Don't misinterpret `branches`

The `branches` keyword indicates which branches depart from the current
revision. Its value should therefore _not_ be stored in the current
commit `branches` set.

Removing this prevents the generation of spurious branches at every
branch point.

7 years agoAlways specify from if present
Giuseppe Bilotta [Thu, 20 Sep 2012 17:34:42 +0000 (19:34 +0200)] 
Always specify from if present

Not specifying `from` during the export is a useless optimization, and
can in fact cause problems when the commit export sequence jumps between

7 years agoFix previous commit
Giuseppe Bilotta [Thu, 20 Sep 2012 17:31:39 +0000 (19:31 +0200)] 
Fix previous commit

By supporting one-line branches specification, the previous commit
actually broke support for multi-line specifications. Fix by also
checking for end-of-line right after the `branches` keyword.

7 years agoFix branch handling
Giuseppe Bilotta [Thu, 20 Sep 2012 16:22:30 +0000 (18:22 +0200)] 
Fix branch handling

The script assumed that when the branches keyword had arguments, these
were in subsequent lines; however, this is not always the case: we can
also have

    branches somebranch;

Fix this by catching any lines _starting_ with 'branches ' rather than
just matching the word. This must be done after skipping over empty
branches line, and by re-processing the line after stripping the initial
'branches ' part so that the :branches action processing only finds the
actual branch.

7 years agodon't trim "RCS" that is part of longer dir name
Nathan Stratton Treadway [Mon, 27 Aug 2012 19:12:46 +0000 (15:12 -0400)] 
don't trim "RCS" that is part of longer dir name

When a directory is specified on the command line and the program
is converting the names of the input files being processed into output
filenames, don't strip "RCS" off the end unless that's the full name of
the final directory in the input path.

(Before this fix, an input file named something like
"from_RCS/sourcefile,v" have produced an output path of

7 years agoignore trailing slash on directory argument
Nathan Stratton Treadway [Mon, 27 Aug 2012 18:15:34 +0000 (14:15 -0400)] 
ignore trailing slash on directory argument

When a directory is specified on the command line, ignore any trailing
slashes on that path name. (Before this fix, including a trailing
slash on a directory name would prevent that path from being stripped
off the front of the output filenames as it should have been.)

7 years agoCommit.exports(): use #join (to work in Ruby 1.9)
Nathan Stratton Treadway [Mon, 20 Aug 2012 21:00:36 +0000 (17:00 -0400)] 
Commit.exports(): use #join (to work in Ruby 1.9)

When rcs-fast-export.rb was run in "directory" mode under Ruby 1.9, then
log messages that were output came out in "array" format rather than plain
text, as in
  ["log line 1\n","log line 2\n"]

Switching from ".to_s" to ".join" allows this to work in both Ruby 1.8 and

(This is fix is similar to commit 3dbc2f0ee9e36444c6927ad1ec7dc163f08d6f2f
from Jan 12 2011, which makes a similar change to the log messages output
when the script processes a single RCS file.)

7 years agosteal_username: be more Ruby 1.9-friendly
Giuseppe Bilotta [Sun, 10 Jun 2012 14:49:07 +0000 (10:49 -0400)] 
steal_username: be more Ruby 1.9-friendly

The closing empty array was making Ruby 1.9 nervous, get rid of it.

8 years agoSupport deleted files
Giuseppe Bilotta [Mon, 16 Jan 2012 16:54:30 +0000 (17:54 +0100)] 
Support deleted files

Some RCS derivatives (cs-rcs, cvs) use the 'dead' file state to mark
files that are deleted from a specific revision. Support this.

8 years agoPreserve commit date during coalesce
Giuseppe Bilotta [Mon, 11 Jul 2011 14:52:26 +0000 (16:52 +0200)] 
Preserve commit date during coalesce

Instead of altering the commit date when coalescing commits, keep a
minimum and maximum date that get updated to span the whole time range
from the first to the last commit merged.

8 years agoRewrite commit coalescing logic to preserve monotonicity
Giuseppe Bilotta [Mon, 11 Jul 2011 13:51:50 +0000 (15:51 +0200)] 
Rewrite commit coalescing logic to preserve monotonicity

The previous logic would allow a situation such as A A' B B' C C'
where A' B' and C' could be merged to result in A A* B C violating
history flow for files in B and C.

The new strategy coalesces less commits but the result is (or should be
modulo new bugs) correct.

8 years agoAllow export of main branch for multi-file repos
Giuseppe Bilotta [Mon, 11 Jul 2011 07:35:51 +0000 (09:35 +0200)] 
Allow export of main branch for multi-file repos

8 years agoMake branches into a Set too
Giuseppe Bilotta [Mon, 11 Jul 2011 06:52:33 +0000 (08:52 +0200)] 
Make branches into a Set too

Commit 9698794877f857871b48a1d39afc6f9eb50d2e79 broke the single-file
branch management by causing a failure when branches and symbols were
merged. Fix by making branches into a Set too.

9 years agoruby 1.9: Array#to_s != Array#join
Giuseppe Bilotta [Wed, 12 Jan 2011 13:09:33 +0000 (14:09 +0100)] 
ruby 1.9: Array#to_s != Array#join

Since Ruby 1.9, Array#to_s maps to #inspect of #join, so just use #join,
as it works in both.

9 years agoruby 1.9: open RCS file with ASCII-8BIT encoding
Giuseppe Bilotta [Wed, 12 Jan 2011 13:05:39 +0000 (14:05 +0100)] 
ruby 1.9: open RCS file with ASCII-8BIT encoding

9 years agoMark TODO about commitid
Giuseppe Bilotta [Sun, 14 Nov 2010 08:58:37 +0000 (09:58 +0100)] 
Mark TODO about commitid

Apparently, RCS 5.8 and later are going to support commitid (from CVS).
Consider adding this to rcs-fast-export too as it would make life
easier for us.

9 years agoSuggest a simple "git reset" after import
Giuseppe Bilotta [Fri, 15 Oct 2010 22:35:25 +0000 (00:35 +0200)] 
Suggest a simple "git reset" after import

This is much safer than git reset --hard as it doesn't overwriter local
changes that might be present.

9 years agoAlways coalesce commits if symbols lists are subsets
Giuseppe Bilotta [Wed, 13 Oct 2010 21:22:36 +0000 (23:22 +0200)] 
Always coalesce commits if symbols lists are subsets

Commit coalescing is now skipped only if each symbol list has an item
which is not in the other, and --no-symbol-check overrides this. To
speed things up in this sense, the symbols list is now a Set instead of
an Array.

Add some related TODOs and rewrite the warning messages too.

9 years agoOption to coalesce commits with differing symbol lists
Giuseppe Bilotta [Tue, 12 Oct 2010 23:21:21 +0000 (01:21 +0200)] 
Option to coalesce commits with differing symbol lists

9 years agoSmall help text rewording
Giuseppe Bilotta [Tue, 12 Oct 2010 20:00:19 +0000 (22:00 +0200)] 
Small help text rewording

9 years agoTypo fixes and documentation improvements.
Eric S. Raymond [Tue, 12 Oct 2010 17:40:55 +0000 (13:40 -0400)] 
Typo fixes and documentation improvements.

9 years agoHandle fuzzy coalescing errors
Giuseppe Bilotta [Sun, 25 Jul 2010 18:20:29 +0000 (20:20 +0200)] 
Handle fuzzy coalescing errors

Detect failures to coalesce commits fuzzily and inform the user without

9 years agoAtomic merges
Giuseppe Bilotta [Sun, 25 Jul 2010 15:53:11 +0000 (17:53 +0200)] 
Atomic merges

Move the tree-merging method to Tree, and make it atomic: if merging
fails, the tree is not updated. Since the error propagates up, and the
tree merge is the first step of a commit merge, commit merges are atomic

9 years agoSkip unhandled commands correctly
Giuseppe Bilotta [Mon, 28 Jun 2010 14:20:05 +0000 (16:20 +0200)] 
Skip unhandled commands correctly

Commands such as access can be multi-line, so keep skipping until we come
across the terminating semicolon.

9 years agoFixed bug when binary file changed in RCS.
Ben Martin [Mon, 21 Jun 2010 14:13:17 +0000 (10:13 -0400)] 
Fixed bug when binary file changed in RCS.

If the RCS file being tracked is missing a final new-line character, the
program would crash whenever the last line was deleted and then added.

Reproduction steps:

mkdir /tmp/bug_demo && cd /tmp/bug_demo
rcs -i foo.txt
echo -n "foo" > foo.txt
ci foo.txt
co -l foo.txt
echo -n "d" >> foo.txt
ci foo.txt
git init
~/bin/rcs-fast-export.rb foo.txt,v

9 years agoAdded 'expand' to the list of known but unhandled RCS commands.
Ben Martin [Mon, 21 Jun 2010 14:08:49 +0000 (10:08 -0400)] 
Added 'expand' to the list of known but unhandled RCS commands.

10 years agoProper file modes
Giuseppe Bilotta [Tue, 13 Apr 2010 21:21:38 +0000 (23:21 +0200)] 
Proper file modes

10 years agoPreliminary support for full-repo export
Giuseppe Bilotta [Tue, 13 Apr 2010 21:15:38 +0000 (23:15 +0200)] 
Preliminary support for full-repo export

10 years agoImprove parsing
Giuseppe Bilotta [Tue, 13 Apr 2010 08:58:55 +0000 (10:58 +0200)] 
Improve parsing

Some (older?) RCS files have a more lax syntax (e.g. symbols in the same line
as the symbols command itself, multiple symbols per line, etc). Handle this
situation, and take the change to give the parser an overall cleaner approach.
In particular, tell apart unsupported (skipped) commands from unknown ones (abort).

10 years agoImport entire directories
Giuseppe Bilotta [Wed, 12 Aug 2009 09:31:16 +0000 (11:31 +0200)] 
Import entire directories

It is now possible to specify directories instead of files, in which
case the directory structure is descended, importing all RCS-tracked
files, considered with their path relative to the specified directory.

Feature suggested in private communication by David Kettler.

10 years agoOption to prepend filenames to commit logs
Giuseppe Bilotta [Wed, 12 Aug 2009 08:27:46 +0000 (10:27 +0200)] 
Option to prepend filenames to commit logs

Feature suggested in private comunication by David Kettler.

11 years agoSuppress two more warnings
Giuseppe Bilotta [Sat, 4 Apr 2009 09:20:40 +0000 (11:20 +0200)] 
Suppress two more warnings

* parenthesize an Array explosion
* define :date as an attribute reader since we're going to define the
  :date= writer ourselves

11 years agoFix warning about missing parens around arg
Ben Jackson [Fri, 3 Apr 2009 22:20:48 +0000 (15:20 -0700)] 
Fix warning about missing parens around arg

11 years agoBackport Integer#odd? to older Ruby versions
Giuseppe Bilotta [Sat, 4 Apr 2009 08:47:24 +0000 (10:47 +0200)] 
Backport Integer#odd? to older Ruby versions

As pointed out by a private communication from Ben Jackson, Integer#odd?
was introduced in Ruby 1.8.7; to make the script runnable on older Ruby
versions, we define the method ourselves if it's missing.

11 years agoFix diff index handling
Giuseppe Bilotta [Sat, 28 Mar 2009 00:05:04 +0000 (01:05 +0100)] 
Fix diff index handling

Inserting text at index 0 (a0 N command, to prepend N lines) resulted in
text being appended since the diff index 0 was mapped to Ruby index -1.
The solution is to turn insertions into Array#unshift rather than
Array#<<, so that they can use the same index as the diff, and only
decrementing the diff index for deletions.

11 years agoBuild buffer as an array of arrays
Giuseppe Bilotta [Fri, 27 Mar 2009 23:44:11 +0000 (00:44 +0100)] 
Build buffer as an array of arrays

Sanitizing the buffer by splitting buffer entries at newlines causes the
newlines to disappear. A much cleaner solution, which doesn't have this
serious bug, is to turn the buffer into a buffer of arrays of strings,
to be flattened right before the final assignment.

11 years agosanitize buffer after ranges of additions
Giuseppe Bilotta [Thu, 26 Mar 2009 07:52:32 +0000 (08:52 +0100)] 
sanitize buffer after ranges of additions

When adding a range of lines, they would be added as a single string
with embedded newlines so as to preserve line indices for subsequent
insertions/deletions. However, such lines need to be split before
loading them into the next revision text buffer, to ensure that
revisions using the new one as diff base find the correct lines.

11 years agoExport all branches for each revision
Giuseppe Bilotta [Thu, 26 Mar 2009 00:34:41 +0000 (01:34 +0100)] 
Export all branches for each revision

11 years agoHandle symbolic heads
Giuseppe Bilotta [Thu, 26 Mar 2009 00:27:51 +0000 (01:27 +0100)] 
Handle symbolic heads

RCS files can contain symbols that don't point to an actual commit;
checking out these symbols retrieves the highest revision with matching
major numbers. Fo example, with symbol SYM:3 and revisions 2.1, 3.1,
3.2, 4.1, checking out SYM results in 3.2 being checked out.

This feature translates pretty straightforwardly to git heads. These
symbols are detected by their missing date and are deleted after
assigning their name as branch to the appropriate revision.

11 years agoTry to guess the user's name and email
Giuseppe Bilotta [Tue, 18 Nov 2008 00:00:14 +0000 (01:00 +0100)] 
Try to guess the user's name and email

A common use case for RCS fast export is likely to be of a user trying to
convert its RCS histories into git histories. In these cases we don't need an
authors file, since the committer full name and email are information likely
to be found elsewhere.

We look at the git config, but also the gecos entry in the passwd file. As
extreme resources we also peek in their .hgrc and .vimrc files

11 years agoDocument config options in usage
Giuseppe Bilotta [Mon, 17 Nov 2008 22:17:10 +0000 (23:17 +0100)] 
Document config options in usage

11 years agoAlso read config option rcs.tageachrev
Giuseppe Bilotta [Mon, 17 Nov 2008 22:15:23 +0000 (23:15 +0100)] 
Also read config option rcs.tageachrev

11 years agoConfig before command line
Giuseppe Bilotta [Mon, 17 Nov 2008 22:12:12 +0000 (23:12 +0100)] 
Config before command line

11 years agoImprove usage
Giuseppe Bilotta [Mon, 17 Nov 2008 22:09:43 +0000 (23:09 +0100)] 
Improve usage

11 years agoExpand authorsfile path
Giuseppe Bilotta [Mon, 17 Nov 2008 21:59:28 +0000 (22:59 +0100)] 
Expand authorsfile path

11 years agoAlso read config option rcs.authorsfile
Giuseppe Bilotta [Mon, 17 Nov 2008 21:58:59 +0000 (22:58 +0100)] 
Also read config option rcs.authorsfile

11 years agoImplement --authors-file option
Giuseppe Bilotta [Mon, 17 Nov 2008 21:45:03 +0000 (22:45 +0100)] 
Implement --authors-file option

11 years agoImplement --tag-each-rev option
Giuseppe Bilotta [Mon, 17 Nov 2008 21:32:01 +0000 (22:32 +0100)] 
Implement --tag-each-rev option

11 years agoOptions infrastructure
Giuseppe Bilotta [Mon, 17 Nov 2008 20:51:50 +0000 (21:51 +0100)] 
Options infrastructure

11 years agoImport RCS symbols as lightweight git tags
Giuseppe Bilotta [Mon, 17 Nov 2008 19:47:07 +0000 (20:47 +0100)] 
Import RCS symbols as lightweight git tags

11 years agoFix branch names
Giuseppe Bilotta [Mon, 17 Nov 2008 18:35:13 +0000 (19:35 +0100)] 
Fix branch names

11 years agoInitial commit
Giuseppe Bilotta [Sat, 15 Nov 2008 02:11:31 +0000 (03:11 +0100)] 
Initial commit