]> source.dussan.org Git - jgit.git/log
jgit.git
13 years agoDHT: Replace TinyProtobuf with Google Protocol Buffers 45/3345/7
Shawn O. Pearce [Fri, 13 May 2011 14:44:42 +0000 (07:44 -0700)]
DHT: Replace TinyProtobuf with Google Protocol Buffers

The standard Google distribution of Protocol Buffers in Java is better
maintained than TinyProtobuf, and should be faster for most uses.  It
does use slightly more memory due to many of our key types being
stored as strings in protobuf messages, but this is probably worth the
small hit to memory in exchange for better maintained code that is
easier to reuse in other applications.

Exposing all of our data members to the underlying implementation
makes it easier to develop reporting and data mining tools, or to
expand out a nested structure like RefData into a flat format in a SQL
database table.

Since the C++ `protoc` tool is necessary to convert the protobuf
script into Java code, the generated files are committed as part of
the source repository to make it easier for developers who do not have
this tool installed to still build the overall JGit package and make
use of it.  Reviewers will need to be careful to ensure that any edits
made to a *.proto file come in a commit that also updates the
generated code to match.

CQ: 5135
Change-Id: I53e11e82c186b9cf0d7b368e0276519e6a0b2893
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoDHT: Remove per-process ChunkCache 41/3341/4
Shawn O. Pearce [Thu, 5 May 2011 18:18:54 +0000 (11:18 -0700)]
DHT: Remove per-process ChunkCache

Performance testing has indicated the per-process ChunkCache isn't
very effective for the DHT storage implementation.  If a server is
using the DHT storage backend, it is most likely part of a larger
cluster where requests are distributed in a round-robin fashion
between the member servers.

In such a scenario there is insufficient data locality between
requests to get a good hit ratio on the per-process ChunkCache.  A low
hit ratio means the cache is actually hurting performance by eating up
memory that could otherwise be used for transient request data, and
increasing pressure on the GC when it needs to find free space.

Remove all of the ChunkCache code.  Installations that want to cache
(to reduce database usage) should wrap their Database with a
CacheDatabase and use a network based CacheServer.

I left the ChunkCache in the original DHT storage commit because I
wanted to document in the history of the project that its probably
worth *not* having, but leave open a door for someone to revert this
change if they find otherwise at a later date.

Change-Id: I364d0725c46c5a19f7443642a40c89ba4d3fdd29
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Let RefDirectory use FileSnapShot to handle fast updates"
Chris Aniszczyk [Wed, 25 May 2011 13:46:49 +0000 (09:46 -0400)]
Merge "Let RefDirectory use FileSnapShot to handle fast updates"

13 years agoAdd a DiffFormatter which calculates a patch-id 86/3486/4
Stefan Lay [Tue, 24 May 2011 08:38:59 +0000 (01:38 -0700)]
Add a DiffFormatter which calculates a patch-id

Adds a class which can be used to calculates a SHA1 of the diff
associated with a patch, similar to git patch-id.

In this version whitespace is not ignored.

Change-Id: I421d15ea905e23df543082786786841cbe3ef10d
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd CleanCommandTest and fix CleanCommand 17/3517/5
Abhishek Bhatnagar [Tue, 24 May 2011 18:45:05 +0000 (14:45 -0400)]
Add CleanCommandTest and fix CleanCommand

Bug: 334767
Change-Id: I0a836451ceb668f943b1f353dc65420157810b23
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd CleanCommand to JGit API 84/3484/6
Abhishek Bhatnagar [Fri, 20 May 2011 16:01:37 +0000 (12:01 -0400)]
Add CleanCommand to JGit API

Bug: 334767
Change-Id: I2650c77bc4af2d8f401bbcce5384b44ff2a64ba2
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoLet RefDirectory use FileSnapShot to handle fast updates 81/3481/3
Christian Halstrick [Fri, 20 May 2011 09:18:20 +0000 (11:18 +0200)]
Let RefDirectory use FileSnapShot to handle fast updates

Since this change may affect performance and memory consumption on every
access to a loose ref I explicitly made it a RFC to collect opinions.

Previously RefDirectory.scanRef() was not detecting an update of a
loose ref when the update didn't changed the modification time of
the backing file. RefDirectory cached loose refs and the way to detect
outdated cache entries was to compare lastmodification timestamp on the
file representing the ref. If two updates to the same ref happen faster
than the filesystem-timer granularity (for linux this is 2 seconds)
there is the possiblity that we don't detect the update.

Because of this bug EGit's PushOperationTest only works with 2 second
sleeps inside.

This change let RefDirectory use FileSnapshot to detect such situations.
FileSnapshot helps to remember when a file was last read from disk and
therefore enables to decide when to load a file from disk although
modification time has not changed.

Change-Id: I03b9a137af097ec69c4c5e2eaa512d2bdd7fe080
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd shortening of note ref names to NoteMap 04/3504/3
Kevin Sawicki [Mon, 23 May 2011 18:39:33 +0000 (11:39 -0700)]
Add shortening of note ref names to NoteMap

Change-Id: I224190bbb41c7cbea38388d0148ecc6dc68f3a14
Signed-off-by: Kevin Sawicki <kevin@github.com>
13 years agoMerge "Remove rebase temporary files on checkout failure"
Shawn Pearce [Mon, 23 May 2011 15:33:49 +0000 (11:33 -0400)]
Merge "Remove rebase temporary files on checkout failure"

13 years agoAdd GitAddTask 79/3479/2
Ketan Padegaonkar [Fri, 20 May 2011 09:15:00 +0000 (14:45 +0530)]
Add GitAddTask

Change-Id: Ia9a3c9f4728e13d1e62f530b1d843d09afb4eb42
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoRemove rebase temporary files on checkout failure 99/3499/2
Bernard Leach [Sun, 22 May 2011 14:20:32 +0000 (00:20 +1000)]
Remove rebase temporary files on checkout failure

A checkout conflict during rebase setup should leave the repository
in SAFE state which means ensuring that the rebase temporary files
need to be removed.

Bug: 346813
Change-Id: If8b758fde73ed5a452a99a195a844825a03bae1a
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd LsRemoteCommandTest 74/3474/3
Chris Aniszczyk [Thu, 19 May 2011 19:39:19 +0000 (14:39 -0500)]
Add LsRemoteCommandTest

Bug: 343801
Change-Id: I4a91d93428bbf7f74033fcea5823266fa52d7a0c
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd LsRemoteCommand to JGit API 46/3346/4
Christoph Brill [Thu, 19 May 2011 19:38:39 +0000 (14:38 -0500)]
Add LsRemoteCommand to JGit API

Bug: 343801
Change-Id: Ic651e8e09143e15ed459461b50b2222e13da56c4
Also-by: Chris Aniszczyk <caniszczyk@gmail.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd org.eclipse.jgit.ant.test to parent pom.xml 71/3471/3
Chris Aniszczyk [Thu, 19 May 2011 16:20:19 +0000 (11:20 -0500)]
Add org.eclipse.jgit.ant.test to parent pom.xml

Change-Id: I3fd0b509e03cbd5f2bf3bd6377287dab14e8728e
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd GitCloneTaskTest 68/3468/2
Ketan Padegaonkar [Thu, 19 May 2011 08:32:02 +0000 (14:02 +0530)]
Add GitCloneTaskTest

Change-Id: Iec8cd032d8d659a896d909f9094f76b7d35147e6
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoCreate a MergeResult for deleted/modified files 09/3409/3
Bernard Leach [Fri, 13 May 2011 05:59:57 +0000 (15:59 +1000)]
Create a MergeResult for deleted/modified files

Change Ia2ab4f8dc95020f2914ff01c2bf3b1bc62a9d45d added merge
support for when OURS or THEIRS was simultaneously deleted
and modified.  That changeset however did not add create an
entry in the conflicts table so clients would see a CONFLICTING
result but getConflicts() would return null.

This change creates a MergeResult for the conflicting file.

Bug: 345684
Change-Id: I52acb81c1729b49c9fb3e7a477c6448d8e55c317
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd reset with paths support to ResetCommand 53/3453/3
Bernard Leach [Thu, 19 May 2011 11:04:20 +0000 (21:04 +1000)]
Add reset with paths support to ResetCommand

Bug: 338701
Change-Id: Id7cbce47131b459e632ddc2c9a94628c7d0b75cd
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoFix NPE in URIish when parsing an empty URI 66/3466/2
Ketan Padegaonkar [Thu, 19 May 2011 07:38:26 +0000 (13:08 +0530)]
Fix NPE in URIish when parsing an empty URI

Change-Id: Id1c42dc9843f62c581b9904b02150de53cf7777c
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd org.eclipse.jgit.ant.test 65/3465/2
Ketan Padegaonkar [Thu, 19 May 2011 06:28:28 +0000 (11:58 +0530)]
Add org.eclipse.jgit.ant.test

Change-Id: I9bfb1298864294b8ce29b91660f1cf8316e5f620
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd tests for change If203ce5 56/3456/2
Bernard Leach [Wed, 18 May 2011 16:41:18 +0000 (11:41 -0500)]
Add tests for change If203ce5

Bug: 344779
Change-Id: I1628984479d93665bf4987d6a4ff8e67ad73eb36
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoImplement rebase ff for upstream branches with merge commits 36/3336/8
Chris Aniszczyk [Wed, 18 May 2011 16:39:33 +0000 (11:39 -0500)]
Implement rebase ff for upstream branches with merge commits

Change Ib9898fe0f982fa08e41f1dca9452c43de715fdb6 added support for
the 'cherry-pick' fast forward case where the upstream commit history
does not include any merge commits.  This change adds support for the
case where merge commits exist and the local branch has no changes.

Bug: 344779
Change-Id: If203ce5aa1b4e5d4d7982deb621b710e71f4ee10
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoFix path filtering in LogCommand 55/3455/3
Piotr Janik [Wed, 18 May 2011 14:22:08 +0000 (16:22 +0200)]
Fix path filtering in LogCommand

Bug: 346257
Change-Id: Ib897e1b4962162da9670164479a844aeea7dfcd1
Signed-off-by: Piotr Janik <janikpiotrek@gmail.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Optimize MergeAlgorithm if ours or theirs is empty"
Robin Rosenberg [Tue, 17 May 2011 12:54:18 +0000 (08:54 -0400)]
Merge "Optimize MergeAlgorithm if ours or theirs is empty"

13 years agoOptimize MergeAlgorithm if ours or theirs is empty 10/3410/3
Christian Halstrick [Tue, 17 May 2011 08:59:17 +0000 (10:59 +0200)]
Optimize MergeAlgorithm if ours or theirs is empty

Previously when merging two contents with a non-empty base and one of
the contents was empty (size == 0) and the other was modified there
was a potentially expensive calculation until we finally always come
to the same result -> the complete non-deleted content should collide
with the empty content.

This proposal adds an optimization to detect empty input content and
to produce the appropriate result immediatly.

Change-Id: Ie6a837260c19d808f0e99173f570ff96dd22acd3
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
13 years agoMerge "Fix diff bug on inserted line"
Stefan Lay [Tue, 17 May 2011 01:15:25 +0000 (21:15 -0400)]
Merge "Fix diff bug on inserted line"

13 years agoFix diff bug on inserted line 35/3435/1
Shawn O. Pearce [Mon, 16 May 2011 18:28:23 +0000 (11:28 -0700)]
Fix diff bug on inserted line

For the following patch on the linux 2.6.32 tag:
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -685,6 +685,7 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sc

 static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
+#if 0
 #ifdef CONFIG_SCHED_DEBUG
        s64 d = se->vruntime - cfs_rq->min_vruntime;

@@ -694,6 +695,7 @@ static void check_spread(struct cfs_rq *cfs_rq, struct
sched
        if (d > 3*sysctl_sched_latency)
                schedstat_inc(cfs_rq, nr_spread_over);
 #endif
+#endif
 }

 static void

JGit produced an incorrect diff, attempting to add a new "}" instead
of the new "#endif" at the end of the hunk. This was caused by a prior
fix for bug 328895 where we wanted to "slide" a diff down in the file
when adding a new method/function and want to show the closing curly
brace as being added after the new method, rather than added onto the
end of the prior function or method just before the insertion point.

Bug: 345956
Change-Id: I32b9e24f1e2980258b1b39dd1807919ab1c5f9b2
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoAdd getConflicting() method in Status API 33/3433/2
Piotr Janik [Mon, 16 May 2011 10:51:05 +0000 (12:51 +0200)]
Add getConflicting() method in Status API

Bug: 345899
Change-Id: I133b9dd3e9a9c3c749547a884df3ce371929f38e
Signed-off-by: Piotr Janik <janikpiotrek@gmail.com>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Fix diff when first text is the start of the other"
Shawn Pearce [Sun, 15 May 2011 19:17:52 +0000 (15:17 -0400)]
Merge "Fix diff when first text is the start of the other"

13 years agoFix diff when first text is the start of the other 56/3356/6
Robin Rosenberg [Sun, 15 May 2011 18:34:05 +0000 (20:34 +0200)]
Fix diff when first text is the start of the other

The problem occurred when the first text ends in the middle
of the last line of the other text and the first text has no
end of line.

Bug: 344975
Change-Id: I1f0dd9f8062f2148a7c1341c9122202e082ad19d
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
13 years agoMerge "Add test for reflog part of ResetCommand"
Chris Aniszczyk [Fri, 13 May 2011 22:05:58 +0000 (18:05 -0400)]
Merge "Add test for reflog part of ResetCommand"

13 years agoAdd test for reflog part of ResetCommand 14/3414/2
Robin Rosenberg [Wed, 4 May 2011 22:26:39 +0000 (00:26 +0200)]
Add test for reflog part of ResetCommand

The reflog message fix was done in
I4f1c3cd6b2cf543be213f061afb94223062dde51

Change-Id: I44817ccf4bf226ed3e4ce6fb2d923e88788221dd
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
13 years agoAdd RebaseResult.FAST_FORWARD_RESULT 13/3413/1
Chris Aniszczyk [Fri, 13 May 2011 14:56:09 +0000 (09:56 -0500)]
Add RebaseResult.FAST_FORWARD_RESULT

Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoRevertCommand: Add "." after reverted commit id 11/3411/1
Robin Stocker [Fri, 13 May 2011 11:39:54 +0000 (13:39 +0200)]
RevertCommand: Add "." after reverted commit id

This makes the message look the same as in C Git (the "."):

  This reverts commit <sha1>.

Change-Id: I4c254c122277b127e7b039c0d1c7f7a0d691530d
Signed-off-by: Robin Stocker <robin@nibor.org>
13 years agoUpdate tycho version to 0.12 74/3374/3
Chris Aniszczyk [Tue, 10 May 2011 20:05:09 +0000 (15:05 -0500)]
Update tycho version to 0.12

Following migration instructions [1].

[1] http://dev.eclipse.org/mhonarc/lists/tycho-user/msg00080.html

Change-Id: I9e54f3e7e96892b64546270cbdf0308046e1d40c
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoUpdate findbugs-maven-plugin to the official 2.3.2 release 76/3376/1
Chris Aniszczyk [Tue, 10 May 2011 20:43:40 +0000 (15:43 -0500)]
Update findbugs-maven-plugin to the official 2.3.2 release

Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Formatter for relative dates"
Christian Halstrick [Mon, 9 May 2011 13:23:37 +0000 (09:23 -0400)]
Merge "Formatter for relative dates"

13 years agoFormatter for relative dates 61/3361/4
Matthias Sohn [Mon, 9 May 2011 12:46:38 +0000 (14:46 +0200)]
Formatter for relative dates

Change-Id: I78b307177c68c578e10101a0ee7b6306880a08f7
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoRemove unused serialVersionUID from non-serializable classes. 65/3365/1
Kevin Sawicki [Mon, 9 May 2011 00:51:45 +0000 (17:51 -0700)]
Remove unused serialVersionUID from non-serializable classes.

Change-Id: I819e2ca88577382b54d38b7a1247e94a5127ef9e
Signed-off-by: Kevin Sawicki <kevin@github.com>
13 years agoFix getHumanishName broken for windows paths 98/3198/6
Stefan Lay [Fri, 6 May 2011 08:42:51 +0000 (10:42 +0200)]
Fix getHumanishName broken for windows paths

Since d1718a the method getHumanishName was broken on windows since
the URIish is not normalized anymore. For a path like
"C:\gitRepositories\egit" the whole path was returned instead of
"egit".

Bug: 343519
Change-Id: I95056009072b99d32f288966302d0f8188b47836
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
13 years agoMerge "IndexDiff: conflicting files aren't properly shown"
Chris Aniszczyk [Thu, 5 May 2011 19:34:49 +0000 (15:34 -0400)]
Merge "IndexDiff: conflicting files aren't properly shown"

13 years agoCorrect tabs in top-level pom.xml 42/3342/2
Shawn O. Pearce [Thu, 5 May 2011 18:47:57 +0000 (11:47 -0700)]
Correct tabs in top-level pom.xml

Change-Id: I55900b335f2056093e0a32086afb429a4bc183d3
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoIndexDiff: conflicting files aren't properly shown 95/3295/3
Bernard Leach [Fri, 29 Apr 2011 09:42:10 +0000 (19:42 +1000)]
IndexDiff: conflicting files aren't properly shown

Before this change any files in the conflicting set would
also be listed in the the other IndexDiff Sets which is
confusing.  With this change a conflicting file will not
be included in any of the other sets.

Change-Id: Ife9f2652685220bcfddc1f9820423acdcd5acfdc
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoUpdate IP log to include Ant 1.8.2 (CQ 5111) 40/3340/1
Shawn O. Pearce [Thu, 5 May 2011 17:58:03 +0000 (10:58 -0700)]
Update IP log to include Ant 1.8.2 (CQ 5111)

Change-Id: I953720b88d34e74509b115dcd2c1eb48d3587484
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoIgnore submodule commits during checkout 03/3303/3
Robin Rosenberg [Sun, 1 May 2011 21:17:57 +0000 (23:17 +0200)]
Ignore submodule commits during checkout

Submodules are supposed to be handled by separate operations, so
we should ignore them on checkout, just like C Git does.

This fix does not add submodule support. We just try harder
to ignore them.

Bug: 343566
Change-Id: I2c5ae1024ea7bb57adf27072da6acc9643018eda
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
13 years agoMerge "Fix "into" part of merge message for HEAD"
Shawn Pearce [Thu, 5 May 2011 17:38:40 +0000 (13:38 -0400)]
Merge "Fix "into" part of merge message for HEAD"

13 years agoStore Git on any DHT 95/2295/24
Shawn O. Pearce [Wed, 2 Mar 2011 23:23:30 +0000 (15:23 -0800)]
Store Git on any DHT

jgit.storage.dht is a storage provider implementation for JGit that
permits storing the Git repository in a distributed hashtable, NoSQL
system, or other database.  The actual underlying storage system is
undefined, and can be plugged in by implementing 7 small interfaces:

  *  Database
  *  RepositoryIndexTable
  *  RepositoryTable
  *  RefTable
  *  ChunkTable
  *  ObjectIndexTable
  *  WriteBuffer

The storage provider interface tries to assume very little about the
underlying storage system, and requires only three key features:

  *  key -> value lookup (a hashtable is suitable)
  *  atomic updates on single rows
  *  asynchronous operations (Java's ExecutorService is easy to use)

Most NoSQL database products offer all 3 of these features in their
clients, and so does any decent network based cache system like the
open source memcache product.  Relying only on key equality for data
retrevial makes it simple for the storage engine to distribute across
multiple machines.  Traditional SQL systems could also be used with a
JDBC based spi implementation.

Before submitting this change I have implemented six storage systems
for the spi layer:

  * Apache HBase[1]
  * Apache Cassandra[2]
  * Google Bigtable[3]
  * an in-memory implementation for unit testing
  * a JDBC implementation for SQL
  * a generic cache provider that can ride on top of memcache

All six systems came in with an spi layer around 1000 lines of code to
implement the above 7 interfaces.  This is a huge reduction in size
compared to prior attempts to implement a new JGit storage layer.  As
this package shows, a complete JGit storage implementation is more
than 17,000 lines of fairly complex code.

A simple cache is provided in storage.dht.spi.cache.  Implementers can
use CacheDatabase to wrap any other type of Database and perform fast
reads against a network based cache service, such as the open source
memcached[4].  An implementation of CacheService must be provided to
glue this spi onto the network cache.

[1] https://github.com/spearce/jgit_hbase
[2] https://github.com/spearce/jgit_cassandra
[3] http://labs.google.com/papers/bigtable.html
[4] http://memcached.org/

Change-Id: I0aa4072781f5ccc019ca421c036adff2c40c4295
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoAdd org.eclipse.jgit.ant to parent pom.xml 37/3337/3
Chris Aniszczyk [Thu, 5 May 2011 16:33:16 +0000 (18:33 +0200)]
Add org.eclipse.jgit.ant to parent pom.xml

Bug: 321237
Change-Id: Idd106f2700740db07f41f6d31f50d6b2a30fa732
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoFix "into" part of merge message for HEAD 38/3338/2
Robin Stocker [Thu, 5 May 2011 15:33:01 +0000 (17:33 +0200)]
Fix "into" part of merge message for HEAD

Merging into a non-master branch would result in the following message:

  Merge branch 'a' into HEAD

Now the merge message is correct:

  Merge branch 'a' into b

Change-Id: I488f97190e4c1711c23a7a3cbd64f8b13a87bbac
Signed-off-by: Robin Stocker <robin@nibor.org>
13 years agoMerge "Fix error handling in RepositoryFilter"
Chris Aniszczyk [Thu, 5 May 2011 14:35:55 +0000 (10:35 -0400)]
Merge "Fix error handling in RepositoryFilter"

13 years agoAdd pom.xml to org.eclipse.jgit.ant 73/3273/4
Chris Aniszczyk [Wed, 27 Apr 2011 20:59:14 +0000 (15:59 -0500)]
Add pom.xml to org.eclipse.jgit.ant

Also-by: Ketan Padegaonkar <KetanPadegaonkar@gmail.com>
Bug: 321237
CQ: 5111
Change-Id: Ie93b85df76fcb5c077b93f01ed1959eaeffb3c20
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoFix error handling in RepositoryFilter 35/3335/1
Shawn O. Pearce [Wed, 4 May 2011 21:55:53 +0000 (14:55 -0700)]
Fix error handling in RepositoryFilter

The filter did not correctly match smart HTTP client requests,
so it always fell back on HTTP status codes for errors. This
usually causes a smart client to retry a dumb request, which
is not what the server wants.

Change-Id: I42592378dc42fbe308ef30a2923786c690f668a9
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoPresent reset in the reflog like C Git does nowadays 28/3328/1
Robin Rosenberg [Mon, 2 May 2011 23:13:21 +0000 (01:13 +0200)]
Present reset in the reflog like C Git does nowadays

Confirmed for v1.7.4.1

Change-Id: I4f1c3cd6b2cf543be213f061afb94223062dde51
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
13 years agoImplemented merge for parallel delete/modification 94/3294/2
Bernard Leach [Fri, 29 Apr 2011 09:37:00 +0000 (19:37 +1000)]
Implemented merge for parallel delete/modification

Duplicates cgit behaviour for merging the case where
OURS is deleted and THEIRS is modified as well as
OURS is modified and THEIRS id deleted.

Change-Id: Ia2ab4f8dc95020f2914ff01c2bf3b1bc62a9d45d
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd better exception handling for the git-init ant task 13/3313/2
Ketan Padegaonkar [Mon, 2 May 2011 16:48:27 +0000 (09:48 -0700)]
Add better exception handling for the git-init ant task

Change-Id: Ia935720fc9c09b427abb84be038c4dc74610850c
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Attempt to make git prefix detection more reliable"
Chris Aniszczyk [Tue, 3 May 2011 16:53:49 +0000 (12:53 -0400)]
Merge "Attempt to make git prefix detection more reliable"

13 years agoMerge "Add path support to checkout command."
Stefan Lay [Tue, 3 May 2011 15:39:11 +0000 (11:39 -0400)]
Merge "Add path support to checkout command."

13 years agoAdd path support to checkout command. 80/3280/18
Kevin Sawicki [Tue, 3 May 2011 15:07:15 +0000 (08:07 -0700)]
Add path support to checkout command.

Change-Id: I89e8edfc6dd87d5bf8fd08704df2432720084330
Signed-off-by: Kevin Sawicki <kevin@github.com>
13 years agoQualify post-0.12 builds 17/3317/1
Matthias Sohn [Mon, 2 May 2011 22:19:54 +0000 (00:19 +0200)]
Qualify post-0.12 builds

Change-Id: I70fe2671321efb5c3d271121ce00299533d1b388
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoMerge branch 'stable-0.12' 16/3316/1
Matthias Sohn [Mon, 2 May 2011 22:11:47 +0000 (00:11 +0200)]
Merge branch 'stable-0.12'

* stable-0.12:
  JGit 0.12.1

13 years agoAttempt to make git prefix detection more reliable 61/3261/4
Robin Rosenberg [Mon, 2 May 2011 20:35:54 +0000 (22:35 +0200)]
Attempt to make git prefix detection more reliable

This fix makes sure the readPipe methods drains the stderr
pipe and close the subprocess' stdin stream before reading
the process outputs.

I never managed to repeat the reported problem myself, so this
may help in diagnosing the probelm on other peoples machines.

Bug: 337533
Change-Id: I299555f09768c34d5868327e574326946ee265e1

13 years agoAdd better javadoc to the git-init ant task 12/3312/2
Ketan Padegaonkar [Mon, 2 May 2011 16:44:34 +0000 (09:44 -0700)]
Add better javadoc to the git-init ant task

Change-Id: If41e5a9ab37533cce10ea1c1925d7bd3ece586ea
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoJGit 0.12.1 10/3310/1 stable-0.12 v0.12.1
Matthias Sohn [Mon, 2 May 2011 16:24:45 +0000 (18:24 +0200)]
JGit 0.12.1

Change-Id: Ia6e58b466fa3ef7ddd61b40f2ad44141fe8786c4
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoAdd GitCheckoutTask to org.eclipse.jgit.ant 78/3278/4
Ketan Padegaonkar [Tue, 26 Apr 2011 16:41:56 +0000 (09:41 -0700)]
Add GitCheckoutTask to org.eclipse.jgit.ant

Bug: 321237
Change-Id: I5c4753f7b99d0be002b32e403f5dfff9353c57b0
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd GitCloneTask to org.eclipse.jgit.ant 77/3277/3
Ketan Padegaonkar [Tue, 26 Apr 2011 16:33:52 +0000 (09:33 -0700)]
Add GitCloneTask to org.eclipse.jgit.ant

Bug: 321237
Change-Id: I605da8150048158d918c577ef8ca4f6edbed0133
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd org.eclipse.jgit.ant 06/3306/3
Ketan Padegaonkar [Mon, 25 Apr 2011 17:24:48 +0000 (10:24 -0700)]
Add org.eclipse.jgit.ant

Adds the initial project and a GitInitTask.

Bug: 321237
Change-Id: I06b94e0b42b20ecf51f86845e47d49913f3513c4
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge branch 'stable-0.12' 15/3215/1
Shawn O. Pearce [Thu, 21 Apr 2011 23:33:56 +0000 (16:33 -0700)]
Merge branch 'stable-0.12'

* stable-0.12:
  Implement the no-done capability

13 years agoImplement the no-done capability 16/2716/9
Shawn O. Pearce [Tue, 15 Mar 2011 01:18:49 +0000 (18:18 -0700)]
Implement the no-done capability

Smart HTTP clients may request both multi_ack_detailed and no-done in
the same request to prevent the client from needing to send a "done"
line to the server in response to a server's "ACK %s ready".

For smart HTTP, this can save 1 full HTTP RPC in the fetch exchange,
improving overall latency when incrementally updating a client that
has not diverged very far from the remote repository.

Unfortuantely this capability cannot be enabled for the traditional
bi-directional connections.  multi_ack_detailed has the client sending
more "have" lines at the same time that the server is creating the
"ACK %s ready" and writing out the PACK stream, resulting in some race
conditions and/or deadlock, depending on how the pipe buffers are
implemented.  For very small updates, a server might actually be able
to send "ACK %s ready", then the PACK, and disconnect before the
client even finishes sending its first batch of "have" lines.  This
may cause the client to fail with a broken pipe exception.  To avoid
all of these potential problems, "no-done" is restricted only to the
smart HTTP variant of the protocol.

Change-Id: Ie0d0a39320202bc096fec2e97cb58e9efd061b2d
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoMerge branch 'stable-0.12' 12/3212/1
Shawn O. Pearce [Thu, 21 Apr 2011 22:41:10 +0000 (15:41 -0700)]
Merge branch 'stable-0.12'

* stable-0.12:
  Fix sorting of names in RefDirectory
  Make running static checks configurable in maven build
  Add constants for gerrit change id configuration

13 years agoFix sorting of names in RefDirectory 08/3208/1
Shawn O. Pearce [Thu, 21 Apr 2011 19:40:26 +0000 (12:40 -0700)]
Fix sorting of names in RefDirectory

RefDirectory did not correctly follow the contract of RefList.  The
contract says if you use add() method of RefList builder, you MUST
sort() it afterwards, and later every other method assumes that list
is properly sorted (especially the binary search in the find() and
get() methods).  Instead RefDirectory class tried to scan the refs
recursively while sorting every folder in the process before
processing and did not call sort().

For example, when scanning the contents of refs/tags project1 string
is smaller than project1-*, so it will recursively go into the folder
and add these tags first and only then will add project-* ones. This
will result in a broken list (any project1-* string is less than
project1/* one, but they all appear after them in the list), that's
why binary search will fail making loose RefList and the whole local
RefMap completely unusable.

Change-Id: Ibad90017e3b2435b1396b69a22520db4b1b022bb
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoEnabled unit tests in HttpClientTests 96/3196/1
Christian Halstrick [Tue, 12 Apr 2011 15:21:27 +0000 (17:21 +0200)]
Enabled unit tests in HttpClientTests

Change-Id: I92ae117f1dcfc569e27c66c191e090a60fbe2bb6
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
13 years agoAdded support to IndexDiff to return information on conflicts 05/3105/4
Bernard Leach [Tue, 19 Apr 2011 21:51:40 +0000 (07:51 +1000)]
Added support to IndexDiff to return information on conflicts

Change-Id: I43c13eb72a44f80135c93525fce0c0280b0e64a2
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Make running static checks configurable in maven build" into stable-0.12
Shawn Pearce [Mon, 18 Apr 2011 15:46:47 +0000 (11:46 -0400)]
Merge "Make running static checks configurable in maven build" into stable-0.12

13 years agoMake running static checks configurable in maven build 47/3147/2
Matthias Sohn [Sat, 16 Apr 2011 00:08:24 +0000 (02:08 +0200)]
Make running static checks configurable in maven build

In order to run the static checks run:

mvn -P static-checks clean install

Change-Id: I14077498a04be986ded123ddbfc97da8f9bc3130
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoAdd constants for gerrit change id configuration 19/3119/1
Stefan Lay [Thu, 14 Apr 2011 15:25:22 +0000 (17:25 +0200)]
Add constants for gerrit change id configuration

Change-Id: I22fc46dff6cc5dfd975f6e82161d265781778cde
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoUpdate eclipse IP log for 0.12 82/3082/2
Matthias Sohn [Tue, 12 Apr 2011 21:21:57 +0000 (23:21 +0200)]
Update eclipse IP log for 0.12

Change-Id: I8f2ce63e039d5baabc1533477128470696a36ced
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoHande latin-1 encoding 44/3044/7
Leonard Broman [Fri, 8 Apr 2011 19:09:04 +0000 (21:09 +0200)]
Hande latin-1 encoding

Bug: 342259
Change-Id: Ie285b8819b5ea6f9892ebafc4ebbd9c6d091d1fe
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd NotesCommand to the JGit API 70/2970/6
Chris Aniszczyk [Tue, 29 Mar 2011 21:56:58 +0000 (16:56 -0500)]
Add NotesCommand to the JGit API

Bug: 334765
Change-Id: Ie0fb79671e7a741eb85651f507b8ade930bfcc20
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Create all test data in trash folder"
Chris Aniszczyk [Sat, 9 Apr 2011 23:12:23 +0000 (19:12 -0400)]
Merge "Create all test data in trash folder"

13 years agoCreate all test data in trash folder 34/3034/2
Matthias Sohn [Sat, 9 Apr 2011 23:02:29 +0000 (01:02 +0200)]
Create all test data in trash folder

This ensures that all test data is separated from project sources and
cleaned up after the test. Previously the cloned bare test repository
was created in org.eclipse.jgit.test/ and not deleted after the test
run.

Change-Id: I55110442e365fc8fe610f1c372f72a71ee6e1412
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoUpdate to use Tycho 0.11 32/3032/1
Matthias Sohn [Sat, 9 Apr 2011 21:23:47 +0000 (23:23 +0200)]
Update to use Tycho 0.11

Change-Id: I1f9053fe2af39898851b41e1e86c9320ab5594ca
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoAdd "Conflicts" section to merge message on conflict 14/3014/1
Robin Stocker [Wed, 6 Apr 2011 20:55:10 +0000 (22:55 +0200)]
Add "Conflicts" section to merge message on conflict

The same as with cherry-pick, the commit message of a merge should
include a "Conflicts" section when the merge resulted in conflicts.

Change-Id: I6261dc898262322924af5ca1bef841a654b0df55
Signed-off-by: Robin Stocker <robin@nibor.org>
13 years agoRefactor reading and writing heads in Repository 13/3013/2
Robin Stocker [Wed, 6 Apr 2011 19:10:16 +0000 (21:10 +0200)]
Refactor reading and writing heads in Repository

Add private methods which are used for reading and writing MERGE_HEAD
and CHERRY_PICK_HEAD files, as suggested in the comments on change
I947967fdc2f1d55016c95106b104c2afcc9797a1.

Change-Id: If4617a05ee57054b8b1fcba36a06a641340ecc0e
Signed-off-by: Robin Stocker <robin@nibor.org>
13 years agoAdd CHERRY_PICK_HEAD for cherry-pick conflicts 96/2996/3
Robin Stocker [Sun, 3 Apr 2011 17:37:55 +0000 (19:37 +0200)]
Add CHERRY_PICK_HEAD for cherry-pick conflicts

Add handling of CHERRY_PICK_HEAD file in .git (similar to MERGE_HEAD),
which is written in case of a conflicting cherry-pick merge.

It is used so that Repository.getRepositoryState can return the new
states CHERRY_PICKING and CHERRY_PICKING_RESOLVED. These states, as well
as CHERRY_PICK_HEAD can be used in EGit to properly show the merge tool.

Also, in case of a conflict, MERGE_MSG is written with the original
commit message and a "Conflicts" section appended. This way, the
cherry-picked message is not lost and can later be re-used in the commit
dialog.

Bug: 339092
Change-Id: I947967fdc2f1d55016c95106b104c2afcc9797a1
Signed-off-by: Robin Stocker <robin@nibor.org>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoAdd parameters for timeout and branches to clone 09/3009/2
Stefan Lay [Wed, 6 Apr 2011 12:08:25 +0000 (14:08 +0200)]
Add parameters for timeout and branches to clone

The timeout is also used in the FetchCommand called by the
CloneCommand.

The possibility to provide a list of branches to fetch initially is a
feature offered by EGit. To implement it here is a prerequisite for
EGit to be able to use the CloneCommand.

Change-Id: I21453de22e9ca61919a7c3386fcc526024742f5f
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
13 years agoTry to checkout branch after cloning 08/3008/2
Stefan Lay [Wed, 6 Apr 2011 12:58:48 +0000 (14:58 +0200)]
Try to checkout branch after cloning

When no branch was specified in the clone command, HEAD pointed to a
commit after clone. Now the clone command tries to find a branch which
points to the same commit and checks out this branch.

Bug: 339354
Change-Id: Ie3844465329f213dee4a8868dbf434ac3ce23a08
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
13 years agoFix DirCache.isModified() 02/3002/1
Philipp Thun [Mon, 4 Apr 2011 16:04:21 +0000 (18:04 +0200)]
Fix DirCache.isModified()

Change I61a1b45db2d60fdcc0f87373ac6fd75ac4c4a202 fixed a possible NPE
occurring for newly created repositories - but in that case a wrong
value (false = not modified) was returned.

If a current version of the index file exists (liveFile), but there is
no snapshot, this means that there have been modifications (i.e. true
has to be returned).

Change-Id: I698f78112249f9924860fc58eb7eab7afdf87eb7
Signed-off-by: Philipp Thun <philipp.thun@sap.com>
13 years ago[findbugs] Use explicit initialization 98/2998/2
Matthias Sohn [Mon, 4 Apr 2011 00:19:16 +0000 (02:19 +0200)]
[findbugs] Use explicit initialization

Findbugs doesn't like using implicitly initialized field in
initializer.

Change-Id: Ic1ff9011813cc02950a71df587f31ed9f8415b49
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years ago[findbugs] Make mutable static field final 95/2995/1
Matthias Sohn [Sat, 2 Apr 2011 22:32:37 +0000 (00:32 +0200)]
[findbugs] Make mutable static field final

Change-Id: I310bc2093571bf22a58106f09706cc3eb43a2453
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 years agoMerge "Make DeltaBaseCache per-ObjectReader"
Chris Aniszczyk [Sat, 2 Apr 2011 17:35:54 +0000 (13:35 -0400)]
Merge "Make DeltaBaseCache per-ObjectReader"

13 years agoMerge "Fix ReceivePack connectivity validation with alternates"
Chris Aniszczyk [Sat, 2 Apr 2011 13:44:26 +0000 (09:44 -0400)]
Merge "Fix ReceivePack connectivity validation with alternates"

13 years agoMerge "Add open(File) and wrap(Repository) to Git"
Christian Halstrick [Sat, 2 Apr 2011 07:38:07 +0000 (03:38 -0400)]
Merge "Add open(File) and wrap(Repository) to Git"

13 years agoAdd open(File) and wrap(Repository) to Git 69/2969/3
Christian Halstrick [Wed, 30 Mar 2011 00:47:19 +0000 (02:47 +0200)]
Add open(File) and wrap(Repository) to Git

When a new Git instance for an exisiting git repository should be
created there are two use-cases: either the application has already a
Repository instance in hand or the application knows where the
repository resides in the filesystem. Two methods are added to
explicitly support these use-cases: wrap(Repository db) and open(File
gitDir)

Change-Id: I2970e4aa8d4602cb1298f01e5b76bf0f96c492e5
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
13 years agoSupport reading first SHA-1 from large FETCH_HEAD files 39/2739/3
Carsten Pfeiffer [Wed, 16 Mar 2011 15:57:35 +0000 (16:57 +0100)]
Support reading first SHA-1 from large FETCH_HEAD files

When reading refs, avoid reading huge files that were put there
accidentally, but still read the top of e.g. FETCH_HEAD, which
may be longer than our limit. We're only interested in the first line
anyway.

Bug: 340880
Change-Id: I11029b9b443f22019bf80bd3dd942b48b531bc11
Signed-off-by: Carsten Pfieffer <carsten.pfeiffer@gebit.de>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 years agoMerge "Let LockFile.unlock use FileUtils.delete()"
Shawn Pearce [Sat, 2 Apr 2011 00:46:33 +0000 (20:46 -0400)]
Merge "Let LockFile.unlock use FileUtils.delete()"

13 years agoMake DeltaBaseCache per-ObjectReader 94/2994/1
Shawn O. Pearce [Sat, 2 Apr 2011 00:42:06 +0000 (20:42 -0400)]
Make DeltaBaseCache per-ObjectReader

The 'Counting objects' phase of PackWriter requires good hit rates
from the DeltaBaseCache while walking trees, the deltas need to find
their bases in the cache in order to inflate in a reasonable time.

If JGit is running in a multi-threaded server, such as Gerrit Code
Review, each thread needs its own DeltaBaseCache to prevent one thread
from evicting the other thread's relevant bases.  Move the cache to be
per-ObjectReader, lazily allocated when required by a PackFile.

Change-Id: If9d5ed06728e813632ae96dcfb811f4860b276e8
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoFix ReceivePack connectivity validation with alternates 93/2993/1
Shawn O. Pearce [Sat, 2 Apr 2011 00:21:38 +0000 (20:21 -0400)]
Fix ReceivePack connectivity validation with alternates

If a repository has an alternate object database, the alternate has
its references advertised as ".have" lines, which permits the client
to use these as delta base candidates when generating the pack.  If
setCheckReferencedObjectsAreReachable(true) is used, these additional
have lines need to be considered in addition to the advertised refs.

Change-Id: Ie39c6696f9d3ff147ef4405cd5624f6011700ce5
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agoLet LockFile.unlock use FileUtils.delete() 82/2982/2
Christian Halstrick [Wed, 30 Mar 2011 15:29:10 +0000 (17:29 +0200)]
Let LockFile.unlock use FileUtils.delete()

We sometimes face the problem that the file .git/index.lock
can't deleted causing JGit operations to fail. Problem is
that LockFile.unlock() simply deletes the lockfile and ignores the
return value of File.delete(). Instead use
FileUtils.delete() with retry option. This method will retry the
deletion of the file at most 10 times with sleeps inbetween.

Bug: 335959
Change-Id: I9598edea9f2304fe12e6f470301211b503434848
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
13 years agoEnhance RefDatabase with a refresh() method 80/2880/2
Christian Halstrick [Tue, 22 Mar 2011 10:19:18 +0000 (11:19 +0100)]
Enhance RefDatabase with a refresh() method

There should be a way to explictly refresh the refs cached in the
RefDirectory. Since commit c261b28 (use of FileSnapshot) this is
not needed anymore for storage in the filesystem. But for DHT based
storage an explicit refresh may be needed.

Change-Id: I7d30c3496c05e1fb6e9519f3af9f23c6adb93bf9
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
13 years agoRefDirectory: Use FileSnapshot for packed-refs 18/2118/4
Shawn O. Pearce [Mon, 13 Dec 2010 21:41:19 +0000 (13:41 -0800)]
RefDirectory: Use FileSnapshot for packed-refs

Instead of tracking the length and modification time by hand, rely
on FileSnapshot to tell RefDirectory when the $GIT_DIR/packed-refs
file has been changed or should be re-read from disk.

Change-Id: I067d268dfdca1d39c72dfa536b34e6a239117cc3
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
13 years agosmart HTTP: Return errors inside payload 48/2748/7
Shawn O. Pearce [Thu, 17 Mar 2011 02:19:15 +0000 (19:19 -0700)]
smart HTTP: Return errors inside payload

When the client is clearly making a smart HTTP request to our smart
HTTP server, return any errors like RepositoryNotFoundException or
ServiceNotEnabledException inside of the payload as a Git level ERR
message, rather than an HTTP error code.

This prevents the C Git command line client from retrying a failed
"$URL/info/refs?service=git-upload-pack" request without the smart
service URL, only to fail again with "403 Forbidden" when the dumb
as-is service has been disabled by the server configuration, or is
unavailable because the repository is not on the local filesystem.

Change-Id: I57e8756d5026e885e0ca615979bfcd729703be6c
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>