Browse Source
* master: Prepare 5.8.0-SNAPSHOT builds JGit v5.8.0.202005061305-m2 Update to bouncycastle 1.65 and orbit I20200506000552 ApplyCommand: use Files#copy to copy file Apply hunks when renaming or copying from patch files Create parent directories when renaming a file in ApplyCommand Reduce BitmappedObjectReachabilityChecker visibility Add missing @since to new API Add missing test source file to the build Upgrade Tycho to 1.7.0 ObjectReachabilityCheckers: Make walk member final Upgrade wagon-ssh to 3.4.0 UploadPack: Use more relevant refs first in object reachability check UploadPack: Refactor to generalize the object reachability checks UploadPack: Use BitmappedReachabilityChecker for not advertised wants revwalk: Introduce bitmap-based object reachability checker Bump Bazel version to 3.1.0 revwalk: Extract ObjectReachabilityChecker interface UploadPack: Extract walk-based reachability check Enable passing java options to jgit command line executable RefTreeBatch: fix unclosed resource warning CherryPickCommand: fix unclosed resource warning URIish: suppress non-localized message warning Always use https to access download.eclipse.org UploadPack: Clear advertised ref map after negotiation Use Map directly in MetaFilter Fix human name for local .bundle files Bazel: Disable SecurityManagerMissingPermissionsTest test Remove double blank from sentence start Upgrade maven-antrun-plugin to 3.0.0 Upgrade maven-shade-plugin to 3.2.3 Remove double blank from sentence start Bump Bazel version to 3.0.0 Scan through all merged reftables for max/min update indices FileUtils: improve delete (Windows) FS.runInShell(): handle quoted filters and hooksPath containing blanks Document gc and pack relevant options Define constants for pack config option keys Fix javadoc typo Upgrade ecj to 3.21.0 ReceivePack: Use error message if set Handle non-normalized index also for executable files Update to org.apache.sshd 2.4.0 Scan through all merged reftables for max/min update indices ResolveMerger: Ignore merge conflicts if asked so Upgrade spotbugs-maven-plugin to 4.0.0 Upgrade maven-javadoc-plugin to 3.2.0 Upgrade maven-dependency-plugin to 3.1.2 tag option for clone command Set baseline for japicmp to 5.7.0.202003110725-r RevWalk: fix bad topo flags error message RevWalk: new topo sort to not mix lines of history Upgrade maven-site-plugin to 3.9.0 Upgrade build-helper-maven-plugin to 3.1.0 Prepare 5.7.1-SNAPSHOT builds JGit v5.7.0.202003110725-r TransportHttp: support HTTP response 308 Permanent Redirect Remove unused API problem filters Change-Id: Ifc0c42fd3881b6026b0dcf7a2eb599e7cdede67e Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>next
Matthias Sohn
5 years ago
99 changed files with 2280 additions and 630 deletions
@ -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. | |
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
||||
|
@ -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 |
||||
} |
@ -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] |
||||
} |
@ -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
|
@ -0,0 +1,4 @@
|
||||
line1 |
||||
lineB |
||||
line3 |
||||
line4 |
@ -0,0 +1,4 @@
|
||||
line1 |
||||
line2 |
||||
line3 |
||||
line4 |
@ -0,0 +1,4 @@
|
||||
diff --git a/RenameNoHunks b/nested/subdir/Renamed
|
||||
similarity index 100%
|
||||
rename from RenameNoHunks
|
||||
rename to nested/subdir/Renamed
|
@ -0,0 +1,4 @@
|
||||
line1 |
||||
line2 |
||||
line3 |
||||
line4 |
@ -0,0 +1,4 @@
|
||||
line1 |
||||
line2 |
||||
line3 |
||||
line4 |
@ -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
|
@ -0,0 +1,4 @@
|
||||
line1 |
||||
lineB |
||||
line3 |
||||
line4 |
@ -0,0 +1,4 @@
|
||||
line1 |
||||
line2 |
||||
line3 |
||||
line4 |
@ -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<FileRepository> repository) throws Exception { |
||||
// GC generates the bitmaps
|
||||
GC gc = new GC(repository.getRepository()); |
||||
gc.setAuto(false); |
||||
gc.gc(); |
||||
|
||||
return new BitmappedObjectReachabilityChecker( |
||||
repository.getRevWalk().toObjectWalkWithSameObjects()); |
||||
} |
||||
|
||||
} |
@ -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<FileRepository> repo; |
||||
private AddressableRevCommit baseCommit; |
||||
private AddressableRevCommit branchACommit; |
||||
private AddressableRevCommit branchBCommit; |
||||
private AddressableRevCommit mergeCommit; |
||||
|
||||
abstract ObjectReachabilityChecker getChecker( |
||||
TestRepository<FileRepository> 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<RevObject> result) { |
||||
assertFalse(msg, result.isPresent()); |
||||
} |
||||
|
||||
private static void assertUnreachable(String msg, Optional<RevObject> result) { |
||||
assertTrue(msg, result.isPresent()); |
||||
} |
||||
} |
@ -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<FileRepository> repository) |
||||
throws Exception { |
||||
return new PedestrianObjectReachabilityChecker( |
||||
repository.getRevWalk().toObjectWalkWithSameObjects()); |
||||
} |
||||
} |
@ -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<RevObject> areAllReachable(Collection<RevObject> targets, |
||||
Stream<RevObject> starters) throws IOException { |
||||
|
||||
try { |
||||
List<RevObject> remainingTargets = new ArrayList<>(targets); |
||||
BitmapWalker bitmapWalker = new BitmapWalker(walk, |
||||
walk.getObjectReader().getBitmapIndex(), null); |
||||
|
||||
Iterator<RevObject> starterIt = starters.iterator(); |
||||
BitmapBuilder seen = null; |
||||
while (starterIt.hasNext()) { |
||||
List<RevObject> 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); |
||||
} |
||||
} |
||||
} |
@ -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<RevObject> areAllReachable(Collection<RevObject> targets, |
||||
Stream<RevObject> starters) throws IOException; |
||||
|
||||
} |
@ -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<RevObject> areAllReachable(Collection<RevObject> targets, |
||||
Stream<RevObject> starters) throws IOException { |
||||
try { |
||||
walk.reset(); |
||||
walk.sort(RevSort.TOPO); |
||||
for (RevObject target : targets) { |
||||
walk.markStart(target); |
||||
} |
||||
|
||||
Iterator<RevObject> 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); |
||||
} |
||||
} |
||||
} |
@ -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. |
||||
* <p> |
||||
* 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; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue