diff --git a/.bazelversion b/.bazelversion index ccbccc3dc..fd2a01863 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -2.2.0 +3.1.0 diff --git a/Documentation/config-options.md b/Documentation/config-options.md new file mode 100644 index 000000000..94ef5b955 --- /dev/null +++ b/Documentation/config-options.md @@ -0,0 +1,57 @@ +# JGit configuration options + +## Legend + +| git option | description | +|------------|-------------| +| ✅ | option defined by native git | +| ⃞ | jgit custom option not supported by native git | + +## __core__ options + +| option | default | git option | description | +|---------|---------|------------|-------------| +| `core.bigFileThreshold` | `52428800` (50 MiB) | ✅ | Maximum file size that will be delta compressed. Files larger than this size are stored deflated, without attempting delta compression. | +| `core.compression` | `-1` (default compression) | ✅ | An integer -1..9, indicating a default compression level. -1 is the zlib default. 0 means no compression, and 1..9 are various speed/size tradeoffs, 9 being slowest.| + +## __gc__ options + +| option | default | git option | description | +|---------|---------|------------|-------------| +| `gc.aggressiveDepth` | 50 | ✅ | The depth parameter used in the delta compression algorithm used by aggressive garbage collection. | +| `gc.aggressiveWindow` | 250 | ✅ | The window size parameter used in the delta compression algorithm used by aggressive garbage collection. | +| `gc.auto` | `6700` | ✅ | Number of loose objects until auto gc combines all loose objects into a pack and consolidates all existing packs into one. Setting to 0 disables automatic packing of loose objects. | +| `gc.autoDetach` | `true` | ✅ | Make auto gc return immediately and run in background. | +| `gc.autoPackLimit` | `50` | ✅ | Number of packs until auto gc consolidates existing packs (except those marked with a .keep file) into a single pack. Setting `gc.autoPackLimit` to 0 disables automatic consolidation of packs. | +| `gc.logExpiry` | `1.day.ago` | ✅ | If the file `gc.log` exists, then auto gc will print its content and exit successfully instead of running unless that file is more than `gc.logExpiry` old. | +| `gc.pruneExpire` | `2.weeks.ago` | ✅ | Grace period after which unreachable objects will be pruned. | +| `gc.prunePackExpire` | `1.hour.ago` | ⃞ | Grace period after which packfiles only containing unreachable objects will be pruned. | + +## __pack__ options + +| option | default | git option | description | +|---------|---------|------------|-------------| +| `pack.bitmapContiguousCommitCount` | `100` | ⃞ | Count of most recent commits for which to build bitmaps. | +| `pack.bitmapDistantCommitSpan` | `5000` | ⃞ | Span of commits when building bitmaps for distant history. | +| `pack.bitmapExcessiveBranchCount` | `100` | ⃞ | The count of branches deemed "excessive". If the count of branches in a repository exceeds this number and bitmaps are enabled, "inactive" branches will have fewer bitmaps than "active" branches. | +| `pack.bitmapInactiveBranchAgeInDays` | `90` | ⃞ | Age in days that marks a branch as "inactive" for bitmap creation. | +| `pack.bitmapRecentCommitCount` | `20000` | ⃞ | Count at which to switch from `bitmapRecentCommitSpan` to `bitmapDistantCommitSpan`. | +| `pack.bitmapRecentCommitSpan` | `100` | ⃞ | Span of commits when building bitmaps for recent history. | +| `pack.buildBitmaps` | `true` | ⃞ synonym for `repack.writeBitmaps` | Whether index writer is allowed to build bitmaps for indexes. | +| `pack.compression` | `core.compression` | ✅ | Compression level applied to objects in the pack. | +| `pack.cutDeltaChains` | `false` | ⃞ | Whether existing delta chains should be cut at {@link #getMaxDeltaDepth() | +| `pack.deltaCacheLimit` | `100` | ✅ | Maximum size in bytes of a delta to cache. | +| `pack.deltaCacheSize` | `52428800` (50 MiB) | ✅ | Size of the in-memory delta cache. | +| `pack.deltaCompression` | `true` | ⃞ | Whether the writer will create new deltas on the fly. `true` if the pack writer will create a new delta when either `pack.reuseDeltas` is false, or no suitable delta is available for reuse. | +| `pack.depth` | `50` | ✅ | Maximum depth of delta chain set up for the pack writer. | +| `pack.indexVersion` | `2` | ✅ | Pack index file format version. | +| `pack.minSizePreventRacyPack` | `104857600` (100 MiB) | ⃞ | Minimum packfile size for which we wait before opening a newly written pack to prevent its lastModified timestamp could be racy if `pack.waitPreventRacyPack` is `true`. | +| `pack.preserveOldPacks` | `false` | ⃞ | Whether to preserve old packs in a preserved directory. | +| `prunePreserved`, only via API of PackConfig | `false` | ⃞ | Whether to remove preserved pack files in a preserved directory. | +| `pack.reuseDeltas` | `true` |⃞ | Whether to reuse deltas existing in repository. | +| `pack.reuseObjects` | `true` | ⃞ | Whether to reuse existing objects representation in repository. | +| `pack.singlePack` | `false` | ⃞ | Whether all of `refs/*` should be packed in a single pack. | +| `pack.threads` | `0` (auto-detect number of processors) | ✅ | Number of threads to use for delta compression. | +| `pack.waitPreventRacyPack` | `false` | ⃞ | Whether we wait before opening a newly written pack to prevent its lastModified timestamp could be racy. | +| `pack.window` | `10` | ✅ | Number of objects to try when looking for a delta base per thread searching for deltas. | +| `pack.windowMemory` | `0` (unlimited) | ✅ | Maximum number of bytes to put into the delta search window. | diff --git a/WORKSPACE b/WORKSPACE index 5fa28f9e2..9e0ad3ecb 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -95,14 +95,14 @@ maven_jar( maven_jar( name = "sshd-osgi", - artifact = "org.apache.sshd:sshd-osgi:2.2.0", - sha1 = "a45d48cb53678e699816e8e054e55fa33f5a4558", + artifact = "org.apache.sshd:sshd-osgi:2.4.0", + sha1 = "fc4551c1eeda35e4671b263297d37d2bca81c4d4", ) maven_jar( name = "sshd-sftp", - artifact = "org.apache.sshd:sshd-sftp:2.2.0", - sha1 = "3d011e00adf38e49bb8711a9dd762fe908a2170c", + artifact = "org.apache.sshd:sshd-sftp:2.4.0", + sha1 = "92e1b7d1e19c715efb4a8871d34145da8f87cdb2", ) maven_jar( @@ -253,25 +253,25 @@ maven_jar( src_sha1 = "c84dc3026cc4aea013dc97b18228756816167745", ) -BOUNCYCASTLE_VER = "1.64" +BOUNCYCASTLE_VER = "1.65" maven_jar( name = "bcpg", artifact = "org.bouncycastle:bcpg-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "56956a8c63ccadf62e7c678571cf86f30bd84441", - src_sha1 = "b241337df9516b35637d9be84451e2f03a81d186", + sha1 = "f32fc02cc29c9fdcc35c0de4d16964f01777067c", + src_sha1 = "35e87838bf9348b25aae07135ceccfbef6827e3c", ) maven_jar( name = "bcprov", artifact = "org.bouncycastle:bcprov-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "1467dac1b787b5ad2a18201c0c281df69882259e", - src_sha1 = "2881bfaf2c15e9e64b62c2a143db90db7a0d6035", + sha1 = "320b989112f00a63a3bcfa5a98f31a4f865a20fa", + src_sha1 = "ef2676604015c183bb29f8e17846cb3aa4b80c24", ) maven_jar( name = "bcpkix", artifact = "org.bouncycastle:bcpkix-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "3dac163e20110817d850d17e0444852a6d7d0bd7", - src_sha1 = "5c87199786c06e1a53adf16b1998386bad52da89", + sha1 = "c9507d93e4b453320b57d9ac21bdd67d65a00bbc", + src_sha1 = "16c71e83af43927d20ccad19defcbb0babcbdb26", ) diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java index e586888bb..f53c8aecb 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java @@ -124,7 +124,7 @@ public class MetaFilter implements Filter { @Override public boolean contains(Object o) { - return m.keySet().contains(o); + return m.containsKey(o); } @Override diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF index a4761afe9..28f3513b8 100644 --- a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF @@ -8,28 +8,28 @@ Bundle-Localization: plugin Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.apache.sshd.common;version="[2.2.0,2.3.0)", - org.apache.sshd.common.config.keys;version="[2.2.0,2.3.0)", - org.apache.sshd.common.file.virtualfs;version="[2.2.0,2.3.0)", - org.apache.sshd.common.helpers;version="[2.2.0,2.3.0)", - org.apache.sshd.common.io;version="[2.2.0,2.3.0)", - org.apache.sshd.common.kex;version="[2.2.0,2.3.0)", - org.apache.sshd.common.keyprovider;version="[2.2.0,2.3.0)", - org.apache.sshd.common.session;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.buffer;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.logging;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.threads;version="[2.2.0,2.3.0)", - org.apache.sshd.server;version="[2.2.0,2.3.0)", - org.apache.sshd.server.auth;version="[2.2.0,2.3.0)", - org.apache.sshd.server.auth.gss;version="[2.2.0,2.3.0)", - org.apache.sshd.server.auth.keyboard;version="[2.2.0,2.3.0)", - org.apache.sshd.server.auth.password;version="[2.2.0,2.3.0)", - org.apache.sshd.server.command;version="[2.2.0,2.3.0)", - org.apache.sshd.server.session;version="[2.2.0,2.3.0)", - org.apache.sshd.server.shell;version="[2.2.0,2.3.0)", - org.apache.sshd.server.subsystem;version="[2.2.0,2.3.0)", - org.apache.sshd.server.subsystem.sftp;version="[2.2.0,2.3.0)", +Import-Package: org.apache.sshd.common;version="[2.4.0,2.5.0)", + org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)", + org.apache.sshd.common.file.virtualfs;version="[2.4.0,2.5.0)", + org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)", + org.apache.sshd.common.io;version="[2.4.0,2.5.0)", + org.apache.sshd.common.kex;version="[2.4.0,2.5.0)", + org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)", + org.apache.sshd.common.session;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.buffer;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.logging;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.threads;version="[2.4.0,2.5.0)", + org.apache.sshd.server;version="[2.4.0,2.5.0)", + org.apache.sshd.server.auth;version="[2.4.0,2.5.0)", + org.apache.sshd.server.auth.gss;version="[2.4.0,2.5.0)", + org.apache.sshd.server.auth.keyboard;version="[2.4.0,2.5.0)", + org.apache.sshd.server.auth.password;version="[2.4.0,2.5.0)", + org.apache.sshd.server.command;version="[2.4.0,2.5.0)", + org.apache.sshd.server.session;version="[2.4.0,2.5.0)", + org.apache.sshd.server.shell;version="[2.4.0,2.5.0)", + org.apache.sshd.server.subsystem;version="[2.4.0,2.5.0)", + org.apache.sshd.server.subsystem.sftp;version="[2.4.0,2.5.0)", org.eclipse.jgit.annotations;version="[6.0.0,6.1.0)", org.eclipse.jgit.lib;version="[6.0.0,6.1.0)", org.eclipse.jgit.transport;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java index ac4e9927d..883ff0b8b 100644 --- a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java +++ b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.List; import java.util.Locale; -import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.NamedResource; import org.apache.sshd.common.PropertyResolverUtils; import org.apache.sshd.common.SshConstants; @@ -40,14 +39,15 @@ import org.apache.sshd.server.ServerAuthenticationManager; import org.apache.sshd.server.ServerFactoryManager; import org.apache.sshd.server.SshServer; import org.apache.sshd.server.auth.UserAuth; +import org.apache.sshd.server.auth.UserAuthFactory; import org.apache.sshd.server.auth.gss.GSSAuthenticator; import org.apache.sshd.server.auth.gss.UserAuthGSS; import org.apache.sshd.server.auth.gss.UserAuthGSSFactory; import org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator; import org.apache.sshd.server.command.AbstractCommandSupport; -import org.apache.sshd.server.command.Command; import org.apache.sshd.server.session.ServerSession; import org.apache.sshd.server.shell.UnknownCommand; +import org.apache.sshd.server.subsystem.SubsystemFactory; import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.lib.Repository; @@ -117,14 +117,14 @@ public class SshTestGitServer { configureAuthentication(); - List> subsystems = configureSubsystems(); + List subsystems = configureSubsystems(); if (!subsystems.isEmpty()) { server.setSubsystemFactories(subsystems); } configureShell(); - server.setCommandFactory(command -> { + server.setCommandFactory((channel, command) -> { if (command.startsWith(RemoteConfig.DEFAULT_UPLOAD_PACK)) { return new GitUploadPackCommand(command, executorService); } else if (command.startsWith(RemoteConfig.DEFAULT_RECEIVE_PACK)) { @@ -155,11 +155,12 @@ public class SshTestGitServer { } } - private List> getAuthFactories() { - List> authentications = new ArrayList<>(); + private List getAuthFactories() { + List authentications = new ArrayList<>(); authentications.add(new UserAuthGSSFactory() { @Override - public UserAuth create() { + public UserAuth createUserAuth(ServerSession session) + throws IOException { return new FakeUserAuthGSS(); } }); @@ -208,7 +209,7 @@ public class SshTestGitServer { * @return A possibly empty collection of subsystems. */ @NonNull - protected List> configureSubsystems() { + protected List configureSubsystems() { // SFTP. server.setFileSystemFactory(new VirtualFileSystemFactory() { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target index c5a8b09eb..f4c2acf7d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd index ed3cd211d..34357eee0 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd @@ -1,8 +1,8 @@ target "jgit-4.10" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/2018-12/" { +location "https://download.eclipse.org/releases/2018-12/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target index ac0c33de1..b17d13aad 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd index 426b61ea1..f7c0a5b7d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd @@ -1,8 +1,8 @@ target "jgit-4.11" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/2019-03/" { +location "https://download.eclipse.org/releases/2019-03/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target index 39d011cc1..f72699b73 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd index 8a8c0df1c..4be47a478 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd @@ -1,8 +1,8 @@ target "jgit-4.12" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/2019-06/" { +location "https://download.eclipse.org/releases/2019-06/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target index f875b54ea..7be48e553 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd index a58e21559..3c3dd50c4 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd @@ -1,8 +1,8 @@ target "jgit-4.13" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/2019-09/" { +location "https://download.eclipse.org/releases/2019-09/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target index d601082ff..02330c92d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd index a9ef71d17..69fb2bb0d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd @@ -1,8 +1,8 @@ target "jgit-4.14-staging" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/2019-12/201912181000/" { +location "https://download.eclipse.org/releases/2019-12/201912181000/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.target index ab8e6ec15..f070f48c2 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.tpd index 1bfb3752b..84bad578c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15-staging.tpd @@ -1,8 +1,8 @@ target "jgit-4.14-staging" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/staging/2020-03/" { +location "https://download.eclipse.org/staging/2020-03/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target index 8cdce9372..4a40ec0f9 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd index 5e169d8c6..8c8253597 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd @@ -1,8 +1,8 @@ target "jgit-4.6" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/neon/" { +location "https://download.eclipse.org/releases/neon/" { org.eclipse.osgi lazy } \ No newline at end of file diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target index bd287080d..0a704200e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd index c87530276..baa228a70 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd @@ -1,8 +1,8 @@ target "jgit-4.7" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/oxygen/" { +location "https://download.eclipse.org/releases/oxygen/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target index cd15ba60f..fa0413746 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd index 91ab59716..e60b7b556 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd @@ -1,8 +1,8 @@ target "jgit-4.8" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/photon/" { +location "https://download.eclipse.org/releases/photon/" { org.eclipse.osgi lazy } diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target index f71923f1d..4db5e3b1c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target @@ -1,7 +1,7 @@ - + @@ -53,18 +53,18 @@ - - - - + + + + - - - - - - + + + + + + @@ -74,8 +74,8 @@ - - + + @@ -84,11 +84,11 @@ - + - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd index faa6fba18..af62db9ec 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd @@ -1,8 +1,8 @@ target "jgit-4.9" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20200224183213-2020-03.tpd" +include "orbit/I20200506000552.tpd" -location "http://download.eclipse.org/releases/2018-09/" { +location "https://download.eclipse.org/releases/2018-09/" { org.eclipse.osgi lazy } \ No newline at end of file diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/I20200506000552.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/I20200506000552.tpd new file mode 100644 index 000000000..5edb2fc4c --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/I20200506000552.tpd @@ -0,0 +1,66 @@ +target "I20200506000552" with source configurePhase +// see https://download.eclipse.org/tools/orbit/downloads/ + +location "https://download.eclipse.org/tools/orbit/downloads/drops/I20200506000552/repository" { + com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110] + com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110] + com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902] + com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902] + com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305] + com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305] + javaewah [1.1.7.v20200107-0831,1.1.7.v20200107-0831] + javaewah.source [1.1.7.v20200107-0831,1.1.7.v20200107-0831] + javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800] + javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800] + net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410] + net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534] + net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534] + net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410] + net.i2p.crypto.eddsa [0.3.0.v20181102-1323,0.3.0.v20181102-1323] + net.i2p.crypto.eddsa.source [0.3.0.v20181102-1323,0.3.0.v20181102-1323] + org.apache.ant [1.10.7.v20190926-0324,1.10.7.v20190926-0324] + org.apache.ant.source [1.10.7.v20190926-0324,1.10.7.v20190926-0324] + org.apache.commons.codec [1.13.0.v20200108-0001,1.13.0.v20200108-0001] + org.apache.commons.codec.source [1.13.0.v20200108-0001,1.13.0.v20200108-0001] + org.apache.commons.compress [1.19.0.v20200106-2343,1.19.0.v20200106-2343] + org.apache.commons.compress.source [1.19.0.v20200106-2343,1.19.0.v20200106-2343] + org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502] + org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502] + org.apache.httpcomponents.httpclient [4.5.10.v20200114-1512,4.5.10.v20200114-1512] + org.apache.httpcomponents.httpclient.source [4.5.10.v20200114-1512,4.5.10.v20200114-1512] + org.apache.httpcomponents.httpcore [4.4.12.v20200108-1212,4.4.12.v20200108-1212] + org.apache.httpcomponents.httpcore.source [4.4.12.v20200108-1212,4.4.12.v20200108-1212] + org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815] + org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815] + org.apache.sshd.osgi [2.4.0.v20200318-1614,2.4.0.v20200318-1614] + org.apache.sshd.osgi.source [2.4.0.v20200318-1614,2.4.0.v20200318-1614] + org.apache.sshd.sftp [2.4.0.v20200319-1547,2.4.0.v20200319-1547] + org.apache.sshd.sftp.source [2.4.0.v20200319-1547,2.4.0.v20200319-1547] + org.assertj [3.14.0.v20200120-1926,3.14.0.v20200120-1926] + org.assertj.source [3.14.0.v20200120-1926,3.14.0.v20200120-1926] + org.bouncycastle.bcpg [1.65.0.v20200502-2229,1.65.0.v20200502-2229] + org.bouncycastle.bcpg.source [1.65.0.v20200502-2229,1.65.0.v20200502-2229] + org.bouncycastle.bcpkix [1.65.0.v20200502-2229,1.65.0.v20200502-2229] + org.bouncycastle.bcpkix.source [1.65.0.v20200502-2229,1.65.0.v20200502-2229] + org.bouncycastle.bcprov [1.65.0.v20200502-2229,1.65.0.v20200502-2229] + org.bouncycastle.bcprov.source [1.65.0.v20200502-2229,1.65.0.v20200502-2229] + org.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000] + org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519] + org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519] + org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246] + org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246] + org.junit [4.13.0.v20200204-1500,4.13.0.v20200204-1500] + org.junit.source [4.13.0.v20200204-1500,4.13.0.v20200204-1500] + org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218] + org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218] + org.mockito [2.23.0.v20200310-1642,2.23.0.v20200310-1642] + org.mockito.source [2.23.0.v20200310-1642,2.23.0.v20200310-1642] + org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519] + org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519] + org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250] + org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250] + org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200] + org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200] + org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613] + org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613] +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd index e278bb18f..4d584a96b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd @@ -1,5 +1,5 @@ target "R20190602212107-2019-06" with source configurePhase -// see http://download.eclipse.org/tools/orbit/downloads/ +// see https://download.eclipse.org/tools/orbit/downloads/ location "https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository" { com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110] diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190827152740-2019-09.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190827152740-2019-09.tpd index 63642f5e4..d5366eb5c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190827152740-2019-09.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190827152740-2019-09.tpd @@ -1,5 +1,5 @@ target "R20190827152740-2019-09" with source configurePhase -// see http://download.eclipse.org/tools/orbit/downloads/ +// see https://download.eclipse.org/tools/orbit/downloads/ location "https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository" { com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110] diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20191126223242-2019-12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20191126223242-2019-12.tpd index 679e919cd..6c4402aca 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20191126223242-2019-12.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20191126223242-2019-12.tpd @@ -1,5 +1,5 @@ target "R20191126223242-2019-12" with source configurePhase -// see http://download.eclipse.org/tools/orbit/downloads/ +// see https://download.eclipse.org/tools/orbit/downloads/ location "https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository" { com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110] diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200224183213-2020-03.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200224183213-2020-03.tpd index 796afa082..b3b360029 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200224183213-2020-03.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200224183213-2020-03.tpd @@ -1,5 +1,5 @@ target "R20200224183213-2020-03" with source configurePhase -// see http://download.eclipse.org/tools/orbit/downloads/ +// see https://download.eclipse.org/tools/orbit/downloads/ location "https://download.eclipse.org/tools/orbit/downloads/drops/R20200224183213/repository" { com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110] diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 939150bad..9d51ea4df 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -22,7 +22,7 @@ JGit Tycho Parent - 1.6.0 + 1.7.0 ${tycho-version} jgit-4.6 diff --git a/org.eclipse.jgit.pgm/jgit.sh b/org.eclipse.jgit.pgm/jgit.sh index e26378273..a36922003 100644 --- a/org.eclipse.jgit.pgm/jgit.sh +++ b/org.eclipse.jgit.pgm/jgit.sh @@ -79,7 +79,7 @@ CYGWIN*) Darwin) if [ -e /System/Library/Frameworks/JavaVM.framework ] then - java_args=' + java_args+=' -Dcom.apple.mrj.application.apple.menu.about.name=JGit -Dcom.apple.mrj.application.growbox.intrudes=false -Dapple.laf.useScreenMenuBar=true diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF index ff94436cf..b69f89da6 100644 --- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF @@ -7,14 +7,14 @@ Bundle-Version: 6.0.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.apache.sshd.client.config.hosts;version="[2.2.0,2.3.0)", - org.apache.sshd.common;version="[2.2.0,2.3.0)", - org.apache.sshd.common.auth;version="[2.2.0,2.3.0)", - org.apache.sshd.common.config.keys;version="[2.2.0,2.3.0)", - org.apache.sshd.common.keyprovider;version="[2.2.0,2.3.0)", - org.apache.sshd.common.session;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.net;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)", +Import-Package: org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)", + org.apache.sshd.common;version="[2.4.0,2.5.0)", + org.apache.sshd.common.auth;version="[2.4.0,2.5.0)", + org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)", + org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)", + org.apache.sshd.common.session;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)", org.eclipse.jgit.api.errors;version="[6.0.0,6.1.0)", org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.0.0,6.1.0)", org.eclipse.jgit.junit;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF index 40bd6901a..a9f1f1ceb 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF @@ -33,48 +33,48 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.0.0";x-inter org.apache.sshd.client.session, org.apache.sshd.client.keyverifier" Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)", - org.apache.sshd.agent;version="[2.2.0,2.3.0)", - org.apache.sshd.client;version="[2.2.0,2.3.0)", - org.apache.sshd.client.auth;version="[2.2.0,2.3.0)", - org.apache.sshd.client.auth.keyboard;version="[2.2.0,2.3.0)", - org.apache.sshd.client.auth.password;version="[2.2.0,2.3.0)", - org.apache.sshd.client.auth.pubkey;version="[2.2.0,2.3.0)", - org.apache.sshd.client.channel;version="[2.2.0,2.3.0)", - org.apache.sshd.client.config.hosts;version="[2.2.0,2.3.0)", - org.apache.sshd.client.config.keys;version="[2.2.0,2.3.0)", - org.apache.sshd.client.future;version="[2.2.0,2.3.0)", - org.apache.sshd.client.keyverifier;version="[2.2.0,2.3.0)", - org.apache.sshd.client.session;version="[2.2.0,2.3.0)", - org.apache.sshd.client.subsystem.sftp;version="[2.2.0,2.3.0)", - org.apache.sshd.common;version="[2.2.0,2.3.0)", - org.apache.sshd.common.auth;version="[2.2.0,2.3.0)", - org.apache.sshd.common.channel;version="[2.2.0,2.3.0)", - org.apache.sshd.common.compression;version="[2.2.0,2.3.0)", - org.apache.sshd.common.config.keys;version="[2.2.0,2.3.0)", - org.apache.sshd.common.config.keys.loader;version="[2.2.0,2.3.0)", - org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.2.0,2.3.0)", - org.apache.sshd.common.digest;version="[2.2.0,2.3.0)", - org.apache.sshd.common.forward;version="[2.2.0,2.3.0)", - org.apache.sshd.common.future;version="[2.2.0,2.3.0)", - org.apache.sshd.common.helpers;version="[2.2.0,2.3.0)", - org.apache.sshd.common.io;version="[2.2.0,2.3.0)", - org.apache.sshd.common.kex;version="[2.2.0,2.3.0)", - org.apache.sshd.common.keyprovider;version="[2.2.0,2.3.0)", - org.apache.sshd.common.mac;version="[2.2.0,2.3.0)", - org.apache.sshd.common.random;version="[2.2.0,2.3.0)", - org.apache.sshd.common.session;version="[2.2.0,2.3.0)", - org.apache.sshd.common.session.helpers;version="[2.2.0,2.3.0)", - org.apache.sshd.common.signature;version="[2.2.0,2.3.0)", - org.apache.sshd.common.subsystem.sftp;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.buffer;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.closeable;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.io;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.io.resource;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.logging;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.net;version="[2.2.0,2.3.0)", - org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)", - org.apache.sshd.server.auth;version="[2.2.0,2.3.0)", + org.apache.sshd.agent;version="[2.4.0,2.5.0)", + org.apache.sshd.client;version="[2.4.0,2.5.0)", + org.apache.sshd.client.auth;version="[2.4.0,2.5.0)", + org.apache.sshd.client.auth.keyboard;version="[2.4.0,2.5.0)", + org.apache.sshd.client.auth.password;version="[2.4.0,2.5.0)", + org.apache.sshd.client.auth.pubkey;version="[2.4.0,2.5.0)", + org.apache.sshd.client.channel;version="[2.4.0,2.5.0)", + org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)", + org.apache.sshd.client.config.keys;version="[2.4.0,2.5.0)", + org.apache.sshd.client.future;version="[2.4.0,2.5.0)", + org.apache.sshd.client.keyverifier;version="[2.4.0,2.5.0)", + org.apache.sshd.client.session;version="[2.4.0,2.5.0)", + org.apache.sshd.client.subsystem.sftp;version="[2.4.0,2.5.0)", + org.apache.sshd.common;version="[2.4.0,2.5.0)", + org.apache.sshd.common.auth;version="[2.4.0,2.5.0)", + org.apache.sshd.common.channel;version="[2.4.0,2.5.0)", + org.apache.sshd.common.compression;version="[2.4.0,2.5.0)", + org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)", + org.apache.sshd.common.config.keys.loader;version="[2.4.0,2.5.0)", + org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.4.0,2.5.0)", + org.apache.sshd.common.digest;version="[2.4.0,2.5.0)", + org.apache.sshd.common.forward;version="[2.4.0,2.5.0)", + org.apache.sshd.common.future;version="[2.4.0,2.5.0)", + org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)", + org.apache.sshd.common.io;version="[2.4.0,2.5.0)", + org.apache.sshd.common.kex;version="[2.4.0,2.5.0)", + org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)", + org.apache.sshd.common.mac;version="[2.4.0,2.5.0)", + org.apache.sshd.common.random;version="[2.4.0,2.5.0)", + org.apache.sshd.common.session;version="[2.4.0,2.5.0)", + org.apache.sshd.common.session.helpers;version="[2.4.0,2.5.0)", + org.apache.sshd.common.signature;version="[2.4.0,2.5.0)", + org.apache.sshd.common.subsystem.sftp;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.buffer;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.closeable;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.io;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.io.resource;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.logging;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)", + org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)", + org.apache.sshd.server.auth;version="[2.4.0,2.5.0)", org.eclipse.jgit.annotations;version="[6.0.0,6.1.0)", org.eclipse.jgit.errors;version="[6.0.0,6.1.0)", org.eclipse.jgit.fnmatch;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthFactory.java index 2d5991647..e4b3716fc 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthFactory.java @@ -9,8 +9,11 @@ */ package org.eclipse.jgit.internal.transport.sshd; +import java.io.IOException; + import org.apache.sshd.client.auth.AbstractUserAuthFactory; import org.apache.sshd.client.auth.UserAuth; +import org.apache.sshd.client.session.ClientSession; /** * Factory to create {@link GssApiWithMicAuthentication} handlers. @@ -28,7 +31,8 @@ public class GssApiWithMicAuthFactory extends AbstractUserAuthFactory { } @Override - public UserAuth create() { + public UserAuth createUserAuth(ClientSession session) + throws IOException { return new GssApiWithMicAuthentication(); } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java index 0bf203f45..420a1d16e 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java @@ -12,6 +12,7 @@ package org.eclipse.jgit.internal.transport.sshd; import static java.text.MessageFormat.format; import java.io.IOException; +import java.io.StreamCorruptedException; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; @@ -309,18 +310,6 @@ public class JGitClientSession extends ClientSessionImpl { return newNames; } - @Override - protected boolean readIdentification(Buffer buffer) throws IOException { - // Propagate a failure from doReadIdentification. - // TODO: remove for sshd > 2.3.0; its doReadIdentification throws - // StreamCorruptedException instead of IllegalStateException. - try { - return super.readIdentification(buffer); - } catch (IllegalStateException e) { - throw new IOException(e.getLocalizedMessage(), e); - } - } - /** * Reads the RFC 4253, section 4.2 protocol version identification. The * Apache MINA sshd default implementation checks for NUL bytes also in any @@ -336,12 +325,14 @@ public class JGitClientSession extends ClientSessionImpl { * @return the lines read, with the server identification line last, or * {@code null} if no identification line was found and more bytes * are needed - * + * @throws StreamCorruptedException + * if the identification is malformed * @see RFC 4253, * section 4.2 */ @Override - protected List doReadIdentification(Buffer buffer, boolean server) { + protected List doReadIdentification(Buffer buffer, boolean server) + throws StreamCorruptedException { if (server) { // Should never happen. No translation; internal bug. throw new IllegalStateException( @@ -379,12 +370,12 @@ public class JGitClientSession extends ClientSessionImpl { ident.add(line); if (line.startsWith("SSH-")) { //$NON-NLS-1$ if (hasNul) { - throw new IllegalStateException( + throw new StreamCorruptedException( format(SshdText.get().serverIdWithNul, escapeControls(line))); } if (line.length() + eol > 255) { - throw new IllegalStateException( + throw new StreamCorruptedException( format(SshdText.get().serverIdTooLong, escapeControls(line))); } @@ -406,7 +397,7 @@ public class JGitClientSession extends ClientSessionImpl { log.debug(msg); log.debug(buffer.toHex()); } - throw new IllegalStateException(msg); + throw new StreamCorruptedException(msg); } } // Need more data diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthFactory.java index 0326368fc..715f3b8ed 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthFactory.java @@ -9,9 +9,12 @@ */ package org.eclipse.jgit.internal.transport.sshd; +import java.io.IOException; + import org.apache.sshd.client.auth.AbstractUserAuthFactory; -import org.apache.sshd.client.auth.UserAuth; +import org.apache.sshd.client.auth.password.UserAuthPassword; import org.apache.sshd.client.auth.password.UserAuthPasswordFactory; +import org.apache.sshd.client.session.ClientSession; /** * A customized {@link UserAuthPasswordFactory} that creates instance of @@ -27,7 +30,8 @@ public class JGitPasswordAuthFactory extends AbstractUserAuthFactory { } @Override - public UserAuth create() { + public UserAuthPassword createUserAuth(ClientSession session) + throws IOException { return new JGitPasswordAuthentication(); } } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java index 54157448a..4c1b49b67 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java @@ -29,11 +29,10 @@ import java.util.stream.Collectors; import org.apache.sshd.client.ClientBuilder; import org.apache.sshd.client.SshClient; -import org.apache.sshd.client.auth.UserAuth; +import org.apache.sshd.client.auth.UserAuthFactory; import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory; import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; -import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.compression.BuiltinCompressions; import org.apache.sshd.common.config.keys.FilePasswordProvider; import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions; @@ -505,7 +504,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { * @return the non-empty list of factories. */ @NonNull - private List> getUserAuthFactories() { + private List getUserAuthFactories() { // About the order of password and keyboard-interactive, see upstream // bug https://issues.apache.org/jira/projects/SSHD/issues/SSHD-866 . // Password auth doesn't have this problem. diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD index b34ef2a79..b04ac553d 100644 --- a/org.eclipse.jgit.test/BUILD +++ b/org.eclipse.jgit.test/BUILD @@ -20,6 +20,7 @@ HELPERS = glob( "nls/MissingPropertyBundle.java", "nls/NoPropertiesBundle.java", "nls/NonTranslatedBundle.java", + "revwalk/ObjectReachabilityTestCase.java", "revwalk/ReachabilityCheckerTestCase.java", "revwalk/RevQueueTestCase.java", "revwalk/RevWalkTestCase.java", @@ -40,6 +41,7 @@ DATA = [ EXCLUDED = [ PKG + "api/SecurityManagerTest.java", + PKG + "api/SecurityManagerMissingPermissionsTest.java", ] RESOURCES = glob(["resources/**"]) diff --git a/org.eclipse.jgit.test/tests.bzl b/org.eclipse.jgit.test/tests.bzl index f27efccc2..d03031645 100644 --- a/org.eclipse.jgit.test/tests.bzl +++ b/org.eclipse.jgit.test/tests.bzl @@ -42,6 +42,10 @@ def tests(tests): additional_deps = [ "//lib:jsch", ] + if src.endswith("SecurityManagerMissingPermissionsTest.java"): + additional_deps = [ + "//lib:log4j", + ] if src.endswith("JSchSshTest.java"): additional_deps = [ "//lib:jsch", diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks.patch new file mode 100644 index 000000000..44cb309e7 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks.patch @@ -0,0 +1,13 @@ +diff --git a/CopyWithHunks b/CopyResult +similarity index 75% +copy from CopyWithHunks +copy to CopyResult +index 0000000..de98044 +--- a/CopyWithHunks ++++ b/CopyResult +@@ -1,4 +1,4 @@ + line1 +-line2 ++lineB + line3 + line4 diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PostImage new file mode 100644 index 000000000..58d80465c --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PostImage @@ -0,0 +1,4 @@ +line1 +lineB +line3 +line4 diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PreImage new file mode 100644 index 000000000..84275f993 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/CopyWithHunks_PreImage @@ -0,0 +1,4 @@ +line1 +line2 +line3 +line4 diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks.patch new file mode 100644 index 000000000..db543abf5 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks.patch @@ -0,0 +1,4 @@ +diff --git a/RenameNoHunks b/nested/subdir/Renamed +similarity index 100% +rename from RenameNoHunks +rename to nested/subdir/Renamed diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PostImage new file mode 100644 index 000000000..84275f993 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PostImage @@ -0,0 +1,4 @@ +line1 +line2 +line3 +line4 diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PreImage new file mode 100644 index 000000000..84275f993 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameNoHunks_PreImage @@ -0,0 +1,4 @@ +line1 +line2 +line3 +line4 diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks.patch new file mode 100644 index 000000000..06b166f0b --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks.patch @@ -0,0 +1,13 @@ +diff --git a/RenameWithHunks b/nested/subdir/Renamed +similarity index 75% +rename from RenameWithHunks +rename to nested/subdir/Renamed +index 0000000..de98044 +--- a/RenameWithHunks ++++ b/nested/subdir/Renamed +@@ -1,4 +1,4 @@ + line1 +-line2 ++lineB + line3 + line4 diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PostImage new file mode 100644 index 000000000..58d80465c --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PostImage @@ -0,0 +1,4 @@ +line1 +lineB +line3 +line4 diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PreImage new file mode 100644 index 000000000..84275f993 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/RenameWithHunks_PreImage @@ -0,0 +1,4 @@ +line1 +line2 +line3 +line4 diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java index 80bcb19d5..63cd21f59 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java @@ -250,6 +250,36 @@ public class ApplyCommandTest extends RepositoryTestCase { assertFalse(new File(db.getWorkTree(), "NonASCIIDel").exists()); } + @Test + public void testRenameNoHunks() throws Exception { + ApplyResult result = init("RenameNoHunks", true, true); + assertEquals(1, result.getUpdatedFiles().size()); + assertEquals(new File(db.getWorkTree(), "RenameNoHunks"), result.getUpdatedFiles() + .get(0)); + checkFile(new File(db.getWorkTree(), "nested/subdir/Renamed"), + b.getString(0, b.size(), false)); + } + + @Test + public void testRenameWithHunks() throws Exception { + ApplyResult result = init("RenameWithHunks", true, true); + assertEquals(1, result.getUpdatedFiles().size()); + assertEquals(new File(db.getWorkTree(), "RenameWithHunks"), result.getUpdatedFiles() + .get(0)); + checkFile(new File(db.getWorkTree(), "nested/subdir/Renamed"), + b.getString(0, b.size(), false)); + } + + @Test + public void testCopyWithHunks() throws Exception { + ApplyResult result = init("CopyWithHunks", true, true); + assertEquals(1, result.getUpdatedFiles().size()); + assertEquals(new File(db.getWorkTree(), "CopyWithHunks"), result.getUpdatedFiles() + .get(0)); + checkFile(new File(db.getWorkTree(), "CopyResult"), + b.getString(0, b.size(), false)); + } + private static byte[] readFile(String patchFile) throws IOException { final InputStream in = getTestResource(patchFile); if (in == null) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java index 3d0dacab3..b737bbec0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java @@ -44,6 +44,7 @@ import org.eclipse.jgit.submodule.SubmoduleStatusType; import org.eclipse.jgit.submodule.SubmoduleWalk; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.TagOpt; import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.util.SystemReader; import org.junit.Test; @@ -111,6 +112,7 @@ public class CloneCommandTest extends RepositoryTestCase { .size()); assertEquals(new RefSpec("+refs/heads/*:refs/remotes/origin/*"), fetchRefSpec(git2.getRepository())); + assertTagOption(git2.getRepository(), TagOpt.AUTO_FOLLOW); } @Test @@ -801,6 +803,50 @@ public class CloneCommandTest extends RepositoryTestCase { } } + @Test + public void testCloneNoTags() throws IOException, JGitInternalException, + GitAPIException, URISyntaxException { + File directory = createTempDirectory("testCloneRepository"); + CloneCommand command = Git.cloneRepository(); + command.setDirectory(directory); + command.setURI(fileUri()); + command.setNoTags(); + Git git2 = command.call(); + addRepoToClose(git2.getRepository()); + assertNotNull(git2); + assertNotNull(git2.getRepository().resolve("refs/heads/test")); + assertNull(git2.getRepository().resolve("tag-initial")); + assertNull(git2.getRepository().resolve("tag-for-blob")); + assertTagOption(git2.getRepository(), TagOpt.NO_TAGS); + } + + @Test + public void testCloneFollowTags() throws IOException, JGitInternalException, + GitAPIException, URISyntaxException { + File directory = createTempDirectory("testCloneRepository"); + CloneCommand command = Git.cloneRepository(); + command.setDirectory(directory); + command.setURI(fileUri()); + command.setBranch("refs/heads/master"); + command.setBranchesToClone( + Collections.singletonList("refs/heads/master")); + command.setTagOption(TagOpt.FETCH_TAGS); + Git git2 = command.call(); + addRepoToClose(git2.getRepository()); + assertNotNull(git2); + assertNull(git2.getRepository().resolve("refs/heads/test")); + assertNotNull(git2.getRepository().resolve("tag-initial")); + assertNotNull(git2.getRepository().resolve("tag-for-blob")); + assertTagOption(git2.getRepository(), TagOpt.FETCH_TAGS); + } + + private void assertTagOption(Repository repo, TagOpt expectedTagOption) + throws URISyntaxException { + RemoteConfig remoteConfig = new RemoteConfig( + repo.getConfig(), "origin"); + assertEquals(expectedTagOption, remoteConfig.getTagOpt()); + } + private String fileUri() { return "file://" + git.getRepository().getWorkTree().getAbsolutePath(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index 4cc3ca0a5..8084505c1 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -16,6 +16,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; import java.io.File; import java.util.Date; @@ -600,40 +601,63 @@ public class CommitCommandTest extends RepositoryTestCase { } } - @Test - public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception { + private void nonNormalizedIndexTest(boolean executable) throws Exception { + String mode = executable ? "100755" : "100644"; try (Git git = new Git(db)) { // Commit a file with CR/LF into the index FileBasedConfig config = db.getConfig(); config.setString("core", null, "autocrlf", "false"); config.save(); - writeTrashFile("file.txt", "line 1\r\nline 2\r\n"); + File testFile = writeTrashFile("file.txt", "line 1\r\nline 2\r\n"); + if (executable) { + FS.DETECTED.setExecute(testFile, true); + } git.add().addFilepattern("file.txt").call(); git.commit().setMessage("Initial").call(); assertEquals( - "[file.txt, mode:100644, content:line 1\r\nline 2\r\n]", + "[file.txt, mode:" + mode + + ", content:line 1\r\nline 2\r\n]", indexState(CONTENT)); config.setString("core", null, "autocrlf", "true"); config.save(); writeTrashFile("file.txt", "line 1\r\nline 1.5\r\nline 2\r\n"); - writeTrashFile("file2.txt", "new\r\nfile\r\n"); + testFile = writeTrashFile("file2.txt", "new\r\nfile\r\n"); + if (executable) { + FS.DETECTED.setExecute(testFile, true); + } git.add().addFilepattern("file.txt").addFilepattern("file2.txt") .call(); git.commit().setMessage("Second").call(); assertEquals( - "[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]" - + "[file2.txt, mode:100644, content:new\nfile\n]", + "[file.txt, mode:" + mode + + ", content:line 1\r\nline 1.5\r\nline 2\r\n]" + + "[file2.txt, mode:" + mode + + ", content:new\nfile\n]", indexState(CONTENT)); writeTrashFile("file2.txt", "new\r\nfile\r\ncontent\r\n"); git.add().addFilepattern("file2.txt").call(); git.commit().setMessage("Third").call(); assertEquals( - "[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]" - + "[file2.txt, mode:100644, content:new\nfile\ncontent\n]", + "[file.txt, mode:" + mode + + ", content:line 1\r\nline 1.5\r\nline 2\r\n]" + + "[file2.txt, mode:" + mode + + ", content:new\nfile\ncontent\n]", indexState(CONTENT)); } } + @Test + public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception { + nonNormalizedIndexTest(false); + } + + @Test + public void commitExecutableWithAutoCrlfAndNonNormalizedIndex() + throws Exception { + assumeTrue(FS.DETECTED.supportsExecute()); + nonNormalizedIndexTest(true); + } + @Test public void testDeletionConflictWithAutoCrlf() throws Exception { try (Git git = new Git(db)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java index e0d9cbc19..7e0de82d8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java @@ -12,6 +12,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import java.io.File; import java.io.IOException; @@ -21,6 +22,8 @@ import org.eclipse.jgit.api.errors.NoFilepatternException; import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Sets; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.util.FS; import org.junit.Test; public class StatusCommandTest extends RepositoryTestCase { @@ -135,4 +138,26 @@ public class StatusCommandTest extends RepositoryTestCase { assertEquals(Sets.of("a", "D/b", "D/D/d"), stat.getModified()); } } + + @Test + public void testExecutableWithNonNormalizedIndex() throws Exception { + assumeTrue(FS.DETECTED.supportsExecute()); + try (Git git = new Git(db)) { + // Commit a file with CR/LF into the index + FileBasedConfig config = db.getConfig(); + config.setString("core", null, "autocrlf", "false"); + config.save(); + File testFile = writeTrashFile("file.txt", "line 1\r\nline 2\r\n"); + FS.DETECTED.setExecute(testFile, true); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("Initial").call(); + assertEquals( + "[file.txt, mode:100755, content:line 1\r\nline 2\r\n]", + indexState(CONTENT)); + config.setString("core", null, "autocrlf", "true"); + config.save(); + Status status = git.status().call(); + assertTrue("Expected no differences", status.isClean()); + } + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java index 2a2aeb592..a246ac9e9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java @@ -286,6 +286,123 @@ public class MergedReftableTest { } } + @Test + public void nonOverlappedUpdateIndices() throws IOException { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + ReftableWriter writer = new ReftableWriter(buf) + .setMinUpdateIndex(1) + .setMaxUpdateIndex(2) + .begin(); + writer.writeRef(ref("refs/heads/a", 1), 1); + writer.writeRef(ref("refs/heads/b", 2), 2); + writer.finish(); + byte[] base = buf.toByteArray(); + + buf = new ByteArrayOutputStream(); + writer = new ReftableWriter(buf) + .setMinUpdateIndex(3) + .setMaxUpdateIndex(4) + .begin(); + writer.writeRef(ref("refs/heads/a", 10), 3); + writer.writeRef(ref("refs/heads/b", 20), 4); + writer.finish(); + byte[] delta = buf.toByteArray(); + + MergedReftable mr = merge(base, delta); + assertEquals(1, mr.minUpdateIndex()); + assertEquals(4, mr.maxUpdateIndex()); + + try (RefCursor rc = mr.allRefs()) { + assertTrue(rc.next()); + assertEquals("refs/heads/a", rc.getRef().getName()); + assertEquals(id(10), rc.getRef().getObjectId()); + assertEquals(3, rc.getRef().getUpdateIndex()); + + assertTrue(rc.next()); + assertEquals("refs/heads/b", rc.getRef().getName()); + assertEquals(id(20), rc.getRef().getObjectId()); + assertEquals(4, rc.getRef().getUpdateIndex()); + } + } + + @Test + public void overlappedUpdateIndices() throws IOException { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + ReftableWriter writer = new ReftableWriter(buf) + .setMinUpdateIndex(1) + .setMaxUpdateIndex(3) + .begin(); + writer.writeRef(ref("refs/heads/a", 1), 1); + writer.writeRef(ref("refs/heads/b", 2), 3); + writer.finish(); + byte[] base = buf.toByteArray(); + + buf = new ByteArrayOutputStream(); + writer = new ReftableWriter(buf) + .setMinUpdateIndex(2) + .setMaxUpdateIndex(4) + .begin(); + writer.writeRef(ref("refs/heads/a", 10), 2); + writer.writeRef(ref("refs/heads/b", 20), 4); + writer.finish(); + byte[] delta = buf.toByteArray(); + + MergedReftable mr = merge(base, delta); + assertEquals(1, mr.minUpdateIndex()); + assertEquals(4, mr.maxUpdateIndex()); + + try (RefCursor rc = mr.allRefs()) { + assertTrue(rc.next()); + assertEquals("refs/heads/a", rc.getRef().getName()); + assertEquals(id(10), rc.getRef().getObjectId()); + assertEquals(2, rc.getRef().getUpdateIndex()); + + assertTrue(rc.next()); + assertEquals("refs/heads/b", rc.getRef().getName()); + assertEquals(id(20), rc.getRef().getObjectId()); + assertEquals(4, rc.getRef().getUpdateIndex()); + } + } + + @Test + public void enclosedUpdateIndices() throws IOException { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + ReftableWriter writer = new ReftableWriter(buf) + .setMinUpdateIndex(1) + .setMaxUpdateIndex(4) + .begin(); + writer.writeRef(ref("refs/heads/a", 1), 1); + writer.writeRef(ref("refs/heads/b", 20), 4); + writer.finish(); + byte[] base = buf.toByteArray(); + + buf = new ByteArrayOutputStream(); + writer = new ReftableWriter(buf) + .setMinUpdateIndex(2) + .setMaxUpdateIndex(3) + .begin(); + writer.writeRef(ref("refs/heads/a", 10), 2); + writer.writeRef(ref("refs/heads/b", 2), 3); + writer.finish(); + byte[] delta = buf.toByteArray(); + + MergedReftable mr = merge(base, delta); + assertEquals(1, mr.minUpdateIndex()); + assertEquals(4, mr.maxUpdateIndex()); + + try (RefCursor rc = mr.allRefs()) { + assertTrue(rc.next()); + assertEquals("refs/heads/a", rc.getRef().getName()); + assertEquals(id(10), rc.getRef().getObjectId()); + assertEquals(2, rc.getRef().getUpdateIndex()); + + assertTrue(rc.next()); + assertEquals("refs/heads/b", rc.getRef().getName()); + assertEquals(id(20), rc.getRef().getObjectId()); + assertEquals(4, rc.getRef().getUpdateIndex()); + } + } + @Test public void compaction() throws IOException { List delta1 = Arrays.asList( diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java index 032349d5f..7a244e1d8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java @@ -1254,6 +1254,94 @@ public class MergerTest extends RepositoryTestCase { } } + /** + * Merging two commits with a conflict in the virtual ancestor. + * + * Content conflicts while merging the virtual ancestor must be ignored. + * + * In the following tree, while merging A and B, the recursive algorithm + * finds as base commits X and Y and tries to merge them: X deletes file "a" + * and Y modifies it. + * + * Note: we delete "a" in (master) and (second-branch) to make avoid manual + * merges. The situation is the same without those deletions and fixing + * manually the merge of (merge-both-sides) on both branches. + * + *
+	 * A  (second-branch) Merge branch 'merge-both-sides' into second-branch
+	 * |\
+	 * o | Delete modified a
+	 * | |
+	 * | | B (master) Merge branch 'merge-both-sides' (into master)
+	 * | |/|
+	 * | X | (merge-both-sides) Delete original a
+	 * | | |
+	 * | | o Delete modified a
+	 * | |/
+	 * |/|
+	 * Y | Modify a
+	 * |/
+	 * o Initial commit
+	 * 
+ * + * @param strategy + * @throws Exception + */ + @Theory + public void checkMergeConflictInVirtualAncestor( + MergeStrategy strategy) throws Exception { + if (!strategy.equals(MergeStrategy.RECURSIVE)) { + return; + } + + Git git = Git.wrap(db); + + // master + writeTrashFile("a", "aaaaaaaa"); + writeTrashFile("b", "bbbbbbbb"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit first = git.commit().setMessage("Initial commit").call(); + + writeTrashFile("a", "aaaaaaaaaaaaaaa"); + git.add().addFilepattern("a").call(); + RevCommit commitY = git.commit().setMessage("Modify a").call(); + + git.rm().addFilepattern("a").call(); + // Do more in this commits, so it is not identical to the deletion in + // second-branch + writeTrashFile("c", "cccccccc"); + git.add().addFilepattern("c").call(); + git.commit().setMessage("Delete modified a").call(); + + // merge-both-sides: starts before "a" is modified and deletes it + git.checkout().setCreateBranch(true).setStartPoint(first) + .setName("merge-both-sides").call(); + git.rm().addFilepattern("a").call(); + RevCommit commitX = git.commit().setMessage("Delete original a").call(); + + // second branch + git.checkout().setCreateBranch(true).setStartPoint(commitY) + .setName("second-branch").call(); + git.rm().addFilepattern("a").call(); + git.commit().setMessage("Delete modified a").call(); + + // Merge merge-both-sides into second-branch + MergeResult mergeResult = git.merge().include(commitX) + .setStrategy(strategy) + .call(); + ObjectId commitB = mergeResult.getNewHead(); + + // Merge merge-both-sides into master + git.checkout().setName("master").call(); + mergeResult = git.merge().include(commitX).setStrategy(strategy) + .call(); + + // Now, merge commit A and B (i.e. "master" and "second-branch"). + // None of them have the file "a", so there is no conflict, BUT while + // building the virtual ancestor it will find a conflict between Y and X + git.merge().include(commitB).call(); + } + private void writeSubmodule(String path, ObjectId commit) throws IOException, ConfigInvalidException { addSubmoduleToIndex(path, commit); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityTest.java new file mode 100644 index 000000000..d2b6e8916 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.internal.storage.file.GC; +import org.eclipse.jgit.junit.TestRepository; + +public class BitmappedObjectReachabilityTest + extends ObjectReachabilityTestCase { + + @Override + ObjectReachabilityChecker getChecker( + TestRepository repository) throws Exception { + // GC generates the bitmaps + GC gc = new GC(repository.getRepository()); + gc.setAuto(false); + gc.gc(); + + return new BitmappedObjectReachabilityChecker( + repository.getRevWalk().toObjectWalkWithSameObjects()); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java index 4a3b04d4e..c8256b89c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java @@ -163,6 +163,23 @@ public class FirstParentRevWalkTest extends RevWalkTestCase { assertNull(rw.next()); } + @Test + public void testTopoNonIntermixSort() throws Exception { + RevCommit a = commit(); + RevCommit b1 = commit(a); + RevCommit b2 = commit(a); + RevCommit c = commit(b1, b2); + + rw.reset(); + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + rw.setFirstParent(true); + markStart(c); + assertCommit(c, rw.next()); + assertCommit(b1, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + @Test public void testCommitTimeSort() throws Exception { RevCommit a = commit(); @@ -428,4 +445,39 @@ public class FirstParentRevWalkTest extends RevWalkTestCase { assertCommit(c, rw.next()); assertNull(rw.next()); } + + @Test + public void testWithTopoNonIntermixSortAndTreeFilter() throws Exception { + RevCommit a = commit(); + RevCommit b = commit(tree(file("0", blob("b"))), a); + RevCommit c = commit(tree(file("0", blob("c"))), b, a); + RevCommit d = commit(tree(file("0", blob("d"))), c); + + rw.reset(); + rw.setFirstParent(true); + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER, true); + rw.setTreeFilter(PathFilterGroup.createFromStrings("0")); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testWithTopoNonIntermixSortAndTreeFilter2() throws Exception { + RevCommit a = commit(); + RevCommit b = commit(tree(file("0", blob("b"))), a); + RevCommit c = commit(tree(file("0", blob("c"))), a, b); + RevCommit d = commit(tree(file("0", blob("d"))), c); + + rw.reset(); + rw.setFirstParent(true); + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER, true); + rw.setTreeFilter(PathFilterGroup.createFromStrings("0")); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertNull(rw.next()); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectReachabilityTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectReachabilityTestCase.java new file mode 100644 index 000000000..267b163f4 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectReachabilityTestCase.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2020, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.junit.TestRepository.CommitBuilder; +import org.junit.Before; +import org.junit.Test; + +public abstract class ObjectReachabilityTestCase + extends LocalDiskRepositoryTestCase { + + private TestRepository repo; + private AddressableRevCommit baseCommit; + private AddressableRevCommit branchACommit; + private AddressableRevCommit branchBCommit; + private AddressableRevCommit mergeCommit; + + abstract ObjectReachabilityChecker getChecker( + TestRepository repository) throws Exception; + + // Pair of commit and blob inside it + protected static class AddressableRevCommit { + RevCommit commit; + + RevBlob blob; + + AddressableRevCommit(RevCommit commit, RevBlob blob) { + this.commit = commit; + this.blob = blob; + } + } + + /** {@inheritDoc} */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + FileRepository db = createWorkRepository(); + repo = new TestRepository<>(db); + prepareRepo(); + } + + @Test + public void blob_in_base_reachable_from_branches() throws Exception { + ObjectReachabilityChecker checker = getChecker(repo); + + RevObject baseBlob = baseCommit.blob; + assertReachable("reachable from one branch", checker.areAllReachable( + Arrays.asList(baseBlob), Stream.of(branchACommit.commit))); + assertReachable("reachable from another branch", + checker.areAllReachable( + Arrays.asList(baseBlob), + Stream.of(branchBCommit.commit))); + } + + @Test + public void blob_reachable_from_owning_commit() throws Exception { + ObjectReachabilityChecker checker = getChecker(repo); + + RevObject branchABlob = branchACommit.blob; + assertReachable("reachable from itself", + checker.areAllReachable(Arrays.asList(branchABlob), + Stream.of(branchACommit.commit))); + } + + @Test + public void blob_in_branch_reachable_from_merge() throws Exception { + ObjectReachabilityChecker checker = getChecker(repo); + + RevObject branchABlob = branchACommit.blob; + assertReachable("reachable from merge", checker.areAllReachable( + Arrays.asList(branchABlob), Stream.of(mergeCommit.commit))); + } + + @Test + public void blob_unreachable_from_earlier_commit() throws Exception { + ObjectReachabilityChecker checker = getChecker(repo); + + RevObject branchABlob = branchACommit.blob; + assertUnreachable("unreachable from earlier commit", + checker.areAllReachable(Arrays.asList(branchABlob), + Stream.of(baseCommit.commit))); + } + + @Test + public void blob_unreachable_from_parallel_branch() throws Exception { + ObjectReachabilityChecker checker = getChecker(repo); + + RevObject branchABlob = branchACommit.blob; + assertUnreachable("unreachable from another branch", + checker.areAllReachable(Arrays.asList(branchABlob), + Stream.of(branchBCommit.commit))); + } + + private void prepareRepo() throws Exception { + baseCommit = createCommit("base"); + branchACommit = createCommit("branchA", baseCommit); + branchBCommit = createCommit("branchB", baseCommit); + mergeCommit = createCommit("merge", branchACommit, branchBCommit); + + // Bitmaps are generated from references + repo.update("refs/heads/a", branchACommit.commit); + repo.update("refs/heads/b", branchBCommit.commit); + repo.update("refs/heads/merge", mergeCommit.commit); + } + + private AddressableRevCommit createCommit(String blobPath, AddressableRevCommit... parents) throws Exception { + RevBlob blob = repo.blob(blobPath + " content"); + CommitBuilder commitBuilder = repo.commit(); + for (int i = 0; i < parents.length; i++) { + commitBuilder.parent(parents[i].commit); + } + commitBuilder.add(blobPath, blob); + + RevCommit commit = commitBuilder.create(); + return new AddressableRevCommit(commit, blob); + } + + private static void assertReachable(String msg, Optional result) { + assertFalse(msg, result.isPresent()); + } + + private static void assertUnreachable(String msg, Optional result) { + assertTrue(msg, result.isPresent()); + } +} \ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianObjectReachabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianObjectReachabilityTest.java new file mode 100644 index 000000000..b1c9556df --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianObjectReachabilityTest.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.junit.TestRepository; + +public class PedestrianObjectReachabilityTest + extends ObjectReachabilityTestCase { + + @Override + ObjectReachabilityChecker getChecker( + TestRepository repository) + throws Exception { + return new PedestrianObjectReachabilityChecker( + repository.getRevWalk().toObjectWalkWithSameObjects()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkSortTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkSortTest.java index 6f110fa31..8af674773 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkSortTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkSortTest.java @@ -10,9 +10,12 @@ package org.eclipse.jgit.revwalk; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.eclipse.jgit.internal.JGitText; import org.junit.Test; public class RevWalkSortTest extends RevWalkTestCase { @@ -144,4 +147,171 @@ public class RevWalkSortTest extends RevWalkTestCase { assertCommit(d, rw.next()); assertNull(rw.next()); } + + @Test + public void testSort_TOPO_NON_INTERMIX() throws Exception { + // c1 is back dated before its parent. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(-5, b); + final RevCommit c2 = commit(10, b); + final RevCommit d = commit(c1, c2); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(c1, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testSort_TOPO_NON_INTERMIX_OutOfOrderCommitTimes() + throws Exception { + // b is committed before c2 in a different line of history. + // + final RevCommit a = commit(); + final RevCommit c1 = commit(a); + final RevCommit b = commit(a); + final RevCommit c2 = commit(c1); + final RevCommit d = commit(b, c2); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(c1, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testSort_TOPO_NON_INTERMIX_MultipleLinesOfHistory() + throws Exception { + final RevCommit a1 = commit(); + final RevCommit b1 = commit(a1); + final RevCommit a2 = commit(a1, b1); + final RevCommit b2 = commit(b1); + final RevCommit b3 = commit(b1); + final RevCommit a3 = commit(a2, b2); + final RevCommit a4 = commit(a3, b3); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + markStart(a4); + assertCommit(a4, rw.next()); + assertCommit(b3, rw.next()); + assertCommit(a3, rw.next()); + assertCommit(b2, rw.next()); + assertCommit(a2, rw.next()); + assertCommit(b1, rw.next()); + assertCommit(a1, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testSort_TOPO_NON_INTERMIX_REVERSE() throws Exception { + // c1 is back dated before its parent. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(-5, b); + final RevCommit c2 = commit(10, b); + final RevCommit d = commit(c1, c2); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + rw.sort(RevSort.REVERSE, true); + markStart(d); + assertCommit(a, rw.next()); + assertCommit(b, rw.next()); + assertCommit(c1, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(d, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testSort_TOPO_NON_INTERMIX_REVERSE_MultipleLinesOfHistory() + throws Exception { + final RevCommit a1 = commit(); + final RevCommit b1 = commit(a1); + final RevCommit a2 = commit(a1, b1); + final RevCommit b2 = commit(b1); + final RevCommit b3 = commit(b1); + final RevCommit a3 = commit(a2, b2); + final RevCommit a4 = commit(a3, b3); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + rw.sort(RevSort.REVERSE, true); + markStart(a4); + assertCommit(a1, rw.next()); + assertCommit(b1, rw.next()); + assertCommit(a2, rw.next()); + assertCommit(b2, rw.next()); + assertCommit(a3, rw.next()); + assertCommit(b3, rw.next()); + assertCommit(a4, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testSort_TOPO_NON_INTERMIX_ParentOfMultipleStartChildren() + throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(a); + final RevCommit d1 = commit(a); + final RevCommit d2 = commit(d1); + final RevCommit e = commit(a); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + markStart(b); + markStart(c); + markStart(d2); + markStart(e); + assertCommit(e, rw.next()); + assertCommit(d2, rw.next()); + assertCommit(d1, rw.next()); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testSort_TOPO_NON_INTERMIX_Uninteresting() throws Exception { + final RevCommit a1 = commit(); + final RevCommit a2 = commit(a1); + final RevCommit a3 = commit(a2); + final RevCommit b = commit(a1); + final RevCommit a4 = commit(a3, b); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + markStart(a4); + markUninteresting(a2); + assertCommit(a4, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a3, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testSort_TOPO_NON_INTERMIX_and_TOPO_throws() throws Exception { + final RevCommit a = commit(); + + rw.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER); + rw.sort(RevSort.TOPO, true); + markStart(a); + try { + rw.next(); + fail("did not throw IllegalStateException"); + } catch (IllegalStateException e) { + assertEquals( + JGitText.get().cannotCombineTopoSortWithTopoKeepBranchTogetherSort, + e.getMessage()); + } + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java index 6bf8b4c7d..d403624b7 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java @@ -953,6 +953,17 @@ public class URIishTest { assertEquals(-1, u.getPort()); assertNull(u.getUser()); assertEquals("b.txt", u.getHumanishName()); + + u = new URIish("file:/a/test.bundle"); + assertEquals("file", u.getScheme()); + assertFalse(u.isRemote()); + assertNull(u.getHost()); + assertNull(u.getPass()); + assertEquals("/a/test.bundle", u.getRawPath()); + assertEquals("/a/test.bundle", u.getPath()); + assertEquals(-1, u.getPort()); + assertNull(u.getUser()); + assertEquals("test", u.getHumanishName()); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java index ea86563da..d58e57698 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java @@ -44,6 +44,7 @@ import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Sets; import org.eclipse.jgit.lib.TextProgressMonitor; @@ -2238,4 +2239,81 @@ public class UploadPackTest { } } + @Test + public void testSafeToClearRefsInFetchV0() throws Exception { + server = + new RefCallsCountingRepository( + new DfsRepositoryDescription("server")); + remote = new TestRepository<>(server); + RevCommit one = remote.commit().message("1").create(); + remote.update("one", one); + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; + }, null); + uri = testProtocol.register(ctx, server); + try (Transport tn = testProtocol.open(uri, client, "server")) { + tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList(new RefSpec(one.name()))); + } + assertTrue(client.getObjectDatabase().has(one.toObjectId())); + assertEquals(1, ((RefCallsCountingRepository)server).numRefCalls()); + } + + @Test + public void testSafeToClearRefsInFetchV2() throws Exception { + server = + new RefCallsCountingRepository( + new DfsRepositoryDescription("server")); + remote = new TestRepository<>(server); + RevCommit one = remote.commit().message("1").create(); + RevCommit two = remote.commit().message("2").create(); + remote.update("one", one); + remote.update("two", two); + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + ByteArrayInputStream recvStream = uploadPackV2( + "command=fetch\n", + PacketLineIn.delimiter(), + "want-ref refs/heads/one\n", + "want-ref refs/heads/two\n", + "done\n", + PacketLineIn.end()); + PacketLineIn pckIn = new PacketLineIn(recvStream); + assertThat(pckIn.readString(), is("wanted-refs")); + assertThat( + Arrays.asList(pckIn.readString(), pckIn.readString()), + hasItems( + one.toObjectId().getName() + " refs/heads/one", + two.toObjectId().getName() + " refs/heads/two")); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + assertTrue(client.getObjectDatabase().has(one.toObjectId())); + assertEquals(1, ((RefCallsCountingRepository)server).numRefCalls()); + } + + private class RefCallsCountingRepository extends InMemoryRepository { + private final InMemoryRepository.MemRefDatabase refdb; + private int numRefCalls; + + public RefCallsCountingRepository(DfsRepositoryDescription repoDesc) { + super(repoDesc); + refdb = new InMemoryRepository.MemRefDatabase() { + @Override + public List getRefs() throws IOException { + numRefCalls++; + return super.getRefs(); + } + }; + } + + public int numRefCalls() { + return numRefCalls; + } + + @Override + public RefDatabase getRefDatabase() { + return refdb; + } + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java index f9ec5d8d6..2b1fb2ef0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java @@ -78,6 +78,15 @@ public class FileUtilsTest { } } + @Test + public void testDeleteReadOnlyFile() throws IOException { + File f = new File(trash, "f"); + FileUtils.createNewFile(f); + assertTrue(f.setReadOnly()); + FileUtils.delete(f); + assertFalse(f.exists()); + } + @Test public void testDeleteRecursive() throws IOException { File f1 = new File(trash, "test/test/a"); @@ -338,6 +347,34 @@ public class FileUtilsTest { assertFalse(e.exists()); } + @Test + public void testDeleteNonRecursiveTreeNotOk() throws IOException { + File t = new File(trash, "t"); + FileUtils.mkdir(t); + File f = new File(t, "f"); + FileUtils.createNewFile(f); + try { + FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY); + fail("expected failure to delete f"); + } catch (IOException e) { + assertTrue(e.getMessage().endsWith(t.getAbsolutePath())); + } + assertTrue(f.exists()); + assertTrue(t.exists()); + } + + @Test + public void testDeleteNonRecursiveTreeIgnoreError() throws IOException { + File t = new File(trash, "t"); + FileUtils.mkdir(t); + File f = new File(t, "f"); + FileUtils.createNewFile(f); + FileUtils.delete(t, + FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.IGNORE_ERRORS); + assertTrue(f.exists()); + assertTrue(t.exists()); + } + @Test public void testRenameOverNonExistingFile() throws IOException { File d = new File(trash, "d"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java index 254878ae0..33ed360ef 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java @@ -258,6 +258,38 @@ public class HookTest extends RepositoryTestCase { } } + @Test + public void testHookPathWithBlank() throws Exception { + assumeSupportedPlatform(); + + File file = writeHookFile("../../a directory/" + PreCommitHook.NAME, + "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\n" + + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\""); + StoredConfig cfg = db.getConfig(); + cfg.load(); + cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_HOOKS_PATH, + file.getParentFile().getAbsolutePath()); + cfg.save(); + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream err = new ByteArrayOutputStream()) { + ProcessResult res = FS.DETECTED.runHookIfPresent(db, + PreCommitHook.NAME, new String[] { "arg1", "arg2" }, + new PrintStream(out), new PrintStream(err), "stdin"); + + assertEquals("unexpected hook output", + "test arg1 arg2\nstdin\n" + + db.getDirectory().getAbsolutePath() + '\n' + + db.getWorkTree().getAbsolutePath() + '\n', + out.toString("UTF-8")); + assertEquals("unexpected output on stderr stream", "stderr\n", + err.toString("UTF-8")); + assertEquals("unexpected exit code", 0, res.getExitCode()); + assertEquals("unexpected process status", ProcessResult.Status.OK, + res.getStatus()); + } + } + @Test public void testFailedPreCommitHookBlockCommit() throws Exception { assumeSupportedPlatform(); diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index 9df953bec..c8b7bf799 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -1,107 +1,10 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index 1218ee612..c9ca11b54 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -54,6 +54,7 @@ cannotChangeActionOnComment=Cannot change action on comment line in git-rebase-t cannotCheckoutFromUnbornBranch=Cannot check out from unborn branch cannotCheckoutOursSwitchBranch=Checking out ours/theirs is only possible when checking out index, not when switching branches. cannotCombineSquashWithNoff=Cannot combine --squash with --no-ff. +cannotCombineTopoSortWithTopoKeepBranchTogetherSort=Cannot combine sorts TOPO and TOPO_KEEP_BRANCH_TOGETHER cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RevFilter {1}. cannotCommitOnARepoWithState=Cannot commit on a repo with state: {0} cannotCommitWriteTo=Cannot commit write to {0} @@ -302,7 +303,7 @@ flagNotFromThis={0} not from this. flagsAlreadyCreated={0} flags already created. funnyRefname=funny refname gcFailed=Garbage collection failed. -gcTooManyUnpruned=Too many loose, unpruneable objects after garbage collection. Consider adjusting gc.auto or gc.pruneExpire. +gcTooManyUnpruned=Too many loose, unpruneable objects after garbage collection. Consider adjusting gc.auto or gc.pruneExpire. gpgFailedToParseSecretKey=Failed to parse secret key file in directory: {0}. Is the entered passphrase correct? gpgNoCredentialsProvider=missing credentials provider gpgNoKeyring=neither pubring.kbx nor secring.gpg files found diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java index 680f2babc..0d4b3da6a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; +import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.text.MessageFormat; import java.util.ArrayList; @@ -34,7 +35,6 @@ import org.eclipse.jgit.patch.FileHeader; import org.eclipse.jgit.patch.HunkHeader; import org.eclipse.jgit.patch.Patch; import org.eclipse.jgit.util.FileUtils; -import org.eclipse.jgit.util.IO; /** * Apply a patch to files and/or to the index. @@ -114,24 +114,21 @@ public class ApplyCommand extends GitCommand { f = getFile(fh.getOldPath(), false); File dest = getFile(fh.getNewPath(), false); try { + FileUtils.mkdirs(dest.getParentFile(), true); FileUtils.rename(f, dest, StandardCopyOption.ATOMIC_MOVE); } catch (IOException e) { throw new PatchApplyException(MessageFormat.format( JGitText.get().renameFileFailed, f, dest), e); } + apply(dest, fh); break; case COPY: f = getFile(fh.getOldPath(), false); - byte[] bs = IO.readFully(f); - FileOutputStream fos = new FileOutputStream(getFile( - fh.getNewPath(), - true)); - try { - fos.write(bs); - } finally { - fos.close(); - } + File target = getFile(fh.getNewPath(), false); + FileUtils.mkdirs(target.getParentFile(), true); + Files.copy(f.toPath(), target.toPath()); + apply(target, fh); } r.addUpdatedFile(f); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java index c5bc8587e..5d0154c6d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -142,12 +142,14 @@ public class CherryPickCommand extends GitCommand { dco.setProgressMonitor(monitor); dco.checkout(); if (!noCommit) { - newHead = new Git(getRepository()).commit() - .setMessage(srcCommit.getFullMessage()) - .setReflogComment(reflogPrefix + " " //$NON-NLS-1$ - + srcCommit.getShortMessage()) - .setAuthor(srcCommit.getAuthorIdent()) - .setNoVerify(true).call(); + try (Git git = new Git(getRepository())) { + newHead = git.commit() + .setMessage(srcCommit.getFullMessage()) + .setReflogComment(reflogPrefix + " " //$NON-NLS-1$ + + srcCommit.getShortMessage()) + .setAuthor(srcCommit.getAuthorIdent()) + .setNoVerify(true).call(); + } } cherryPickedRefs.add(src); } else { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java index 78afe18f3..30d7f9adc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java @@ -89,6 +89,8 @@ public class CloneCommand extends TransportCommand { private FETCH_TYPE fetchType; + private TagOpt tagOption; + private enum FETCH_TYPE { MULTIPLE_BRANCHES, ALL_BRANCHES, MIRROR } @@ -278,6 +280,9 @@ public class CloneCommand extends TransportCommand { config.setFetchRefSpecs(calculateRefSpecs(fetchType, config.getName())); config.setMirror(fetchType == FETCH_TYPE.MIRROR); + if (tagOption != null) { + config.setTagOpt(tagOption); + } config.update(clonedRepo.getConfig()); clonedRepo.getConfig().save(); @@ -286,7 +291,12 @@ public class CloneCommand extends TransportCommand { FetchCommand command = new FetchCommand(clonedRepo); command.setRemote(remote); command.setProgressMonitor(monitor); - command.setTagOpt(fetchAll ? TagOpt.FETCH_TAGS : TagOpt.AUTO_FOLLOW); + if (tagOption != null) { + command.setTagOpt(tagOption); + } else { + command.setTagOpt( + fetchAll ? TagOpt.FETCH_TAGS : TagOpt.AUTO_FOLLOW); + } configure(command); return command.call(); @@ -663,6 +673,30 @@ public class CloneCommand extends TransportCommand { return this; } + /** + * Set the tag option used for the remote configuration explicitly. + * + * @param tagOption + * tag option to be used for the remote config + * @return {@code this} + * @since 5.8 + */ + public CloneCommand setTagOption(TagOpt tagOption) { + this.tagOption = tagOption; + return this; + } + + /** + * Set the --no-tags option. Tags are not cloned now and the remote + * configuration is initialized with the --no-tags option as well. + * + * @return {@code this} + * @since 5.8 + */ + public CloneCommand setNoTags() { + return setTagOption(TagOpt.NO_TAGS); + } + /** * Set whether to skip checking out a branch * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index 6235dd83d..ec2414d41 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -82,6 +82,7 @@ public class JGitText extends TranslationBundle { /***/ public String cannotCheckoutFromUnbornBranch; /***/ public String cannotCheckoutOursSwitchBranch; /***/ public String cannotCombineSquashWithNoff; + /***/ public String cannotCombineTopoSortWithTopoKeepBranchTogetherSort; /***/ public String cannotCombineTreeFilterWithRevFilter; /***/ public String cannotCommitOnARepoWithState; /***/ public String cannotCommitWriteTo; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java index 18c013fd8..36335153a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java @@ -61,8 +61,16 @@ public class MergedReftable extends Reftable { */ @Override public long maxUpdateIndex() throws IOException { - return tables.length > 0 ? tables[tables.length - 1].maxUpdateIndex() - : 0; + if (tables.length == 0) { + return 0; + } + long maxUpdateIndex = tables[tables.length - 1].maxUpdateIndex(); + for (int i = tables.length - 2; i >= 0; i--) { + if (maxUpdateIndex < tables[i].maxUpdateIndex()) { + maxUpdateIndex = tables[i].maxUpdateIndex(); + } + } + return maxUpdateIndex; } /** @@ -70,8 +78,16 @@ public class MergedReftable extends Reftable { */ @Override public long minUpdateIndex() throws IOException { - return tables.length > 0 ? tables[0].minUpdateIndex() - : 0; + if (tables.length == 0) { + return 0; + } + long minUpdateIndex = tables[0].minUpdateIndex(); + for (int i = 0; i < tables.length - 1; i++) { + if (tables[i].minUpdateIndex() < minUpdateIndex) { + minUpdateIndex = tables[i].minUpdateIndex(); + } + } + return minUpdateIndex; } /** {@inheritDoc} */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java index c5560b97b..b154b95ad 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java @@ -88,8 +88,9 @@ class RefTreeBatch extends BatchRefUpdate { tree = RefTree.read(rw.getObjectReader(), c.getTree()); } else { parentCommitId = ObjectId.zeroId(); - parentTreeId = new ObjectInserter.Formatter() - .idFor(OBJ_TREE, new byte[] {}); + try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) { + parentTreeId = fmt.idFor(OBJ_TREE, new byte[] {}); + } tree = RefTree.newEmptyTree(); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java index e607edc2e..eef822fa4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -542,4 +542,124 @@ public final class ConfigConstants { * @since 5.1.13 */ public static final String CONFIG_JMX_SECTION = "jmx"; + + /** + * The "pack.bigfilethreshold" key + * @since 5.8 + */ + public static final String CONFIG_KEY_BIGFILE_THRESHOLD = "bigfilethreshold"; + + /** + * The "pack.bitmapContiguousCommitCount" key + * @since 5.8 + */ + public static final String CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT = "bitmapcontiguouscommitcount"; + + /** + * The "pack.bitmapDistantCommitSpan" key + * @since 5.8 + */ + public static final String CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN = "bitmapdistantcommitspan"; + + /** + * The "pack.bitmapExcessiveBranchCount" key + * @since 5.8 + */ + public static final String CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT = "bitmapexcessivebranchcount"; + + /** + * The "pack.bitmapInactiveBranchAgeInDays" key + * @since 5.8 + */ + public static final String CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS = "bitmapinactivebranchageindays"; + + /** + * The "pack.bitmapRecentCommitSpan" key + * @since 5.8 + */ + public static final String CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT = "bitmaprecentcommitspan"; + + /** + * The "pack.buildBitmaps" key + * @since 5.8 + */ + public static final String CONFIG_KEY_BUILD_BITMAPS = "buildbitmaps"; + + /** + * The "pack.cutDeltaChains" key + * @since 5.8 + */ + public static final String CONFIG_KEY_CUT_DELTACHAINS = "cutdeltachains"; + + /** + * The "pack.deltaCacheLimit" key + * @since 5.8 + */ + public static final String CONFIG_KEY_DELTA_CACHE_LIMIT = "deltacachelimit"; + + /** + * The "pack.deltaCacheSize" key + * @since 5.8 + */ + public static final String CONFIG_KEY_DELTA_CACHE_SIZE = "deltacachesize"; + + /** + * The "pack.deltaCompression" key + * @since 5.8 + */ + public static final String CONFIG_KEY_DELTA_COMPRESSION = "deltacompression"; + + /** + * The "pack.depth" key + * @since 5.8 + */ + public static final String CONFIG_KEY_DEPTH = "depth"; + + /** + * The "pack.minSizePreventRacyPack" key + * @since 5.8 + */ + public static final String CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK = "minsizepreventracypack"; + + /** + * The "pack.reuseDeltas" key + * @since 5.8 + */ + public static final String CONFIG_KEY_REUSE_DELTAS = "reusedeltas"; + + /** + * The "pack.reuseObjects" key + * @since 5.8 + */ + public static final String CONFIG_KEY_REUSE_OBJECTS = "reuseobjects"; + + /** + * The "pack.singlePack" key + * @since 5.8 + */ + public static final String CONFIG_KEY_SINGLE_PACK = "singlepack"; + + /** + * The "pack.threads" key + * @since 5.8 + */ + public static final String CONFIG_KEY_THREADS = "threads"; + + /** + * The "pack.waitPreventRacyPack" key + * @since 5.8 + */ + public static final String CONFIG_KEY_WAIT_PREVENT_RACYPACK = "waitpreventracypack"; + + /** + * The "pack.window" key + * @since 5.8 + */ + public static final String CONFIG_KEY_WINDOW = "window"; + + /** + * The "pack.windowMemory" key + * @since 5.8 + */ + public static final String CONFIG_KEY_WINDOW_MEMORY = "windowmemory"; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java index 459ca2f7f..92367ebd0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java @@ -385,6 +385,13 @@ public final class Constants { /** A bare repository typically ends with this string */ public static final String DOT_GIT_EXT = ".git"; + /** + * The default extension for local bundle files + * + * @since 5.8 + */ + public static final String DOT_BUNDLE_EXT = ".bundle"; + /** * Name of the attributes file * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java index 575e7bd28..506d33312 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -789,27 +789,37 @@ public class ResolveMerger extends ThreeWayMerger { MergeResult result = contentMerge(base, ours, theirs, attributes); - add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0); - add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0); - DirCacheEntry e = add(tw.getRawPath(), theirs, - DirCacheEntry.STAGE_3, EPOCH, 0); + if (ignoreConflicts) { + // In case a conflict is detected the working tree file is + // again filled with new content (containing conflict + // markers). But also stage 0 of the index is filled with + // that content. + result.setContainsConflicts(false); + updateIndex(base, ours, theirs, result, attributes); + } else { + add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0); + add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0); + DirCacheEntry e = add(tw.getRawPath(), theirs, + DirCacheEntry.STAGE_3, EPOCH, 0); - // OURS was deleted checkout THEIRS - if (modeO == 0) { - // Check worktree before checking out THEIRS - if (isWorktreeDirty(work, ourDce)) - return false; - if (nonTree(modeT)) { - if (e != null) { - addToCheckout(tw.getPathString(), e, attributes); + // OURS was deleted checkout THEIRS + if (modeO == 0) { + // Check worktree before checking out THEIRS + if (isWorktreeDirty(work, ourDce)) { + return false; + } + if (nonTree(modeT)) { + if (e != null) { + addToCheckout(tw.getPathString(), e, attributes); + } } } - } - unmergedPaths.add(tw.getPathString()); + unmergedPaths.add(tw.getPathString()); - // generate a MergeResult for the deleted file - mergeResults.put(tw.getPathString(), result); + // generate a MergeResult for the deleted file + mergeResults.put(tw.getPathString(), result); + } } } return true; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityChecker.java new file mode 100644 index 000000000..89aef7dc4 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityChecker.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; + +/** + * Checks if all objects are reachable from certain starting points using + * bitmaps. + */ +class BitmappedObjectReachabilityChecker + implements ObjectReachabilityChecker { + + private final ObjectWalk walk; + + /** + * New instance of the reachability checker using a existing walk. + * + * @param walk + * ObjectWalk instance to reuse. Caller retains ownership. + */ + public BitmappedObjectReachabilityChecker(ObjectWalk walk) { + this.walk = walk; + } + + /** + * {@inheritDoc} + * + * This implementation tries to shortcut the check adding starters + * incrementally. Ordering the starters by relevance can improve performance + * in the average case. + */ + @Override + public Optional areAllReachable(Collection targets, + Stream starters) throws IOException { + + try { + List remainingTargets = new ArrayList<>(targets); + BitmapWalker bitmapWalker = new BitmapWalker(walk, + walk.getObjectReader().getBitmapIndex(), null); + + Iterator starterIt = starters.iterator(); + BitmapBuilder seen = null; + while (starterIt.hasNext()) { + List asList = Arrays.asList(starterIt.next()); + BitmapBuilder visited = bitmapWalker.findObjects(asList, seen, + true); + seen = seen == null ? visited : seen.or(visited); + + remainingTargets.removeIf(seen::contains); + if (remainingTargets.isEmpty()) { + return Optional.empty(); + } + } + + return Optional.of(remainingTargets.get(0)); + } catch (MissingObjectException | IncorrectObjectTypeException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java index 02514526d..0d9c4593b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java @@ -42,7 +42,7 @@ class BitmappedReachabilityChecker implements ReachabilityChecker { * @throws IOException * if the index or the object reader cannot be opened. */ - public BitmappedReachabilityChecker(RevWalk walk) + BitmappedReachabilityChecker(RevWalk walk) throws IOException { this.walk = walk; if (walk.getObjectReader().getBitmapIndex() == null) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectReachabilityChecker.java new file mode 100644 index 000000000..48e908e88 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectReachabilityChecker.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import java.io.IOException; +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Stream; + +/** + * Checks if all objects are reachable from certain starting points. + * + * This is an expensive check that browses commits, trees, blobs and tags. For + * reachability just between commits see {@link ReachabilityChecker} + * implementations. + * + * @since 5.8 + */ +public interface ObjectReachabilityChecker { + + /** + * Checks that all targets are reachable from the starters. + * + * @implSpec Missing or invalid objects are reported as illegal state. + * Caller should have found them while translating ObjectIds into + * RevObjects. They can only happen here if the caller is mixing + * revwalks. + * + * @param targets + * objects to check for reachability from the starters + * @param starters + * objects known to be reachable to the caller + * @return Optional a single unreachable target if there are any (there + * could be more). Empty optional means all targets are reachable. + * @throws IOException + * Cannot access underlying storage + */ + Optional areAllReachable(Collection targets, + Stream starters) throws IOException; + +} \ No newline at end of file diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java index 04a4b4c63..4c7a6f556 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java @@ -159,6 +159,29 @@ public class ObjectWalk extends RevWalk { pathBuf = new byte[256]; } + /** + * Create an object reachability checker that will use bitmaps if possible. + * + * This reachability checker accepts any object as target. For checks + * exclusively between commits, see + * {@link RevWalk#createReachabilityChecker()}. + * + * @return an object reachability checker, using bitmaps if possible. + * + * @throws IOException + * when the index fails to load. + * + * @since 5.8 + */ + public ObjectReachabilityChecker createObjectReachabilityChecker() + throws IOException { + if (reader.getBitmapIndex() != null) { + return new BitmappedObjectReachabilityChecker(this); + } + + return new PedestrianObjectReachabilityChecker(this); + } + /** * Mark an object or commit to start graph traversal from. *

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianObjectReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianObjectReachabilityChecker.java new file mode 100644 index 000000000..df5d68a66 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianObjectReachabilityChecker.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import java.io.IOException; +import java.io.InvalidObjectException; +import java.util.Collection; +import java.util.Iterator; +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.jgit.errors.MissingObjectException; + +/** + * Checks if all objects are reachable from certain starting points doing a + * walk. + */ +class PedestrianObjectReachabilityChecker implements ObjectReachabilityChecker { + private final ObjectWalk walk; + + /** + * New instance of the reachability checker using a existing walk. + * + * @param walk + * ObjectWalk instance to reuse. Caller retains ownership. + */ + PedestrianObjectReachabilityChecker(ObjectWalk walk) { + this.walk = walk; + } + + /** + * {@inheritDoc} + */ + @Override + public Optional areAllReachable(Collection targets, + Stream starters) throws IOException { + try { + walk.reset(); + walk.sort(RevSort.TOPO); + for (RevObject target : targets) { + walk.markStart(target); + } + + Iterator iterator = starters.iterator(); + while (iterator.hasNext()) { + RevObject o = iterator.next(); + walk.markUninteresting(o); + + RevObject peeled = walk.peel(o); + if (peeled instanceof RevCommit) { + // By default, for performance reasons, ObjectWalk does not + // mark + // a tree as uninteresting when we mark a commit. Mark it + // ourselves so that we can determine reachability exactly. + walk.markUninteresting(((RevCommit) peeled).getTree()); + } + } + + RevCommit commit = walk.next(); + if (commit != null) { + return Optional.of(commit); + } + + RevObject object = walk.nextObject(); + if (object != null) { + return Optional.of(object); + } + + return Optional.empty(); + } catch (MissingObjectException | InvalidObjectException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java index 5ce4bc33b..4d2684a0f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java @@ -152,6 +152,7 @@ public abstract class RevObject extends ObjectIdOwnerMap.Entry { */ protected void appendCoreFlags(StringBuilder s) { s.append((flags & RevWalk.TOPO_DELAY) != 0 ? 'o' : '-'); + s.append((flags & RevWalk.TOPO_QUEUED) != 0 ? 'q' : '-'); s.append((flags & RevWalk.TEMP_MARK) != 0 ? 't' : '-'); s.append((flags & RevWalk.REWRITE) != 0 ? 'r' : '-'); s.append((flags & RevWalk.UNINTERESTING) != 0 ? 'u' : '-'); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevSort.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevSort.java index fc6ae28dc..08396a806 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevSort.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevSort.java @@ -39,6 +39,18 @@ public enum RevSort { */ TOPO, + /** + * Topological sorting (all children before parents) without intermixing + * lines of history. + *

+ * This behavior more closely resembles C Git's git-log --topo-order than + * {@link #TOPO}. See C Git's topo-order description. + * + * @since 5.8 + */ + TOPO_KEEP_BRANCH_TOGETHER, + /** * Flip the output into the reverse ordering. *

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index f425e8761..6b62fcdf6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -131,8 +131,17 @@ public class RevWalk implements Iterable, AutoCloseable { */ static final int TOPO_DELAY = 1 << 5; + /** + * Temporary mark for use within {@link TopoNonIntermixSortGenerator}. + *

+ * This mark indicates the commit has been queued for emission in + * {@link TopoSortGenerator} and can be produced. This mark is removed when + * the commit has been produced. + */ + static final int TOPO_QUEUED = 1 << 6; + /** Number of flag bits we keep internal for our own use. See above flags. */ - static final int RESERVED_FLAGS = 6; + static final int RESERVED_FLAGS = 7; private static final int APP_FLAGS = -1 & ~((1 << RESERVED_FLAGS) - 1); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java index 2c1b0a59e..bfcea6ea8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java @@ -135,8 +135,18 @@ class StartGenerator extends Generator { } if (walker.hasRevSort(RevSort.TOPO) - && (g.outputType() & SORT_TOPO) == 0) + && walker.hasRevSort(RevSort.TOPO_KEEP_BRANCH_TOGETHER)) { + throw new IllegalStateException(JGitText + .get().cannotCombineTopoSortWithTopoKeepBranchTogetherSort); + } + + if (walker.hasRevSort(RevSort.TOPO) + && (g.outputType() & SORT_TOPO) == 0) { g = new TopoSortGenerator(g); + } else if (walker.hasRevSort(RevSort.TOPO_KEEP_BRANCH_TOGETHER) + && (g.outputType() & SORT_TOPO) == 0) { + g = new TopoNonIntermixSortGenerator(g); + } if (walker.hasRevSort(RevSort.REVERSE)) g = new LIFORevQueue(g); if (boundary) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java new file mode 100644 index 000000000..4f6d417ed --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020, Google LLC. and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package org.eclipse.jgit.revwalk; + +import java.io.IOException; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; + +/** Sorts commits in topological order without intermixing lines of history. */ +class TopoNonIntermixSortGenerator extends Generator { + private static final int TOPO_QUEUED = RevWalk.TOPO_QUEUED; + + private final FIFORevQueue pending; + + private final int outputType; + + /** + * Create a new sorter and completely spin the generator. + *

+ * When the constructor completes the supplied generator will have no + * commits remaining, as all of the commits will be held inside of this + * generator's internal buffer. + * + * @param s + * generator to pull all commits out of, and into this buffer. + * @throws MissingObjectException + * @throws IncorrectObjectTypeException + * @throws IOException + */ + TopoNonIntermixSortGenerator(Generator s) throws MissingObjectException, + IncorrectObjectTypeException, IOException { + super(s.firstParent); + pending = new FIFORevQueue(firstParent); + outputType = s.outputType() | SORT_TOPO; + s.shareFreeList(pending); + for (;;) { + final RevCommit c = s.next(); + if (c == null) { + break; + } + if ((c.flags & TOPO_QUEUED) == 0) { + for (RevCommit p : c.parents) { + p.inDegree++; + + if (firstParent) { + break; + } + } + } + c.flags |= TOPO_QUEUED; + pending.add(c); + } + } + + @Override + int outputType() { + return outputType; + } + + @Override + void shareFreeList(BlockRevQueue q) { + q.shareFreeList(pending); + } + + @Override + RevCommit next() throws MissingObjectException, + IncorrectObjectTypeException, IOException { + for (;;) { + final RevCommit c = pending.next(); + if (c == null) { + return null; + } + + if (c.inDegree > 0) { + // At least one of our children is missing. We delay + // production until all of our children are output. + // + continue; + } + + if ((c.flags & TOPO_QUEUED) == 0) { + // c is a parent that already produced or a parent that + // was never in the priority queue and should never produce. + // + continue; + } + + for (RevCommit p : c.parents) { + if (--p.inDegree == 0 && (p.flags & TOPO_QUEUED) != 0) { + // The parent has no unproduced interesting children. unpop + // the parent so it goes right behind this child. This means + // that this parent commit may appear in "pending" more than + // once, but this is safe since upon the second and + // subsequent iterations with this commit, it will no longer + // have TOPO_QUEUED set, and thus will be skipped. + // + pending.unpop(p); + } + if (firstParent) { + break; + } + } + + c.flags &= ~TOPO_QUEUED; + return c; + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java index 553d875bb..d476a0d2f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java @@ -32,7 +32,7 @@ import org.eclipse.jgit.lib.Repository; *

  * new FileRepositoryBuilder() //
  * 		.setGitDir(gitDirArgument) // --git-dir if supplied, no-op if null
- * 		.readEnviroment() // scan environment GIT_* variables
+ * 		.readEnvironment() // scan environment GIT_* variables
  * 		.findGitDir() // scan up the file system tree
  * 		.build()
  * 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java index 259f01175..f76dd2721 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java @@ -11,6 +11,31 @@ package org.eclipse.jgit.storage.pack; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BIGFILE_THRESHOLD; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BUILD_BITMAPS; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_COMPRESSION; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_CUT_DELTACHAINS; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_LIMIT; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_SIZE; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_COMPRESSION; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DEPTH; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_INDEXVERSION; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_DELTAS; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_OBJECTS; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SINGLE_PACK; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_THREADS; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WAIT_PREVENT_RACYPACK; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW_MEMORY; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION; + import java.util.concurrent.Executor; import java.util.zip.Deflater; @@ -1101,52 +1126,63 @@ public class PackConfig { * configuration to read properties from. */ public void fromConfig(Config rc) { - setMaxDeltaDepth(rc.getInt("pack", "depth", getMaxDeltaDepth())); //$NON-NLS-1$ //$NON-NLS-2$ - setDeltaSearchWindowSize(rc.getInt( - "pack", "window", getDeltaSearchWindowSize())); //$NON-NLS-1$ //$NON-NLS-2$ - setDeltaSearchMemoryLimit(rc.getLong( - "pack", "windowmemory", getDeltaSearchMemoryLimit())); //$NON-NLS-1$ //$NON-NLS-2$ - setDeltaCacheSize(rc.getLong( - "pack", "deltacachesize", getDeltaCacheSize())); //$NON-NLS-1$ //$NON-NLS-2$ - setDeltaCacheLimit(rc.getInt( - "pack", "deltacachelimit", getDeltaCacheLimit())); //$NON-NLS-1$ //$NON-NLS-2$ - setCompressionLevel(rc.getInt("pack", "compression", //$NON-NLS-1$ //$NON-NLS-2$ - rc.getInt("core", "compression", getCompressionLevel()))); //$NON-NLS-1$ //$NON-NLS-2$ - setIndexVersion(rc.getInt("pack", "indexversion", getIndexVersion())); //$NON-NLS-1$ //$NON-NLS-2$ - setBigFileThreshold(rc.getInt( - "core", "bigfilethreshold", getBigFileThreshold())); //$NON-NLS-1$ //$NON-NLS-2$ - setThreads(rc.getInt("pack", "threads", getThreads())); //$NON-NLS-1$ //$NON-NLS-2$ + setMaxDeltaDepth(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_DEPTH, + getMaxDeltaDepth())); + setDeltaSearchWindowSize(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_WINDOW, getDeltaSearchWindowSize())); + setDeltaSearchMemoryLimit(rc.getLong(CONFIG_PACK_SECTION, + CONFIG_KEY_WINDOW_MEMORY, getDeltaSearchMemoryLimit())); + setDeltaCacheSize(rc.getLong(CONFIG_PACK_SECTION, + CONFIG_KEY_DELTA_CACHE_SIZE, getDeltaCacheSize())); + setDeltaCacheLimit(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_DELTA_CACHE_LIMIT, getDeltaCacheLimit())); + setCompressionLevel(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_COMPRESSION, rc.getInt(CONFIG_CORE_SECTION, + CONFIG_KEY_COMPRESSION, getCompressionLevel()))); + setIndexVersion(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_INDEXVERSION, + getIndexVersion())); + setBigFileThreshold(rc.getInt(CONFIG_CORE_SECTION, + CONFIG_KEY_BIGFILE_THRESHOLD, getBigFileThreshold())); + setThreads(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_THREADS, + getThreads())); // These variables aren't standardized - // - setReuseDeltas(rc.getBoolean("pack", "reusedeltas", isReuseDeltas())); //$NON-NLS-1$ //$NON-NLS-2$ - setReuseObjects( - rc.getBoolean("pack", "reuseobjects", isReuseObjects())); //$NON-NLS-1$ //$NON-NLS-2$ - setDeltaCompress( - rc.getBoolean("pack", "deltacompression", isDeltaCompress())); //$NON-NLS-1$ //$NON-NLS-2$ - setCutDeltaChains( - rc.getBoolean("pack", "cutdeltachains", getCutDeltaChains())); //$NON-NLS-1$ //$NON-NLS-2$ - setSinglePack( - rc.getBoolean("pack", "singlepack", getSinglePack())); //$NON-NLS-1$ //$NON-NLS-2$ - setBuildBitmaps( - rc.getBoolean("pack", "buildbitmaps", isBuildBitmaps())); //$NON-NLS-1$ //$NON-NLS-2$ - setBitmapContiguousCommitCount( - rc.getInt("pack", "bitmapcontiguouscommitcount", //$NON-NLS-1$ //$NON-NLS-2$ - getBitmapContiguousCommitCount())); - setBitmapRecentCommitCount(rc.getInt("pack", "bitmaprecentcommitcount", //$NON-NLS-1$ //$NON-NLS-2$ + setReuseDeltas(rc.getBoolean(CONFIG_PACK_SECTION, + CONFIG_KEY_REUSE_DELTAS, isReuseDeltas())); + setReuseObjects(rc.getBoolean(CONFIG_PACK_SECTION, + CONFIG_KEY_REUSE_OBJECTS, isReuseObjects())); + setDeltaCompress(rc.getBoolean(CONFIG_PACK_SECTION, + CONFIG_KEY_DELTA_COMPRESSION, isDeltaCompress())); + setCutDeltaChains(rc.getBoolean(CONFIG_PACK_SECTION, + CONFIG_KEY_CUT_DELTACHAINS, getCutDeltaChains())); + setSinglePack(rc.getBoolean(CONFIG_PACK_SECTION, + CONFIG_KEY_SINGLE_PACK, + getSinglePack())); + setBuildBitmaps(rc.getBoolean(CONFIG_PACK_SECTION, + CONFIG_KEY_BUILD_BITMAPS, isBuildBitmaps())); + setBitmapContiguousCommitCount(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT, + getBitmapContiguousCommitCount())); + setBitmapRecentCommitCount(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT, getBitmapRecentCommitCount())); - setBitmapRecentCommitSpan(rc.getInt("pack", "bitmaprecentcommitspan", //$NON-NLS-1$ //$NON-NLS-2$ + setBitmapRecentCommitSpan(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT, getBitmapRecentCommitSpan())); - setBitmapDistantCommitSpan(rc.getInt("pack", "bitmapdistantcommitspan", //$NON-NLS-1$ //$NON-NLS-2$ + setBitmapDistantCommitSpan(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN, getBitmapDistantCommitSpan())); - setBitmapExcessiveBranchCount(rc.getInt("pack", //$NON-NLS-1$ - "bitmapexcessivebranchcount", getBitmapExcessiveBranchCount())); //$NON-NLS-1$ - setBitmapInactiveBranchAgeInDays( - rc.getInt("pack", "bitmapinactivebranchageindays", //$NON-NLS-1$ //$NON-NLS-2$ - getBitmapInactiveBranchAgeInDays())); - setWaitPreventRacyPack(rc.getBoolean("pack", "waitpreventracypack", //$NON-NLS-1$ //$NON-NLS-2$ - isWaitPreventRacyPack())); - setMinSizePreventRacyPack(rc.getLong("pack", "minsizepreventracypack", //$NON-NLS-1$//$NON-NLS-2$ + setBitmapExcessiveBranchCount(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT, + getBitmapExcessiveBranchCount())); + setBitmapInactiveBranchAgeInDays(rc.getInt(CONFIG_PACK_SECTION, + CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS, + getBitmapInactiveBranchAgeInDays())); + setWaitPreventRacyPack(rc.getBoolean(CONFIG_PACK_SECTION, + CONFIG_KEY_WAIT_PREVENT_RACYPACK, isWaitPreventRacyPack())); + setMinSizePreventRacyPack(rc.getLong(CONFIG_PACK_SECTION, + CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK, getMinSizePreventRacyPack())); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java index ec2b76938..8a8c1ae0b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -1814,55 +1814,59 @@ public class ReceivePack { .append(" ("); //$NON-NLS-1$ } - switch (cmd.getResult()) { - case NOT_ATTEMPTED: - r.append("server bug; ref not processed"); //$NON-NLS-1$ - break; - - case REJECTED_NOCREATE: - r.append("creation prohibited"); //$NON-NLS-1$ - break; - - case REJECTED_NODELETE: - r.append("deletion prohibited"); //$NON-NLS-1$ - break; - - case REJECTED_NONFASTFORWARD: - r.append("non-fast forward"); //$NON-NLS-1$ - break; - - case REJECTED_CURRENT_BRANCH: - r.append("branch is currently checked out"); //$NON-NLS-1$ - break; - - case REJECTED_MISSING_OBJECT: + if (cmd.getResult() == Result.REJECTED_MISSING_OBJECT) { if (cmd.getMessage() == null) r.append("missing object(s)"); //$NON-NLS-1$ else if (cmd.getMessage() .length() == Constants.OBJECT_ID_STRING_LENGTH) { + // TODO: Using get/setMessage to store an OID is a + // misuse. The caller should set a full error message. r.append("object "); //$NON-NLS-1$ r.append(cmd.getMessage()); r.append(" missing"); //$NON-NLS-1$ - } else + } else { r.append(cmd.getMessage()); - break; + } + } else if (cmd.getMessage() != null) { + r.append(cmd.getMessage()); + } else { + switch (cmd.getResult()) { + case NOT_ATTEMPTED: + r.append("server bug; ref not processed"); //$NON-NLS-1$ + break; - case REJECTED_OTHER_REASON: - if (cmd.getMessage() == null) + case REJECTED_NOCREATE: + r.append("creation prohibited"); //$NON-NLS-1$ + break; + + case REJECTED_NODELETE: + r.append("deletion prohibited"); //$NON-NLS-1$ + break; + + case REJECTED_NONFASTFORWARD: + r.append("non-fast forward"); //$NON-NLS-1$ + break; + + case REJECTED_CURRENT_BRANCH: + r.append("branch is currently checked out"); //$NON-NLS-1$ + break; + + case REJECTED_OTHER_REASON: r.append("unspecified reason"); //$NON-NLS-1$ - else - r.append(cmd.getMessage()); - break; + break; - case LOCK_FAILURE: - r.append("failed to lock"); //$NON-NLS-1$ - break; + case LOCK_FAILURE: + r.append("failed to lock"); //$NON-NLS-1$ + break; - case OK: - // We shouldn't have reached this case (see 'ok' case - // above). - continue; + case REJECTED_MISSING_OBJECT: + case OK: + // We shouldn't have reached this case (see 'ok' case + // above and if-statement above). + throw new AssertionError(); + } } + if (!reportStatus) { r.append(")"); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java index 356f88d91..c3c1f2a40 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -549,6 +549,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, case HttpConnection.HTTP_MOVED_PERM: case HttpConnection.HTTP_MOVED_TEMP: case HttpConnection.HTTP_SEE_OTHER: + case HttpConnection.HTTP_11_MOVED_PERM: case HttpConnection.HTTP_11_MOVED_TEMP: // SEE_OTHER should actually never be sent by a git server, // and in general should occur only on POST requests. But it @@ -1412,6 +1413,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, case HttpConnection.HTTP_MOVED_PERM: case HttpConnection.HTTP_MOVED_TEMP: + case HttpConnection.HTTP_11_MOVED_PERM: case HttpConnection.HTTP_11_MOVED_TEMP: // SEE_OTHER after a POST doesn't make sense for a git // server, so we don't handle it here and thus we'll diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java index 06520ec4c..c9bb89a43 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java @@ -738,6 +738,12 @@ public class URIish implements Serializable { else if (result.endsWith(Constants.DOT_GIT_EXT)) result = result.substring(0, result.length() - Constants.DOT_GIT_EXT.length()); + if (("file".equals(scheme) || LOCAL_FILE.matcher(s) //$NON-NLS-1$ + .matches()) + && result.endsWith(Constants.DOT_BUNDLE_EXT)) { + result = result.substring(0, + result.length() - Constants.DOT_BUNDLE_EXT.length()); + } return result; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index 35196c6e3..988901526 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -66,8 +66,6 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.pack.CachedPackUriProvider; import org.eclipse.jgit.internal.storage.pack.PackWriter; import org.eclipse.jgit.internal.transport.parser.FirstWant; -import org.eclipse.jgit.lib.BitmapIndex; -import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; @@ -77,15 +75,14 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.AsyncRevObjectQueue; -import org.eclipse.jgit.revwalk.BitmapWalker; import org.eclipse.jgit.revwalk.DepthWalk; +import org.eclipse.jgit.revwalk.ObjectReachabilityChecker; import org.eclipse.jgit.revwalk.ObjectWalk; import org.eclipse.jgit.revwalk.ReachabilityChecker; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevFlag; import org.eclipse.jgit.revwalk.RevFlagSet; import org.eclipse.jgit.revwalk.RevObject; -import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.filter.CommitTimeRevFilter; @@ -298,7 +295,7 @@ public class UploadPack { private boolean sentReady; - /** Objects we sent in our advertisement list, clients can ask for these. */ + /** Objects we sent in our advertisement list. */ private Set advertised; /** Marked on objects the client has asked us to give them. */ @@ -381,8 +378,10 @@ public class UploadPack { /** * Get refs which were advertised to the client. * - * @return all refs which were advertised to the client, or null if - * {@link #setAdvertisedRefs(Map)} has not been called yet. + * @return all refs which were advertised to the client. Only valid during + * the negotiation phase. Will return {@code null} if + * {@link #setAdvertisedRefs(Map)} has not been called yet or if + * {@code #sendPack()} has been called. */ public final Map getAdvertisedRefs() { return refs; @@ -1896,48 +1895,6 @@ public class UploadPack { } } - private static void checkNotAdvertisedWantsUsingBitmap(ObjectReader reader, - BitmapIndex bitmapIndex, List notAdvertisedWants, - Set reachableFrom) throws IOException { - BitmapWalker bitmapWalker = new BitmapWalker(new ObjectWalk(reader), bitmapIndex, null); - BitmapBuilder reachables = bitmapWalker.findObjects(reachableFrom, null, false); - for (ObjectId oid : notAdvertisedWants) { - if (!reachables.contains(oid)) { - throw new WantNotValidException(oid); - } - } - } - - private static void checkReachabilityByWalkingObjects(ObjectWalk walk, - List wants, Set reachableFrom) throws IOException { - - walk.sort(RevSort.TOPO); - for (RevObject want : wants) { - walk.markStart(want); - } - for (ObjectId have : reachableFrom) { - RevObject o = walk.parseAny(have); - walk.markUninteresting(o); - - RevObject peeled = walk.peel(o); - if (peeled instanceof RevCommit) { - // By default, for performance reasons, ObjectWalk does not mark a - // tree as uninteresting when we mark a commit. Mark it ourselves so - // that we can determine reachability exactly. - walk.markUninteresting(((RevCommit) peeled).getTree()); - } - } - - RevCommit commit = walk.next(); - if (commit != null) { - throw new WantNotValidException(commit); - } - RevObject object = walk.nextObject(); - if (object != null) { - throw new WantNotValidException(object); - } - } - private static void checkNotAdvertisedWants(UploadPack up, List notAdvertisedWants, Collection visibleRefs) throws IOException { @@ -1946,7 +1903,6 @@ public class UploadPack { try (RevWalk walk = new RevWalk(reader)) { walk.setRetainBody(false); - Set reachableFrom = refIdSet(visibleRefs); // Missing "wants" throw exception here List wantsAsObjs = objectIdsToRevObjects(walk, notAdvertisedWants); @@ -1959,33 +1915,33 @@ public class UploadPack { boolean repoHasBitmaps = reader.getBitmapIndex() != null; if (!allWantsAreCommits) { - if (!repoHasBitmaps) { - if (up.transferConfig.isAllowFilter()) { - // Use allowFilter as an indication that the server - // operator is willing to pay the cost of these - // reachability checks. - try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) { - checkReachabilityByWalkingObjects(objWalk, - wantsAsObjs, reachableFrom); - } - return; - } - - // If unadvertized non-commits are requested, use - // bitmaps. If there are no bitmaps, instead of - // incurring the expense of a manual walk, reject - // the request. + if (!repoHasBitmaps && !up.transferConfig.isAllowFilter()) { + // Checking unadvertised non-commits without bitmaps + // requires an expensive manual walk. Use allowFilter as an + // indication that the server operator is willing to pay + // this cost. Reject the request otherwise. RevObject nonCommit = wantsAsObjs .stream() .filter(obj -> !(obj instanceof RevCommit)) .limit(1) .collect(Collectors.toList()).get(0); throw new WantNotValidException(nonCommit); + } + try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) { + Stream startersAsObjs = importantRefsFirst(visibleRefs) + .map(UploadPack::refToObjectId) + .map(objId -> objectIdToRevObject(objWalk, objId)) + .filter(Objects::nonNull); // Ignore missing tips + + ObjectReachabilityChecker reachabilityChecker = objWalk + .createObjectReachabilityChecker(); + Optional unreachable = reachabilityChecker + .areAllReachable(wantsAsObjs, startersAsObjs); + if (unreachable.isPresent()) { + throw new WantNotValidException(unreachable.get()); + } } - checkNotAdvertisedWantsUsingBitmap(reader, - reader.getBitmapIndex(), notAdvertisedWants, - reachableFrom); return; } @@ -2053,6 +2009,29 @@ public class UploadPack { } } + /** + * Translate an object id to a RevObject. + * + * @param walk + * walk on the relevant object storage + * @param objectId + * Object Id + * @return RevObject instance or null if the object is missing + */ + @Nullable + private static RevObject objectIdToRevObject(RevWalk walk, + ObjectId objectId) { + if (objectId == null) { + return null; + } + + try { + return walk.parseAny(objectId); + } catch (IOException e) { + return null; + } + } + // Resolve the ObjectIds into RevObjects. Any missing object raises an // exception private static List objectIdsToRevObjects(RevWalk walk, @@ -2205,6 +2184,11 @@ public class UploadPack { } msgOut.flush(); + // Advertised objects and refs are not used from here on and can be + // cleared. + advertised = null; + refs = null; + PackConfig cfg = packConfig; if (cfg == null) cfg = new PackConfig(db); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java index a5f2bc605..c4d086d4b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java @@ -59,13 +59,25 @@ public interface HttpConnection { int HTTP_SEE_OTHER = java.net.HttpURLConnection.HTTP_SEE_OTHER; /** - * HTTP 1.1 additional MOVED_TEMP status code; value = 307. + * HTTP 1.1 additional "temporary redirect" status code; value = 307. * * @see #HTTP_MOVED_TEMP + * @see RFC + * 7231, section 6.4.7: 307 Temporary Redirect * @since 4.9 */ int HTTP_11_MOVED_TEMP = 307; + /** + * HTTP 1.1 additional "permanent redirect" status code; value = 308. + * + * @see #HTTP_MOVED_TEMP + * @see RFC 7538, + * section 3: 308 Permanent Redirect + * @since 5.8 + */ + int HTTP_11_MOVED_PERM = 308; + /** * @see HttpURLConnection#HTTP_NOT_FOUND */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index 2d406bd5b..994af2607 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -1467,7 +1467,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } // Read blob from index and check for CR/LF-delimited text. DirCacheEntry entry = dirCache.getDirCacheEntry(); - if (FileMode.REGULAR_FILE.equals(entry.getFileMode())) { + if ((entry.getRawMode() & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) { ObjectId blobId = entry.getObjectId(); if (entry.getStage() > 0 && entry.getStage() != DirCacheEntry.STAGE_2) { @@ -1484,7 +1484,10 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { break; } if (entry.getStage() == DirCacheEntry.STAGE_2) { - blobId = entry.getObjectId(); + if ((entry.getRawMode() + & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) { + blobId = entry.getObjectId(); + } break; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index 216bf2c33..988953b00 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -1747,7 +1747,7 @@ public abstract class FS { return new ProcessResult(Status.NOT_PRESENT); } String cmd = hookFile.getAbsolutePath(); - ProcessBuilder hookProcess = runInShell(cmd, args); + ProcessBuilder hookProcess = runInShell(shellQuote(cmd), args); hookProcess.directory(runDirectory.getAbsoluteFile()); Map environment = hookProcess.environment(); environment.put(Constants.GIT_DIR_KEY, @@ -1770,6 +1770,21 @@ public abstract class FS { } } + /** + * Quote a string (such as a file system path obtained from a Java + * {@link File} or {@link Path} object) such that it can be passed as first + * argument to {@link #runInShell(String, String[])}. + *

+ * This default implementation returns the string unchanged. + *

+ * + * @param cmd + * the String to quote + * @return the quoted string + */ + String shellQuote(String cmd) { + return cmd; + } /** * Tries to find a hook matching the given one in the given repository. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index a0822001c..c9d2770b1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -228,7 +228,7 @@ public class FS_POSIX extends FS { List argv = new ArrayList<>(4 + args.length); argv.add("sh"); //$NON-NLS-1$ argv.add("-c"); //$NON-NLS-1$ - argv.add("$0 \"$@\""); //$NON-NLS-1$ + argv.add(cmd + " \"$@\""); //$NON-NLS-1$ argv.add(cmd); argv.addAll(Arrays.asList(args)); ProcessBuilder proc = new ProcessBuilder(); @@ -236,6 +236,11 @@ public class FS_POSIX extends FS { return proc; } + @Override + String shellQuote(String cmd) { + return QuotedString.BOURNE.quote(cmd); + } + /** {@inheritDoc} */ @Override public ProcessResult runHookIfPresent(Repository repository, String hookName, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java index 82b2818a4..d53bff78e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java @@ -116,14 +116,19 @@ public class FS_Win32_Cygwin extends FS_Win32 { List argv = new ArrayList<>(4 + args.length); argv.add("sh.exe"); //$NON-NLS-1$ argv.add("-c"); //$NON-NLS-1$ - argv.add("$0 \"$@\""); //$NON-NLS-1$ - argv.add(cmd.replace(File.separatorChar, '/')); + argv.add(cmd + " \"$@\""); //$NON-NLS-1$ + argv.add(cmd); argv.addAll(Arrays.asList(args)); ProcessBuilder proc = new ProcessBuilder(); proc.command(argv); return proc; } + @Override + String shellQuote(String cmd) { + return QuotedString.BOURNE.quote(cmd.replace(File.separatorChar, '/')); + } + /** {@inheritDoc} */ @Override public String relativize(String base, String other) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java index 4831fbb64..c43956e53 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.file.AtomicMoveNotSupportedException; import java.nio.file.CopyOption; +import java.nio.file.DirectoryNotEmptyException; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.LinkOption; @@ -180,21 +181,31 @@ public class FileUtils { } if (delete) { - Throwable t = null; + IOException t = null; Path p = f.toPath(); - try { - Files.delete(p); - return; - } catch (FileNotFoundException e) { - if ((options & (SKIP_MISSING | IGNORE_ERRORS)) == 0) { - throw new IOException(MessageFormat.format( - JGitText.get().deleteFileFailed, - f.getAbsolutePath()), e); + boolean tryAgain; + do { + tryAgain = false; + try { + Files.delete(p); + return; + } catch (NoSuchFileException | FileNotFoundException e) { + handleDeleteException(f, e, options, + SKIP_MISSING | IGNORE_ERRORS); + return; + } catch (DirectoryNotEmptyException e) { + handleDeleteException(f, e, options, IGNORE_ERRORS); + return; + } catch (IOException e) { + if (!f.canWrite()) { + tryAgain = f.setWritable(true); + } + if (!tryAgain) { + t = e; + } } - return; - } catch (IOException e) { - t = e; - } + } while (tryAgain); + if ((options & RETRY) != 0) { for (int i = 1; i < 10; i++) { try { @@ -210,11 +221,15 @@ public class FileUtils { } } } - if ((options & IGNORE_ERRORS) == 0) { - throw new IOException(MessageFormat.format( - JGitText.get().deleteFileFailed, f.getAbsolutePath()), - t); - } + handleDeleteException(f, t, options, IGNORE_ERRORS); + } + } + + private static void handleDeleteException(File f, IOException e, + int allOptions, int checkOptions) throws IOException { + if (e != null && (allOptions & checkOptions) == 0) { + throw new IOException(MessageFormat.format( + JGitText.get().deleteFileFailed, f.getAbsolutePath()), e); } } diff --git a/pom.xml b/pom.xml index 1af99b40a..debe8e2d4 100644 --- a/pom.xml +++ b/pom.xml @@ -151,8 +151,8 @@ 1.8 ${project.build.directory}/META-INF/MANIFEST.MF - 5.6.0.201912101111-r - 2.2.0 + 5.7.0.202003110725-r + 2.4.0 0.1.55 1.1.1 1.1.7 @@ -168,11 +168,11 @@ 4.4.12 1.7.2 1.2.15 - 3.1.1 - 1.6.0 + 3.2.0 + 1.7.0 2.8.2 - 1.64 - 3.1.12.2 + 1.65 + 4.0.0 3.0.0 3.0.0 3.0.0-M4 @@ -234,19 +234,19 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.2 + 3.2.3 org.apache.maven.plugins maven-antrun-plugin - 1.8 + 3.0.0 org.apache.maven.plugins maven-dependency-plugin - 3.1.1 + 3.1.2 @@ -275,7 +275,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + 3.1.0 @@ -341,12 +341,12 @@ org.apache.maven.plugins maven-site-plugin - 3.8.2 + 3.9.0 org.apache.maven.wagon wagon-ssh - 3.3.4 + 3.4.0 @@ -895,7 +895,7 @@ org.eclipse.jdt ecj - 3.20.0 + 3.21.0