]> source.dussan.org Git - jgit.git/log
jgit.git
2 years agoUse replace instead of replaceAll in toCleanString 59/196659/2
Eryk Szymanski [Tue, 8 Nov 2022 17:22:50 +0000 (18:22 +0100)]
Use replace instead of replaceAll in toCleanString

This is from SonarLint (rule.java:S4348)
Regex patterns should not be created needlessly:

When String::replaceAll is used, the first argument should be a real
regular expression. If it’s not the case, String::replace does exactly
the same thing as String::replaceAll without the performance drawback of
the regex.

Change-Id: I00ba967ff4a27eeeb6fccf9373f6df2c94ecd823

2 years agoFix the path for JSchText.properties 58/196558/2
Sebastian Schuberth [Wed, 26 Oct 2022 20:28:46 +0000 (22:28 +0200)]
Fix the path for JSchText.properties

The paths needs to include "ssh" to match the class's package name. This
resolves

Caused by: TransportException: ssh://git@git.xx.com/xx/xx.git: remote hung up unexpectedly
    Caused by: TranslationBundleLoadingException: Loading of translation bundle failed for [org.eclipse.jgit.internal.transport.ssh.jsch.JSchText, en_US]
        Caused by: MissingResourceException: Can't find bundle for base name org.eclipse.jgit.internal.transport.ssh.jsch.JSchText, locale en_US

Also see [1] for reference.

[1]: https://github.com/oss-review-toolkit/ort/issues/5894#issuecomment-1292100687

Change-Id: Ie27b9fc1cdd1d83f8123821be42e65da59ecf49d
Signed-off-by: Sebastian Schuberth <opensource@schuberth.dev>
2 years agoMerge "UploadPack: Receive and parse client session-id"
Ivan Frade [Fri, 4 Nov 2022 21:56:15 +0000 (17:56 -0400)]
Merge "UploadPack: Receive and parse client session-id"

2 years agoMerge "TransferConfig: Move reading advertisesid setting into TransferConfig"
Ivan Frade [Thu, 3 Nov 2022 20:24:26 +0000 (16:24 -0400)]
Merge "TransferConfig: Move reading advertisesid setting into TransferConfig"

2 years agoMerge "FirstWant: Parse client session-id if received."
Ivan Frade [Thu, 3 Nov 2022 20:23:34 +0000 (16:23 -0400)]
Merge "FirstWant: Parse client session-id if received."

2 years agoFix Maven SHA1 for Bazel build 95/196595/4
Patrick Hiesel [Thu, 3 Nov 2022 11:59:37 +0000 (12:59 +0100)]
Fix Maven SHA1 for Bazel build

The httpcore SHA was wrong resulting in a build breakage.

With this change, `bazelisk build all` succeeds.

Change-Id: I111ab450db2db2328e7d4fe849e29f55e4897543

2 years agoUploadPack: Receive and parse client session-id 97/196497/12
Josh Brown [Tue, 1 Nov 2022 20:51:48 +0000 (20:51 +0000)]
UploadPack: Receive and parse client session-id

Before this change JGit did not support the session-id capability
implemented by native Git in UploadPack. This change implements
advertising the capability from the server and parsing the session-id
received from the client during an UploadPack operation.

Enable the transfer.advertisesid config setting to advertise the
capability from the server. The client may send a session-id capability
in response. If received, the value from this is parsed and available
via the getClientSID method on the UploadPack object.

This change does not add the capability to send a session-id from the
JGit client.

https://git-scm.com/docs/gitprotocol-capabilities#_session_idsession_id

Change-Id: Ib1b6929ff1b3a4528e767925b5e5c44b5d18182f
Signed-off-by: Josh Brown <sjoshbrown@google.com>
2 years agoTransferConfig: Move reading advertisesid setting into TransferConfig 66/196566/6
Josh Brown [Tue, 1 Nov 2022 19:00:07 +0000 (19:00 +0000)]
TransferConfig: Move reading advertisesid setting into TransferConfig

The config setting to enable advertising the session-id capability is
currently read in the ReceivePack class. This change moves it to a
common location in the TransferConfig class so that it can be reused
in other places like UploadPack. TransferConfig is also a more logical
place for the setting as it resides in the `transfer` config section.

Set the transfer.advertisesid setting to true to send the session-id
capability to the client.

Change-Id: If68ecb5e68b59f5c452a7992d02e3688b0a86747
Signed-off-by: Josh Brown <sjoshbrown@google.com>
2 years agoFirstWant: Parse client session-id if received. 65/196565/7
Josh Brown [Tue, 1 Nov 2022 18:16:44 +0000 (18:16 +0000)]
FirstWant: Parse client session-id if received.

In protocol V0 the client capabilities are appended to the first line.
Parsing session-id is currently only supported during a ReceivePack
operation. This change will parse the client session-id capability if
it has been sent by the client.

If the server sends the session-id capability to the client. The client
may respond with a session ID of its own. FirstWant.fromLine will now
parse the ID and make it available via the getClientSID method.

This change does not add support to send the session-id capability from
the server. The change is necessary to support session-id in UploadPack.

Change-Id: Id3fe44fdf9a72984ee3de9cf40cc4e71d434df4a
Signed-off-by: Josh Brown <sjoshbrown@google.com>
2 years agoMerge branch 'stable-6.4' 46/196546/1
Matthias Sohn [Thu, 27 Oct 2022 21:42:01 +0000 (23:42 +0200)]
Merge branch 'stable-6.4'

* stable-6.4:
  Prepare 6.4.0-SNAPSHOT builds
  JGit v6.4.0.202210260700-m2

Change-Id: I3839c8b57912f7678e1a9f9f06349bee321ff175

2 years agoReceivePack: Receive and parse client session-id. 23/196323/14
Josh Brown [Tue, 11 Oct 2022 21:56:09 +0000 (14:56 -0700)]
ReceivePack: Receive and parse client session-id.

Before this change JGit did not support the session-id capability
implemented by native Git. This change implements advertising the
capability from the server and parsing the session-id received from
the client during a ReceivePack operation.

Enable the transfer.advertisesid config setting to advertise the
capability from the server. The client may send a session-id capability
in response. If received, the value from this is parsed and available
via the getClientSID method on the ReceivePack object. All capabilities
in the form `capability=value` are now split into key value pairs at the
first `=` character. This change replaces specific handling for the
agent capability.

This change does not add advertisement or parsing to UploadPack. This
change also does not add the ability to send a session ID from the JGit
client.

https://git-scm.com/docs/protocol-v2/2.33.0#_session_idsession_id

Change-Id: I56fb115e843b11b27e128c4ac427b05d5ec129d0
Signed-off-by: Josh Brown <sjoshbrown@google.com>
2 years agoPrepare 6.4.0-SNAPSHOT builds 17/196517/1
Matthias Sohn [Wed, 26 Oct 2022 15:42:04 +0000 (17:42 +0200)]
Prepare 6.4.0-SNAPSHOT builds

Change-Id: If4da93f775bcbe923e400ebb9315a34485646b40

2 years agoJGit v6.4.0.202210260700-m2 09/196509/1 v6.4.0.202210260700-m2
Matthias Sohn [Wed, 26 Oct 2022 11:01:14 +0000 (13:01 +0200)]
JGit v6.4.0.202210260700-m2

Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Change-Id: Iedb1530c5d30a22be7c9eed80c043daac64b0517

2 years agoPushCommand: allow users to disable use of bitmaps for push 05/194705/3
kylezhao [Thu, 14 Jul 2022 03:23:03 +0000 (11:23 +0800)]
PushCommand: allow users to disable use of bitmaps for push

Reachability bitmaps are designed to speed up the "counting objects"
phase of generating a pack during a clone or fetch. They are not
optimized for Git clients sending a small topic branch via "git push".
In some cases (see [1]), using reachability bitmaps during "git push"
can cause significant performance regressions.

Add PushCommand#setUseBitmaps(boolean) to allow users to tell "git push"
not to use bitmaps.

[1]: https://lore.kernel.org/git/87zhoz8b9o.fsf@evledraar.gmail.com/

Change-Id: I7fb7d26084ec63ddfa7249cf58abb85929b30e56
Signed-off-by: kylezhao <kylezhao@tencent.com>
2 years agoI/O redirection for the pre-push hook 52/196452/2
Thomas Wolf [Thu, 20 Oct 2022 21:25:38 +0000 (23:25 +0200)]
I/O redirection for the pre-push hook

Fix and complete the implementation of calling the pre-push hook.
Add the missing error stream redirect, and add the missing setters
in Transport and in PushCommand. In Transport, delay setting up a
PrePushHook such that it happens only on a push. Previously, the
hook was set up also for fetches.

Bug: 549246
Change-Id: I64a576dfc6b139426f05d9ea6654027ab805734e
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoPackParser: populate full size of the PackedObjectInfos 82/191082/7
Ivan Frade [Thu, 16 Dec 2021 21:08:33 +0000 (13:08 -0800)]
PackParser: populate full size of the PackedObjectInfos

We need the full size of the objects to populate the object-size index
of a pack. This size is not always the one encoded in the object header
in the pack (e.g. for deltas).

Populate the full size of PackedObjectInfos in the PackParser, which is
invoked when receiving a pack e.g. in a push.

Change-Id: I102c20901aefb5e85047e2e526c0d733f82ff74b

2 years agoPackedObjectInfo: add the full size to the description 81/191081/7
Ivan Frade [Wed, 15 Dec 2021 00:24:26 +0000 (16:24 -0800)]
PackedObjectInfo: add the full size to the description

So we can create a size index later.

Change-Id: I9db47ced929fbf045fc37bead6449bbf5484d308

2 years agoObjectReader: New #isNotLargerThan method 80/191080/6
Ivan Frade [Sat, 4 Dec 2021 00:11:10 +0000 (16:11 -0800)]
ObjectReader: New #isNotLargerThan method

Partial clones filter the objects to send by size calling
ObjectReader#getObjectSize per object. This method reads the object from
storage to get the size, which can be expensive.

Offer a #isNotLargerThan method. The default implementation reads the
object, but subclasses can override it with more efficient lookups (e.g.
adding an index).

isNotLargerThan gives implementors more options to optimize than
getObjectIndex (e.g. can be implemented storing only object over certain
size).

Change-Id: Iefd4b1370cb9144f15cc0391286aeeb365e6ea87

2 years agoFail build if there are license issues with dependencies 33/196333/4
Matthias Sohn [Wed, 12 Oct 2022 21:33:14 +0000 (23:33 +0200)]
Fail build if there are license issues with dependencies

Configure the dash license-tool-plugin to fail the build if there are
license issues with build dependencies. This plugin will generate a list
of all build dependencies and their license to target/dash/summary.

Delete the checked-in dependency list DEPENDENCIES since the build now
always generates it to target/dash/summary.

See https://github.com/eclipse/dash-licenses#example-maven-plugin

Change-Id: I0c2bf8eb166d85b840d42afc61750b4a083b7659

2 years agoUpdate org.apache.httpcomponents:httpcore to 4.4.15 94/196294/1
Matthias Sohn [Mon, 10 Oct 2022 15:54:18 +0000 (17:54 +0200)]
Update org.apache.httpcomponents:httpcore to 4.4.15

In target platform we updated to this version already earlier.

Change-Id: Iefa06bac2c007810936a5675482addd99f8f9cd3

2 years agoUpdate Orbit to S20220927175816 81/196281/1
Matthias Sohn [Sun, 9 Oct 2022 23:20:07 +0000 (01:20 +0200)]
Update Orbit to S20220927175816

and
- com.google.code.gson:gson to 2.9.1

Change-Id: Ia9e4fdc557478d3ca37b0169be93711791952068

2 years agoUpdate JMH to 1.35 80/196280/1
Matthias Sohn [Sun, 9 Oct 2022 22:50:25 +0000 (00:50 +0200)]
Update JMH to 1.35

Update
- org.openjdk.jmh:jmh-core to 1.35
- org.openjdk.jmh:jmh-generator-annprocess to 1.35

Change-Id: Iaebae71a9b49b2116da9d2614e6ae1ddbd692aab

2 years agoUpdate org.eclipse.jdt:ecj to 3.31.0 79/196279/1
Matthias Sohn [Sun, 9 Oct 2022 22:47:15 +0000 (00:47 +0200)]
Update org.eclipse.jdt:ecj to 3.31.0

Change-Id: I410f762de37e5273916d4850157744f0a9be1564

2 years agoUpdate plexus compiler to 2.12.1 78/196278/1
Matthias Sohn [Sun, 9 Oct 2022 22:45:13 +0000 (00:45 +0200)]
Update plexus compiler to 2.12.1

Change-Id: Id55b46b7546c830a90cbdf794bb237abf2afbbe4

2 years agoUpdate org.apache.maven.wagon:wagon-ssh to 3.5.2 77/196277/1
Matthias Sohn [Sun, 9 Oct 2022 22:43:35 +0000 (00:43 +0200)]
Update org.apache.maven.wagon:wagon-ssh to 3.5.2

Change-Id: If80cb8e81a5ff8888812626d0658106dec5303ab

2 years agopgm/BUILD: Add dependencty to java EWAH 22/196122/3
Ivan Frade [Thu, 29 Sep 2022 18:24:29 +0000 (11:24 -0700)]
pgm/BUILD: Add dependencty to java EWAH

A fetch to a locally run daemon triggers a runtime exception:

Listening on localhost/127.0.0.1:9418
java.lang.NoClassDefFoundError:
com/googlecode/javaewah/EWAHCompressedBitmap

Add javaEWAH in the deps of the PGM library.

To reproduce:

0. Assume a git repo in <dir-with-repos>/a-repo
1. Run daemon e.g.:
  $ bazel run //org.eclipse.jgit.pgm:jgit -- daemon --export-all=true
  --listen localhost --enable upload-pack <dir-with-repos>

2. Fetch:
  $ git clone git://0.0.0.0:9418/a-repo

Change-Id: I503f9fe45347a5891c3f3de0452b7f300b1e8206

2 years ago[sshd] Guard against numerical overflow 48/196148/1
Thomas Wolf [Sat, 1 Oct 2022 18:44:59 +0000 (20:44 +0200)]
[sshd] Guard against numerical overflow

Check the key length before adding; the addition might overflow.

Change-Id: Icde7c92a5bb267fdd869d5a1c0842967ab1a7fd9
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoMerge branch 'stable-6.3' 93/196093/1
Matthias Sohn [Wed, 28 Sep 2022 16:16:47 +0000 (18:16 +0200)]
Merge branch 'stable-6.3'

* stable-6.3:
  Remove unused imports

Change-Id: I4a92c5afb8f179798234eb772eb34879d41808af

2 years agoRemove unused imports 91/196091/1
Matthias Sohn [Wed, 28 Sep 2022 15:58:50 +0000 (17:58 +0200)]
Remove unused imports

Change-Id: Ib6f80a5f013d30a9b7a59cb05e3ee13aa46b28c8

2 years agoRemove unused API filters 92/196092/1
Matthias Sohn [Thu, 22 Sep 2022 14:34:36 +0000 (16:34 +0200)]
Remove unused API filters

Change-Id: Ief32f935c701842f03b173ee48465d7dcf7dfabd

2 years agoObjectDirectory: avoid using File.getCanonicalPath() 86/195186/8
Jörg Kubitz [Mon, 15 Aug 2022 09:05:04 +0000 (11:05 +0200)]
ObjectDirectory: avoid using File.getCanonicalPath()

On java 17 + Windows OS java.io.File.getCanonicalPath is a very slow
system call which uses most time during clone.

That is since JDK 12 the result of File.getCanonicalPath is not cached
anymore by default:
https://bugs.openjdk.java.net/browse/JDK-8207005

* Use toRealPath() to follow symbolic links also on windows.
* Cache the result.

Bug: 580568
Change-Id: I95f4f5b2babefd7210ee4740646230225ebf3788

2 years agoAutoCRLFOutputStream: use BufferedOutputStream 77/195477/3
Jörg Kubitz [Wed, 31 Aug 2022 15:02:54 +0000 (17:02 +0200)]
AutoCRLFOutputStream: use BufferedOutputStream

This should improve performance of autocrlf checkout.

Bug: 580651
Change-Id: I2e2fe0273ac3c71fad50a575278234804ee28306

2 years agoCloneCommand: set HEAD also when not checking out 82/195882/1
Thomas Wolf [Sun, 18 Sep 2022 17:24:58 +0000 (19:24 +0200)]
CloneCommand: set HEAD also when not checking out

CloneCommand, when setNoCheckout(true) was set, did not set HEAD.
With C git, "git clone --no-checkout" does.

Change-Id: Ief3df7e904ce90829a6345a6c3e9ee6a68486ab0
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoPass on shallowSince only if not null 81/195881/1
Thomas Wolf [Sun, 18 Sep 2022 17:29:22 +0000 (19:29 +0200)]
Pass on shallowSince only if not null

FetchCommand.setShallowSince() and Transport.setDeepenSince() require
a non-null argument.

Change-Id: I1c3a20be518374e380a4e90787ed834438da40ee
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoFix wrong @since tag 80/195880/1
Thomas Wolf [Sun, 18 Sep 2022 15:02:51 +0000 (17:02 +0200)]
Fix wrong @since tag

PatchApplier was merged only in JGit 6.4.

Change-Id: Ica84d8184c1d3a1acce8beba9b076f6c32e749d7
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoMerge "Split out ApplyCommand logic to PatchApplier class"
Han-Wen NIenhuys [Thu, 15 Sep 2022 08:16:48 +0000 (04:16 -0400)]
Merge "Split out ApplyCommand logic to PatchApplier class"

2 years agoSplit out ApplyCommand logic to PatchApplier class 26/194426/62
Nitzan Gur-Furman [Wed, 31 Aug 2022 17:26:13 +0000 (19:26 +0200)]
Split out ApplyCommand logic to PatchApplier class

PatchApplier now routes updates through the index. This has two
results:

* we can now execute patches in-memory.

* the JGit apply command will now always update the
index to match the working tree.

Change-Id: Id60a88232f05d0367787d038d2518c670cdb543f
Co-authored-by: Han-Wen Nienhuys <hanwen@google.com>
Co-authored-by: Nitzan Gur-Furman <nitzan@google.com>
2 years agoPrepare 6.4.0-SNAPSHOT builds 92/195792/2
Matthias Sohn [Mon, 12 Sep 2022 08:55:36 +0000 (10:55 +0200)]
Prepare 6.4.0-SNAPSHOT builds

Change-Id: I47ca5f1d0263caa0bfc7c303042360c6c5ac4dec

2 years agoFix typo in FetchV2Request javadoc 76/195776/2
kylezhao [Wed, 14 Sep 2022 07:46:39 +0000 (15:46 +0800)]
Fix typo in FetchV2Request javadoc

Change-Id: I905dda15e1b7f5e431816d3fbb01a1672e5fc786
Signed-off-by: kylezhao <kylezhao@tencent.com>
2 years agoMerge branch 'stable-6.3' 24/195724/1
Matthias Sohn [Mon, 12 Sep 2022 08:51:37 +0000 (10:51 +0200)]
Merge branch 'stable-6.3'

* stable-6.3:
  Prepare 6.3.1-SNAPSHOT builds
  JGit v6.3.0.202209071007-r
  JGit v6.3.0.2022009070944-r
  [merge] Fix merge conflicts with symlinks
  Update DEPENDENCIES for 6.3.0
  Update tycho to 2.7.5
  Revert "Adds FilteredRevCommit that can overwrites its parents in the DAG."
  Revert "Option to pass start RevCommit to be blamed on to the BlameGenerator."
  Prepare 6.3.0-SNAPSHOT builds
  JGit v6.3.0.202208161710-m3

Change-Id: Ia9430fb516dca795e25064a190704b70689af364

2 years agoPrepare 6.3.1-SNAPSHOT builds 22/195722/1
Matthias Sohn [Mon, 12 Sep 2022 08:09:10 +0000 (10:09 +0200)]
Prepare 6.3.1-SNAPSHOT builds

Change-Id: I44e159eca4131880d74d3078060e7e20f9b5ce76

2 years agoMerge "DfsBundleWriter: Add test case about GC_REST pack."
Ivan Frade [Wed, 7 Sep 2022 20:43:19 +0000 (16:43 -0400)]
Merge "DfsBundleWriter: Add test case about GC_REST pack."

2 years agoDfsBundleWriter: Add test case about GC_REST pack. 10/195610/2
yunjieli [Wed, 7 Sep 2022 00:14:51 +0000 (17:14 -0700)]
DfsBundleWriter: Add test case about GC_REST pack.

Add a test case to make sure that the bundle writer writes objects in
GC_REST packs as well.

Signed-off-by: Yunjie Li <yunjieli@google.com>
Change-Id: Iba4d88c573aa1cda4505afbe2b83581a09a343df

2 years agoJGit v6.3.0.202209071007-r 36/195636/1 v6.3.0.202209071007-r
Matthias Sohn [Wed, 7 Sep 2022 14:07:11 +0000 (16:07 +0200)]
JGit v6.3.0.202209071007-r

Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Change-Id: Iea3fae9f6f6c5fb0a79f7684334a3e0059738c4f

2 years agoJGit v6.3.0.2022009070944-r 32/195632/1
Matthias Sohn [Wed, 7 Sep 2022 13:39:48 +0000 (15:39 +0200)]
JGit v6.3.0.2022009070944-r

Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Change-Id: I3cc78dbcf8c7970e80bf1499751611110ec2b30b

2 years ago[merge] Fix merge conflicts with symlinks 19/195219/3
Thomas Wolf [Mon, 15 Aug 2022 23:02:21 +0000 (01:02 +0200)]
[merge] Fix merge conflicts with symlinks

Previous code would do a content merge on symlinks, and write the merge
result to the working tree as a file. C git doesn't do this; it leaves
a symlink in the working tree unchanged, or in a delete-modify conflict
it would check out "theirs".

Moreover, previous code would write the merge result to the link target,
not to the link. This would overwrite an existing link target, or fail
if the link pointed to a directory.

In link/file conflicts or file/link conflicts, C git always puts the
file into the working tree.

Change conflict handling accordingly. Add tests for all the conflict
cases.

Bug: 580347
Change-Id: I3cffcb4bcf8e336a85186031fff23f0c4b6ee19d
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoUpdate DEPENDENCIES for 6.3.0 01/195601/1
Matthias Sohn [Tue, 6 Sep 2022 15:13:52 +0000 (17:13 +0200)]
Update DEPENDENCIES for 6.3.0

Change-Id: Ie057e4c94a102113fc9026d9773657984530c9c6

2 years agoUpdate tycho to 2.7.5 99/195599/1
Matthias Sohn [Tue, 6 Sep 2022 14:14:48 +0000 (16:14 +0200)]
Update tycho to 2.7.5

Change-Id: I5ef981cf9f01cc8493dc6178938819f5e086f26a

2 years agoMerge branch 'master' into stable-6.3 98/195598/1
Matthias Sohn [Tue, 6 Sep 2022 13:58:47 +0000 (15:58 +0200)]
Merge branch 'master' into stable-6.3

* master:
  Move WorkTreeUpdater to merge package
  WorkTreeUpdater: use DirCacheCheckout#StreamSupplier
  DirCacheCheckout#getContent: also take InputStream supplier
  WorkTreeUpdater: remove safeWrite option

Change-Id: I8be570dbc4ad0d0b46046b85cbda24c3adcba170

2 years agoMerge changes I888f313f,I98de155c,I2efa9a6d,Ifa79dac2
Matthias Sohn [Tue, 6 Sep 2022 13:42:14 +0000 (09:42 -0400)]
Merge changes I888f313f,I98de155c,I2efa9a6d,Ifa79dac2

* changes:
  Move WorkTreeUpdater to merge package
  WorkTreeUpdater: use DirCacheCheckout#StreamSupplier
  DirCacheCheckout#getContent: also take InputStream supplier
  WorkTreeUpdater: remove safeWrite option

2 years agoMove WorkTreeUpdater to merge package 48/195448/7
Han-Wen Nienhuys [Tue, 30 Aug 2022 13:08:48 +0000 (15:08 +0200)]
Move WorkTreeUpdater to merge package

This avoids making it public with the associated costs for backward
compatibility guarantees.

Change-Id: I888f313f3854deace8d4cd92f354a6ef0d3b5460

2 years agoWorkTreeUpdater: use DirCacheCheckout#StreamSupplier 47/195447/9
Han-Wen Nienhuys [Tue, 30 Aug 2022 12:18:25 +0000 (14:18 +0200)]
WorkTreeUpdater: use DirCacheCheckout#StreamSupplier

This avoids having to introduce the StreamLoader bridging class.

Change-Id: I98de155c458745236df24d6323eabed5061e7f8c

2 years agoDirCacheCheckout#getContent: also take InputStream supplier 46/195446/7
Han-Wen Nienhuys [Tue, 30 Aug 2022 08:07:21 +0000 (10:07 +0200)]
DirCacheCheckout#getContent: also take InputStream supplier

This lets us use DirCacheCheckout for routines that want to write
files in the worktree that aren't available as a git object.

DirCacheCheckout#getContent takes a InputStream supplier rather than
InputStream: if filtering fails with IOException, the data is placed
unfiltered in the checkout. This means that the stream has to be read
again, from the start.

Use it in this way in ApplyCommand. This use is incorrect, though: the
same InputStream is returned twice, so if the read to be retried, the
stream will return 0 bytes. It doesn't really matter, because in
either case, the SHA1 will not match up, and the patch fails.

Change-Id: I2efa9a6da06806ff79b155032fe4b34be8fec09e

2 years agoRevert "Adds FilteredRevCommit that can overwrites its parents in the 82/195582/2
Matthias Sohn [Mon, 5 Sep 2022 22:06:04 +0000 (00:06 +0200)]
Revert "Adds FilteredRevCommit that can overwrites its parents in the
DAG."

This reverts commit 6297491e8adb85e43d60ffe75fb71f335e733449.

This is done as a quick fix for the failure of egit tests caused by  the
introduction of FilteredRevCommit.

Bug: 580690
Change-Id: Ia6b651dd11b0a4b02d5e52247eb4bf13adf94e27

2 years agoRevert "Option to pass start RevCommit to be blamed on to the 83/195583/2
Matthias Sohn [Mon, 5 Sep 2022 22:07:17 +0000 (00:07 +0200)]
Revert "Option to pass start RevCommit to be blamed on to the
BlameGenerator."

This reverts commit 5747bba48b22a11beba8ebe0caf13a53d4ca96f2.

This is done as a quick fix for the failure of egit tests caused by  the
introduction of FilteredRevCommit.

Bug: 580690
Change-Id: Ia0178bc2de4fc825a81207bbd7979bf3a386c955

2 years agoWorkTreeUpdater: remove safeWrite option 45/195445/3
Han-Wen Nienhuys [Thu, 25 Aug 2022 17:37:35 +0000 (19:37 +0200)]
WorkTreeUpdater: remove safeWrite option

This was added in Ideaefd5178 to anticipate on writing files for
ApplyCommand, but we are keeping WorkTreeUpdater private to the merge
package for now.

Change-Id: Ifa79dac245e60eb7a77eaea4cc1249222e347d38

2 years agoMerge branch 'master' into stable-6.3 78/195578/1
Matthias Sohn [Mon, 5 Sep 2022 19:19:07 +0000 (21:19 +0200)]
Merge branch 'master' into stable-6.3

* master:
  Update Orbit to R20220830213456 for 2022-09
  BaseSuperprojectWriter: report invalid paths as manifest errors
  ApplyCommand: fix ApplyResult#updatedFiles
  WorkTreeUpdater: rename metadata maps
  WorkTreeUpdater#Result: hide data members
  Add javadoc on RevCommit
  Option to pass start RevCommit to be blamed on to the BlameGenerator.
  WorkTreeUpdater: re-format and clean-up
  Adds FilteredRevCommit that can overwrites its parents in the DAG.

Change-Id: Ie92037b78b54c4ab290db80034e3192b1f90a1fc

2 years agoUpdate Orbit to R20220830213456 for 2022-09 72/195572/1
Matthias Sohn [Mon, 5 Sep 2022 14:48:05 +0000 (16:48 +0200)]
Update Orbit to R20220830213456 for 2022-09

Change-Id: Iab04fd9e72102abe3d9d927a5cae4a1df2001aa2

2 years agoBaseSuperprojectWriter: report invalid paths as manifest errors 10/195310/1
Ivan Frade [Tue, 23 Aug 2022 19:10:27 +0000 (12:10 -0700)]
BaseSuperprojectWriter: report invalid paths as manifest errors

An invalid path in the manifest (e.g. '.') is reported by DirCache in a
runtime exception. In server context this becomes a 500 instead of a user error.

Wrap the runtime invalid path exception into a checked ManifestErrorException that
caller can handle.

Change-Id: I61a2104922765506ae232334891057bb06141d97

2 years agoApplyCommand: fix ApplyResult#updatedFiles 31/195131/5
Han-Wen Nienhuys [Wed, 10 Aug 2022 15:46:12 +0000 (17:46 +0200)]
ApplyCommand: fix ApplyResult#updatedFiles

On executing a copy, mark the destination as updated.

On executing a rename, mark both source and destination as updated.

Change-Id: Ied5b9b0e5a14eac59a06cdd0961e25e143f50ff0

2 years agoWorkTreeUpdater: rename metadata maps 26/195226/3
Han-Wen Nienhuys [Thu, 18 Aug 2022 16:13:54 +0000 (18:13 +0200)]
WorkTreeUpdater: rename metadata maps

Change-Id: I8ff3803da8fc13377d11c2dc5523e9e32d0650cb

2 years agoWorkTreeUpdater#Result: hide data members 25/195225/3
Han-Wen Nienhuys [Thu, 18 Aug 2022 16:10:47 +0000 (18:10 +0200)]
WorkTreeUpdater#Result: hide data members

This is the standard across JGit.

Change-Id: Ie52ad7000d8725657b33dd4f3adcc05ab9666875

2 years agoMerge "WorkTreeUpdater: re-format and clean-up"
Han-Wen NIenhuys [Thu, 18 Aug 2022 15:22:46 +0000 (11:22 -0400)]
Merge "WorkTreeUpdater: re-format and clean-up"

2 years agoAdd javadoc on RevCommit 81/195081/16
Ronald Bhuleskar [Fri, 5 Aug 2022 19:59:39 +0000 (12:59 -0700)]
Add javadoc on RevCommit

Change-Id: Ib413154fe52983286cb6307862a7373af4fec6e8

2 years agoOption to pass start RevCommit to be blamed on to the BlameGenerator. 82/195082/17
Ronald Bhuleskar [Fri, 5 Aug 2022 20:00:10 +0000 (13:00 -0700)]
Option to pass start RevCommit to be blamed on to the BlameGenerator.

This can allow passing a FilteredRevCommit which is the filtered list of
commit graph making it easier for Blame to work on. This can
significantly improve blame performance since blame can skip expensive
RevWalk.

Change-Id: Ie127cb710d004079e9f53a5802130afdb49a7de1

2 years agoWorkTreeUpdater: re-format and clean-up 82/195182/4
Thomas Wolf [Sun, 14 Aug 2022 15:47:36 +0000 (17:47 +0200)]
WorkTreeUpdater: re-format and clean-up

Reformat using the standard JGit formatter settings. Clean-ups:

* Try to improve javadoc.
* Remove blindly copy-pasted "@since 6.1" annotations.
* Get rid of private method nonNullNonBareRepo(); it's not needed.
* Simplify method nonNullRepo(), and annotate as @NonNull.
* Rename setInCoreFileSizeLimit() to getInCoreFileSizeLimit().

Change-Id: Ib1797e7cf925d87554307468330971e8ab2e05e9
Signed-off-by: Thomas Wolf <twolf@apache.org>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
2 years agoPrepare 6.3.0-SNAPSHOT builds 09/195209/1
Matthias Sohn [Wed, 17 Aug 2022 05:44:50 +0000 (07:44 +0200)]
Prepare 6.3.0-SNAPSHOT builds

Change-Id: Ie398b651c5308ec86812bf01fcc563d3e679c828

2 years agoAdds FilteredRevCommit that can overwrites its parents in the DAG. 26/195026/21
Ronald Bhuleskar [Wed, 3 Aug 2022 23:41:43 +0000 (16:41 -0700)]
Adds FilteredRevCommit that can overwrites its parents in the DAG.

Change-Id: I1ea63a3b56074099688fc45d6a22943a8ae3c2ae

2 years agoJGit v6.3.0.202208161710-m3 05/195205/1 v6.3.0.202208161710-m3
Matthias Sohn [Tue, 16 Aug 2022 21:09:30 +0000 (23:09 +0200)]
JGit v6.3.0.202208161710-m3

Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Change-Id: I0954d11a1f35eff196b157df3aa8386476c48a7e

2 years agoMerge changes Ib6689f54,I3b5c22ee
Matthias Sohn [Tue, 16 Aug 2022 21:00:43 +0000 (17:00 -0400)]
Merge changes Ib6689f54,I3b5c22ee

* changes:
  Remove unused API problem filters
  Add missing @since tag for RevCommit#parents introduced in 61b4d105e4

2 years agoDirCacheCheckout: load WorkingTreeOptions only once 81/195181/2
Thomas Wolf [Sun, 14 Aug 2022 14:34:50 +0000 (16:34 +0200)]
DirCacheCheckout: load WorkingTreeOptions only once

Previous code loaded the WorkingTreeOptions afresh for every single
file being checked out. This checked the git config (all three files,
repo, user and system config) for having been modified every time.

These checks can be costly, for instance on Windows, or if one of the
three config files is not on a local disk, or on an otherwise slow
storage.

Improve this by loading the options and thus checking the git config
only once before the checkout.

Bug: 579715
Change-Id: I21cd5a808f9d90b5ca2d022f91f0eeb8ca26091c
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoWorkTreeUpdater: Fix unclosed streams 80/195180/2
Thomas Wolf [Sun, 14 Aug 2022 14:38:57 +0000 (16:38 +0200)]
WorkTreeUpdater: Fix unclosed streams

1. A TemporaryBuffer.LocalFile must be destroyed to ensure the
   temporary file gets deleted on disk.
2. TemporaryBuffer.openInputStream() may be used only after
   TemporaryBuffer.close().
3. The caller of DirCacheCheckout.getContent() is responsible for
   closing the OutputStream!

Change-Id: I46abb0fba27656a1026858e5783fc60d4738a45e
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoMerge "Fix API errors caused by 23a71696cd"
Matthias Sohn [Sun, 14 Aug 2022 09:43:39 +0000 (05:43 -0400)]
Merge "Fix API errors caused by 23a71696cd"

2 years agoFix adding symlinks to the index when core.symlinks=false 08/194808/2
Thomas Wolf [Wed, 20 Jul 2022 16:30:18 +0000 (18:30 +0200)]
Fix adding symlinks to the index when core.symlinks=false

With core.symlinks=false, symlinks are checked out as plain files.
When such a file is re-added to the index, and the index already
contains a symlink there, add the file as a symlink. Previous code
changed the index entry to a regular file.

Bug: 580412
Change-Id: I5497bedc3da89c8b10120b8077c56bc5b67cb791
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoRemove unused API problem filters 57/195157/1
Matthias Sohn [Fri, 12 Aug 2022 08:44:12 +0000 (10:44 +0200)]
Remove unused API problem filters

Change-Id: Ib6689f545585bd59b8fc06ca3a104080021424d6

2 years agoAdd missing @since tag for RevCommit#parents introduced in 61b4d105e4 56/195156/1
Matthias Sohn [Fri, 12 Aug 2022 08:38:57 +0000 (10:38 +0200)]
Add missing @since tag for RevCommit#parents introduced in 61b4d105e4

Change-Id: I3b5c22eea7d0af5464c7df7a7cd855ea08029853

2 years agoFix API errors caused by 23a71696cd 55/195155/2
Matthias Sohn [Fri, 12 Aug 2022 08:19:24 +0000 (10:19 +0200)]
Fix API errors caused by 23a71696cd

- add missing @since 6.3 for new protected field workTreeUpdater and new
  class WorkTreeUpdater
- suppress API errors caused by removing/adding protected fields and
  methods

We follow OSGi semantic versioning which allows breaking implementers in
minor versions which are e.g. subclassing a public class.

Change-Id: I28f0d7b4fdd9a1f0fbc6b137d6c68dda9fe3c11e

2 years agoMerge "Provide encoding to String#getBytes()"
Han-Wen NIenhuys [Tue, 9 Aug 2022 16:17:32 +0000 (12:17 -0400)]
Merge "Provide encoding to String#getBytes()"

2 years agoMerge changes Ideaefd51,I6c347393
Han-Wen NIenhuys [Tue, 9 Aug 2022 09:10:53 +0000 (05:10 -0400)]
Merge changes Ideaefd51,I6c347393

* changes:
  Reapply "Create util class for work tree updating in both filesystem and index."
  ResolveMerger: add coverage for inCore file => directory transition

2 years agoProvide default shallowCommits getter and setter in ObjectDatabase 85/195085/11
Ronald Bhuleskar [Sat, 6 Aug 2022 00:30:55 +0000 (17:30 -0700)]
Provide default shallowCommits getter and setter in ObjectDatabase

I649db9ae679ec2606cf7c530b040f8b6b93eb81a added a default implementation
for getShallowCommits and setShallowCommits to DfsObjDatabase, for the
convenience of any implementers that define subclasses. But we forgot
that some implementers inherit from ObjectDatabase directly instead.
Move the default getter and setter to the base class so that such
callers do not need source changes to unbreak their build.

This also lets us update the api_filters to reflect that this is no
longer an API-breaking change.

Change-Id: I5dcca462eb306e511e57907b7d9264d51b3f3014

2 years agoReapply "Create util class for work tree updating in both filesystem and index." 99/195099/5
Nitzan Gur-Furman [Mon, 8 Aug 2022 15:50:47 +0000 (17:50 +0200)]
Reapply "Create util class for work tree updating in both filesystem and index."

This reverts commit 5709317f71ccaf26eceaa896150f203879b634b8.

Add a bugfix for deletions in ResolveMergers instantiated with just an
ObjectInserter as argument.

Original change description:

Create util class for work tree updating in both filesystem and index.

This class intends to make future support in index updating easier.

This class currently extracts some logic from ResolveMerger. Logic
related to StreamSupplier was copied from ApplyCommand, which will be
integrated in a following change.

Co-authored-by: Nitzan Gur-Furman <nitzan@google.com>
Co-authored-by: Han-Wen Nienhuys <hanwen@google.com>
Change-Id: Ideaefd51789a382a8b499d1ca7ae0146d032f48b

2 years agoResolveMerger: add coverage for inCore file => directory transition 05/195105/2
Han-Wen Nienhuys [Mon, 8 Aug 2022 15:49:14 +0000 (17:49 +0200)]
ResolveMerger: add coverage for inCore file => directory transition

Change-Id: I6c3473932eb418a036f5943c78e619184559ef3a

2 years agoProvide encoding to String#getBytes() 00/195100/1
Han-Wen Nienhuys [Mon, 8 Aug 2022 14:00:48 +0000 (16:00 +0200)]
Provide encoding to String#getBytes()

Fixes ErrorProne complaint.

Change-Id: I706b225f98187bf5f86999ed5342d0072e57e314

2 years agoRevert "Create util class for work tree updating in both filesystem and index." 58/194258/2
Jonathan Nieder [Fri, 5 Aug 2022 20:11:41 +0000 (16:11 -0400)]
Revert "Create util class for work tree updating in both filesystem and index."

This reverts commit 5151b324f4605b1091ac5843dcc1f04b3996f0d1. It is
producing NullPointerExceptions during merges, causing Gerrit's
acceptance tests to fail:

com.google.gerrit.extensions.restapi.RestApiException: Cannot rebase ps
[...]
at com.google.gerrit.server.api.changes.RevisionApiImpl.rebase(RevisionApiImpl.java:280)
at com.google.gerrit.acceptance.api.change.ChangeIT.rebaseChangeBase(ChangeIT.java:1584)
Caused by: com.google.gerrit.server.update.UpdateException: java.lang.NullPointerException: repository is required
at com.google.gerrit.server.update.BatchUpdate.executeUpdateRepo(BatchUpdate.java:588)
[...]
Caused by: java.lang.NullPointerException: repository is required
at org.eclipse.jgit.merge.Merger.nonNullRepo(Merger.java:128)
at org.eclipse.jgit.merge.ResolveMerger.addDeletion(ResolveMerger.java:380)
at org.eclipse.jgit.merge.ResolveMerger.processEntry(ResolveMerger.java:553)
at org.eclipse.jgit.merge.ResolveMerger.mergeTreeWalk(ResolveMerger.java:1224)
at org.eclipse.jgit.merge.ResolveMerger.mergeTrees(ResolveMerger.java:1174)
at org.eclipse.jgit.merge.ResolveMerger.mergeImpl(ResolveMerger.java:299)
at org.eclipse.jgit.merge.Merger.merge(Merger.java:233)
at org.eclipse.jgit.merge.Merger.merge(Merger.java:186)
at org.eclipse.jgit.merge.ThreeWayMerger.merge(ThreeWayMerger.java:96)
at com.google.gerrit.server.change.RebaseChangeOp.rebaseCommit(RebaseChangeOp.java:360)

Change-Id: Idf63de81666d0df118d2d93c4f6e014e00dc05b8

2 years agoProvide a default implementation for set/get shallowCommits on DfsObjDatabase 84/195084/2
Ronald Bhuleskar [Fri, 5 Aug 2022 21:23:17 +0000 (14:23 -0700)]
Provide a default implementation for set/get shallowCommits on DfsObjDatabase

Jgit change https://git.eclipse.org/r/c/jgit/jgit/+/193329 adds an implementation for get/set shallow commits in ObjectDatabase. This failed gerrit's acceptance tests since there is no default implementation for them in DfsObjDatabase.

Change-Id: I649db9ae679ec2606cf7c530b040f8b6b93eb81a

2 years agoMerge "Revert "Option to pass start RevCommit to be blamed on to the BlameGenerator.""
Terry Parker [Wed, 3 Aug 2022 22:38:05 +0000 (18:38 -0400)]
Merge "Revert "Option to pass start RevCommit to be blamed on to the BlameGenerator.""

2 years agoMerge "Revert "Adds FilteredRevCommit that can overwrites its parents in the DAG.""
Terry Parker [Wed, 3 Aug 2022 22:37:57 +0000 (18:37 -0400)]
Merge "Revert "Adds FilteredRevCommit that can overwrites its parents in the DAG.""

2 years agoRevert "Adds FilteredRevCommit that can overwrites its parents in the DAG." 57/194257/1
Ronald Bhuleskar [Wed, 3 Aug 2022 21:16:34 +0000 (17:16 -0400)]
Revert "Adds FilteredRevCommit that can overwrites its parents in the DAG."

This reverts commit ceb51a5e0e9db166e572ea7cd362795b4662b0cd.

Reason for revert: The change in https://git.eclipse.org/r/c/jgit/jgit/+/194354 broke the egit test [1]. Calling c.getShortMessage() causes an NPE.

[1] https://ci.eclipse.org/egit/job/egit.gerrit/2711/

Change-Id: I411565b6eaa0bbb562cc1c8a355942ff09fd29bc

2 years agoRevert "Option to pass start RevCommit to be blamed on to the BlameGenerator." 56/194256/1
Ronald Bhuleskar [Wed, 3 Aug 2022 21:14:18 +0000 (17:14 -0400)]
Revert "Option to pass start RevCommit to be blamed on to the BlameGenerator."

This reverts commit 59e8bec6e7705a89b5d0b9c6ac004b323ffa16b0.

Reason for revert: The change in https://git.eclipse.org/r/c/jgit/jgit/+/194354 broke the egit test [1]. Calling c.getShortMessage() causes an NPE.

[1] https://ci.eclipse.org/egit/job/egit.gerrit/2711/

Change-Id: Iaf5feb35f4bb4c3487b04be15d1fe11376975523

2 years agoCleanCommand: fix prefix matching 44/194944/3
Thomas Wolf [Fri, 29 Jul 2022 22:27:49 +0000 (00:27 +0200)]
CleanCommand: fix prefix matching

String.startsWith() is not a valid test for file path prefixes:
directory "a" is _not_ a prefix of a file "ab", only of "a/b".

Add a proper Paths.isEqualOrPrefix() method and use it in CleanCommand.

Bug: 580478
Change-Id: I6863e6ba94a8ffba6561835cc57044a0945d2770
Signed-off-by: Thomas Wolf <twolf@apache.org>
2 years agoOption to pass start RevCommit to be blamed on to the BlameGenerator. 98/194998/2
Ronald Bhuleskar [Wed, 3 Aug 2022 00:17:46 +0000 (17:17 -0700)]
Option to pass start RevCommit to be blamed on to the BlameGenerator.

This can allow passing a FilteredRevCommit which is the filtered list of
commit graph making it easier for Blame to work on. This can
significantly improve blame performance since blame can skip expensive
RevWalk.

Change-Id: I5dab25301d6aef7df6a0bc25a4c553c730199272

2 years agoAdds FilteredRevCommit that can overwrites its parents in the DAG. 54/194354/29
Ronald Bhuleskar [Wed, 3 Aug 2022 00:15:08 +0000 (17:15 -0700)]
Adds FilteredRevCommit that can overwrites its parents in the DAG.

Change-Id: I2df9843dde0f589f5fea6cedaaff52e313eea6de

2 years agoAdd the ability to override parents on RevCommit. 04/194204/26
Ronald Bhuleskar [Wed, 15 Jun 2022 21:37:21 +0000 (14:37 -0700)]
Add the ability to override parents on RevCommit.

This makes RevCommit extensible to allow having different structure of
child-parent relationship. This change is a pre-requsite for having a
FilteredRevCommit that overrides parents from the RevCommit. That then
provides a cheaper way to walk over a subset of RevCommits instead of
an expensive way that applies filters while walking over selected
commits. Useful with Blame which works on a single file and that can be
made performant, if we know all the commits needed by the Blame
algorithm. So Blame algorithm can avoid walking over finding what
commits to blame on.

This change makes parents field on RevCommit private and exposes it
thrrough overrideable methods such as getParents, getParent at index,
getParentCount and setParents. All other files other than RevCommit are
updating the usages of accessing RevCommits parents.

Change-Id: I2d13b001c599cc4ebc92d1ab6e07b07acb3b7fe5

2 years agoRefactor NameConflictTreeWalk.fastMin method 70/194970/4
Dmitrii Filippov [Mon, 1 Aug 2022 17:13:03 +0000 (19:13 +0200)]
Refactor NameConflictTreeWalk.fastMin method

Change-Id: Iac2e6f615463e18ddf788e6ddfe15ef023cac977

2 years agoFix BUILD rules for FilteredRenameDetectorTest 69/194969/3
Dmitrii Filippov [Mon, 1 Aug 2022 17:11:25 +0000 (19:11 +0200)]
Fix BUILD rules for FilteredRenameDetectorTest

The FilteredRenameDetectorTest was added in [1], but bazel build rules
were not updated.

[1] https://git.eclipse.org/r/c/jgit/jgit/+/194200

Change-Id: I7fc713e19b4768176eb84e9768137431b33a805e

2 years agoRename fastMinHasMatch to allTreesNamesMatchFastMinRef 67/194967/3
Dmitrii Filippov [Mon, 1 Aug 2022 16:43:43 +0000 (18:43 +0200)]
Rename fastMinHasMatch to allTreesNamesMatchFastMinRef

Change-Id: I2d9165616650e9d44745c6848d2cf1045f53f33c

2 years agoMerge "Document TreeWalk#min()"
Han-Wen NIenhuys [Mon, 1 Aug 2022 17:07:29 +0000 (13:07 -0400)]
Merge "Document TreeWalk#min()"

2 years agoMerge "NameConflictTreeWalk: respect git order on multi-tree iteration"
Han-Wen NIenhuys [Mon, 1 Aug 2022 15:25:10 +0000 (11:25 -0400)]
Merge "NameConflictTreeWalk: respect git order on multi-tree iteration"

2 years agoDocument TreeWalk#min() 61/194961/2
Han-Wen Nienhuys [Mon, 1 Aug 2022 13:39:07 +0000 (15:39 +0200)]
Document TreeWalk#min()

Change-Id: I29a6c023929d8270a8cdd1e7f012817a06428f42
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
2 years agoSquash error-prone messages 60/194960/1
Han-Wen Nienhuys [Mon, 1 Aug 2022 13:26:47 +0000 (15:26 +0200)]
Squash error-prone messages

Change-Id: Ibbccc4d1faf1f0a1f0f4136c5bf075f155d80157
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>