diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2023-02-01 01:31:32 +0100 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2023-02-01 01:31:32 +0100 |
commit | f0c00689fd44b3a415aed615418502a102510212 (patch) | |
tree | 1beff71402f7f4a85e6fab65df1be3dd788a2306 | |
parent | f46f30cdc2de44a0942d6b490286e91421cb2b64 (diff) | |
parent | 580cb13f21ec0685a8a425d75a19a6dd78999acc (diff) | |
download | jgit-f0c00689fd44b3a415aed615418502a102510212.tar.gz jgit-f0c00689fd44b3a415aed615418502a102510212.zip |
Merge branch 'master' into stable-6.5
* master:
Shortcut during git fetch for avoiding looping through all local refs
FetchCommand: fix fetchSubmodules to work on a Ref to a blob
Silence API warnings introduced by I466dcde6
Allow the exclusions of refs prefixes from bitmap
PackWriterBitmapPreparer: do not include annotated tags in bitmap
BatchingProgressMonitor: avoid int overflow when computing percentage
[pgm] Fetch-CLI: add support for shallow
Speedup GC listing objects referenced from reflogs
Re-add servlet-api 4.0 to the target platform
Upgrade maven plugins
Cache trustFolderStat/trustPackedRefsStat value per-instance
Refresh 'objects' dir and retry if a loose object is not found
FileSnapshotTest: Add more MISSING_FILE coverage
Change-Id: I370bc228481864912c3cd88d43e5a70517b1c186
39 files changed, 732 insertions, 89 deletions
diff --git a/Documentation/config-options.md b/Documentation/config-options.md index 9cb3c62a35..612b8456ae 100644 --- a/Documentation/config-options.md +++ b/Documentation/config-options.md @@ -45,7 +45,7 @@ For details on native git options see also the official [git config documentatio | `core.streamFileThreshold` | `50 MiB` | ⃞ | The size threshold beyond which objects must be streamed. | | `core.supportsAtomicFileCreation` | `true` | ⃞ | Whether the filesystem supports atomic file creation. | | `core.symlinks` | Auto detect if filesystem supports symlinks| ✅ | If false, symbolic links are checked out as small plain files that contain the link text. | -| `core.trustFolderStat` | `true` | ⃞ | Whether to trust the pack folder's and packed-refs file's file attributes (Java equivalent of stat command on *nix). When looking for pack files, if `false` JGit will always scan the `.git/objects/pack` folder and if set to `true` it assumes that pack files are unchanged if the file attributes of the pack folder are unchanged. When getting the list of packed refs, if `false` JGit will always read the packed-refs file and if set to `true` it uses the file attributes of the packed-refs file and will only read it if a file attribute has changed. Setting this option to `false` can help to workaround caching issues on NFS, but reduces performance.| +| `core.trustFolderStat` | `true` | ⃞ | Whether to trust the pack folder's, packed-refs file's and loose-objects folder's file attributes (Java equivalent of stat command on *nix). When looking for pack files, if `false` JGit will always scan the `.git/objects/pack` folder and if set to `true` it assumes that pack files are unchanged if the file attributes of the pack folder are unchanged. When getting the list of packed refs, if `false` JGit will always read the packed-refs file and if set to `true` it uses the file attributes of the packed-refs file and will only read it if a file attribute has changed. When looking for loose objects, if `false` and if a loose object is not found, JGit will open and close a stream to `.git/objects` folder (which can refresh its directory listing, at least on some NFS clients) and retry looking for that loose object. Setting this option to `false` can help to workaround caching issues on NFS, but reduces performance. | | `core.trustPackedRefsStat` | `unset` | ⃞ | Whether to trust the file attributes (Java equivalent of stat command on *nix) of the packed-refs file. If `never` JGit will ignore the file attributes of the packed-refs file and always read it. If `always` JGit will trust the file attributes of the packed-refs file and will only read it if a file attribute has changed. `after_open` behaves the same as `always`, except that the packed-refs file is opened and closed before its file attributes are considered. An open/close of the packed-refs file is known to refresh its file attributes, at least on some NFS clients. If `unset`, JGit will use the behavior described in `trustFolderStat`. | | `core.worktree` | Root directory of the working tree if it is not the parent directory of the `.git` directory | ✅ | The path to the root of the working tree. | @@ -87,6 +87,7 @@ Proxy configuration uses the standard Java mechanisms via class `java.net.ProxyS | `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.bitmapExcludedRefsPrefixes` | | ⃞ | The refs prefixes to be excluded when building bitmaps. May be specified more than once to exclude multiple prefixes. | | `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. | diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml index 3e37e8263b..f7ef238a67 100644 --- a/org.eclipse.jgit.benchmarks/pom.xml +++ b/org.eclipse.jgit.benchmarks/pom.xml @@ -56,7 +56,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> - <version>3.0.0-M3</version> + <version>3.1.0</version> <executions> <execution> <id>enforce-maven</id> @@ -76,7 +76,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.8.1</version> + <version>3.10.1</version> <configuration> <encoding>UTF-8</encoding> <release>${java.version}</release> @@ -113,7 +113,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> - <version>3.2.4</version> + <version>3.4.1</version> <executions> <execution> <phase>package</phase> @@ -175,7 +175,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> - <version>3.9.1</version> + <version>4.0.0-M4</version> <dependencies> <dependency><!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> @@ -187,17 +187,17 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-report-plugin</artifactId> - <version>3.0.0-M5</version> + <version>3.0.0-M8</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jxr-plugin</artifactId> - <version>3.1.1</version> + <version>3.3.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> - <version>3.1.1</version> + <version>3.4.2</version> </plugin> </plugins> </pluginManagement> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target index 8f041a2d51..72f96f322d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.17" sequenceNumber="1673448236"> +<target name="jgit-4.17" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target index 8f93f0fcd8..a871c58092 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.18" sequenceNumber="1673448236"> +<target name="jgit-4.18" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target index 88599aa121..819a065862 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.19-staging" sequenceNumber="1673448236"> +<target name="jgit-4.19-staging" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target index 5a8dfae9e3..cd615ff22c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.20" sequenceNumber="1673448236"> +<target name="jgit-4.20" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target index d5ccbc1818..993c93f48c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.21" sequenceNumber="1673448236"> +<target name="jgit-4.21" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target index 04b6af5031..86444a51a6 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.22" sequenceNumber="1673448234"> +<target name="jgit-4.22" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target index a4a3c64735..2c1692f676 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.23" sequenceNumber="1673448234"> +<target name="jgit-4.23" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target index 4fed83f41f..3c296b5c71 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.24" sequenceNumber="1673448234"> +<target name="jgit-4.24" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target index 1a7d8bb08a..ad5d99516a 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.25" sequenceNumber="1673448234"> +<target name="jgit-4.25" sequenceNumber="1673875570"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target index fd1f0b0dea..dce8c5581f 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.26" sequenceNumber="1673448442"> +<target name="jgit-4.26" sequenceNumber="1673875557"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.http" version="10.0.13"/> @@ -14,6 +14,11 @@ <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="jakarta.servlet-api" version="4.0.0"/> + <unit id="jakarta.servlet-api.source" version="4.0.0"/> + <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.10.0.v20221207-1049"/> <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/> <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd index 9fe89e2b35..e1afcff6bc 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd @@ -9,3 +9,8 @@ location jetty-10.0.x "https://download.eclipse.org/oomph/jetty/release/10.0.13/ org.eclipse.jetty.util [10.0.13,10.0.14] org.eclipse.jetty.util.ajax [10.0.13,10.0.14] } + +location jetty-10.0.6 "https://download.eclipse.org/eclipse/jetty/10.0.6/" { + jakarta.servlet-api [4.0.0, 5.0.0) + jakarta.servlet-api.source [4.0.0, 5.0.0) +}
\ No newline at end of file diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 06e968069d..53ca7e3b95 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -24,7 +24,6 @@ <properties> <java.version>11</java.version> <tycho-version>2.7.5</tycho-version> - <tycho-extras-version>${tycho-version}</tycho-extras-version> <target-platform>jgit-4.17</target-platform> </properties> diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java index 4cbd61c692..cbb5bbb9cc 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java @@ -17,14 +17,20 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import java.io.File; +import java.time.Instant; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.MockSystemReader; +import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.CLIRepositoryTestCase; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; @@ -41,10 +47,14 @@ public class CloneTest extends CLIRepositoryTestCase { private Git git; + private TestRepository<Repository> tr; + @Override @Before public void setUp() throws Exception { super.setUp(); + + tr = new TestRepository<>(db); git = new Git(db); } @@ -112,6 +122,22 @@ public class CloneTest extends CLIRepositoryTestCase { return git.commit().setMessage("Initial commit").call(); } + private RevCommit createSecondCommit() throws Exception { + JGitTestUtil.writeTrashFile(db, "Test.txt", "Some change"); + git.add().addFilepattern("Test.txt").call(); + return git.commit() + .setCommitter(new PersonIdent(this.committer, tr.getDate())) + .setMessage("Second commit").call(); + } + + private RevCommit createThirdCommit() throws Exception { + JGitTestUtil.writeTrashFile(db, "change.txt", "another change"); + git.add().addFilepattern("change.txt").call(); + return git.commit() + .setCommitter(new PersonIdent(this.committer, tr.getDate())) + .setMessage("Third commit").call(); + } + @Test public void testCloneEmpty() throws Exception { File gitDir = db.getDirectory(); @@ -203,4 +229,117 @@ public class CloneTest extends CLIRepositoryTestCase { assertEquals("refs/*", fetchRefSpec.getDestination()); assertNotNull(git2.getRepository().exactRef("refs/meta/foo/bar")); } + + @Test + public void testDepth() throws Exception { + createInitialCommit(); + createSecondCommit(); + createThirdCommit(); + + File gitDir = db.getDirectory(); + String sourceURI = gitDir.toURI().toString(); + File target = createTempDirectory("target"); + String cmd = "git clone --depth 1 " + sourceURI + " " + + shellQuote(target.getPath()); + String[] result = execute(cmd); + assertArrayEquals(new String[] { + "Cloning into '" + target.getPath() + "'...", "", "" }, result); + + Git git2 = Git.open(target); + addRepoToClose(git2.getRepository()); + + List<RevCommit> log = StreamSupport + .stream(git2.log().all().call().spliterator(), false) + .collect(Collectors.toList()); + assertEquals(1, log.size()); + RevCommit commit = log.get(0); + assertEquals(Set.of(commit.getId()), + git2.getRepository().getObjectDatabase().getShallowCommits()); + assertEquals("Third commit", commit.getFullMessage()); + assertEquals(0, commit.getParentCount()); + } + + @Test + public void testDepth2() throws Exception { + createInitialCommit(); + createSecondCommit(); + createThirdCommit(); + + File gitDir = db.getDirectory(); + String sourceURI = gitDir.toURI().toString(); + File target = createTempDirectory("target"); + String cmd = "git clone --depth 2 " + sourceURI + " " + + shellQuote(target.getPath()); + String[] result = execute(cmd); + assertArrayEquals(new String[] { + "Cloning into '" + target.getPath() + "'...", "", "" }, result); + + Git git2 = Git.open(target); + addRepoToClose(git2.getRepository()); + + List<RevCommit> log = StreamSupport + .stream(git2.log().all().call().spliterator(), false) + .collect(Collectors.toList()); + assertEquals(2, log.size()); + assertEquals(List.of("Third commit", "Second commit"), log.stream() + .map(RevCommit::getFullMessage).collect(Collectors.toList())); + } + + @Test + public void testCloneRepositoryWithShallowSince() throws Exception { + createInitialCommit(); + tr.tick(30); + RevCommit secondCommit = createSecondCommit(); + tr.tick(45); + createThirdCommit(); + + File gitDir = db.getDirectory(); + String sourceURI = gitDir.toURI().toString(); + File target = createTempDirectory("target"); + String cmd = "git clone --shallow-since=" + + Instant.ofEpochSecond(secondCommit.getCommitTime()).toString() + + " " + sourceURI + " " + shellQuote(target.getPath()); + String[] result = execute(cmd); + assertArrayEquals(new String[] { + "Cloning into '" + target.getPath() + "'...", "", "" }, result); + + Git git2 = Git.open(target); + addRepoToClose(git2.getRepository()); + + List<RevCommit> log = StreamSupport + .stream(git2.log().all().call().spliterator(), false) + .collect(Collectors.toList()); + assertEquals(2, log.size()); + assertEquals(List.of("Third commit", "Second commit"), log.stream() + .map(RevCommit::getFullMessage).collect(Collectors.toList())); + } + + @Test + public void testCloneRepositoryWithShallowExclude() throws Exception { + final RevCommit firstCommit = createInitialCommit(); + final RevCommit secondCommit = createSecondCommit(); + createThirdCommit(); + + File gitDir = db.getDirectory(); + String sourceURI = gitDir.toURI().toString(); + File target = createTempDirectory("target"); + String cmd = "git clone --shallow-exclude=" + + firstCommit.getId().getName() + " --shallow-exclude=" + + secondCommit.getId().getName() + " " + sourceURI + " " + + shellQuote(target.getPath()); + String[] result = execute(cmd); + assertArrayEquals(new String[] { + "Cloning into '" + target.getPath() + "'...", "", "" }, result); + + Git git2 = Git.open(target); + addRepoToClose(git2.getRepository()); + + List<RevCommit> log = StreamSupport + .stream(git2.log().all().call().spliterator(), false) + .collect(Collectors.toList()); + assertEquals(1, log.size()); + assertEquals(List.of("Third commit"), log.stream() + .map(RevCommit::getFullMessage).collect(Collectors.toList())); + } + } diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties index 48f4e857a2..98d711d0ff 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties @@ -137,6 +137,7 @@ metaVar_commitOrTag=COMMIT|TAG metaVar_commitPaths=paths metaVar_configFile=FILE metaVar_connProp=conn.prop +metaVar_depth=<depth> metaVar_diffAlg=ALGORITHM metaVar_directory=DIRECTORY metaVar_extraArgument=ours|theirs @@ -144,6 +145,7 @@ metaVar_file=FILE metaVar_filepattern=filepattern metaVar_gitDir=GIT_DIR metaVar_hostName=HOSTNAME +metaVar_instant=<instant> metaVar_lfsStorage=STORAGE metaVar_linesOfContext=lines metaVar_message=message @@ -168,6 +170,8 @@ metaVar_s3Region=REGION metaVar_s3StorageClass=STORAGE-CLASS metaVar_seconds=SECONDS metaVar_service=SERVICE +metaVar_shallowExclude=<revision> +metaVar_shallowSince=<date> metaVar_tagLocalUser=<GPG key ID> metaVar_tool=TOOL metaVar_treeish=tree-ish @@ -374,6 +378,7 @@ usage_detectRenames=detect renamed files usage_diffAlgorithm=the diff algorithm to use. Currently supported are: 'myers', 'histogram' usage_DiffTool=git difftool is a Git command that allows you to compare and edit files between revisions using common diff tools.\ngit difftool is a frontend to git diff and accepts the same options and arguments. usage_MergeTool=git-mergetool - Run merge conflict resolution tools to resolve merge conflicts.\nUse git mergetool to run one of several merge utilities to resolve merge conflicts. It is typically run after git merge. +usage_depth=Limit fetching to the specified number of commits from the tip of each remote branch history. usage_directoriesToExport=directories to export usage_disableTheServiceInAllRepositories=disable the service in all repositories usage_displayAListOfAllRegisteredJgitCommands=Display a list of all registered jgit commands @@ -447,6 +452,8 @@ usage_resetMixed=Resets the index but not the working tree usage_runLfsStore=Run LFS Store in a given directory usage_S3NoSslVerify=Skip verification of Amazon server certificate and hostname usage_setTheGitRepositoryToOperateOn=set the git repository to operate on +usage_shallowExclude=Deepen or shorten the history of a shallow repository to exclude commits reachable from a specified remote branch or tag. +usage_shallowSince=Deepen or shorten the history of a shallow repository to include all reachable commits after <date>. usage_show=Display one commit usage_showRefNamesMatchingCommits=Show ref names matching commits usage_showPatch=display patch diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java index f28915d3fa..9f9fa8fe99 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java @@ -13,7 +13,10 @@ package org.eclipse.jgit.pgm; import java.io.File; import java.io.IOException; import java.text.MessageFormat; +import java.time.Instant; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; @@ -48,6 +51,15 @@ class Clone extends AbstractFetchCommand implements CloneCommand.Callback { @Option(name = "--quiet", usage = "usage_quiet") private Boolean quiet; + @Option(name = "--depth", metaVar = "metaVar_depth", usage = "usage_depth") + private Integer depth = null; + + @Option(name = "--shallow-since", metaVar = "metaVar_shallowSince", usage = "usage_shallowSince") + private Instant shallowSince = null; + + @Option(name = "--shallow-exclude", metaVar = "metaVar_shallowExclude", usage = "usage_shallowExclude") + private List<String> shallowExcludes = new ArrayList<>(); + @Option(name = "--recurse-submodules", usage = "usage_recurseSubmodules") private boolean cloneSubmodules; @@ -97,6 +109,16 @@ class Clone extends AbstractFetchCommand implements CloneCommand.Callback { .setMirror(isMirror).setNoCheckout(noCheckout).setBranch(branch) .setCloneSubmodules(cloneSubmodules).setTimeout(timeout); + if (depth != null) { + command.setDepth(depth.intValue()); + } + if (shallowSince != null) { + command.setShallowSince(shallowSince); + } + for (String shallowExclude : shallowExcludes) { + command.addShallowExclude(shallowExclude); + } + command.setGitDir(gitdir == null ? null : new File(gitdir)); command.setDirectory(localNameF); boolean msgs = quiet == null || !quiet.booleanValue(); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java index fbce4a5343..2e0c36b287 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java @@ -14,6 +14,8 @@ package org.eclipse.jgit.pgm; import java.io.IOException; import java.text.MessageFormat; +import java.time.Instant; +import java.util.ArrayList; import java.util.List; import org.eclipse.jgit.api.FetchCommand; @@ -62,6 +64,15 @@ class Fetch extends AbstractFetchCommand implements FetchCommand.Callback { @Option(name = "--tags", usage="usage_tags", aliases = { "-t" }) private Boolean tags; + @Option(name = "--depth", metaVar = "metaVar_depth", usage = "usage_depth") + private Integer depth = null; + + @Option(name = "--shallow-since", metaVar = "metaVar_shallowSince", usage = "usage_shallowSince") + private Instant shallowSince = null; + + @Option(name = "--shallow-exclude", metaVar = "metaVar_shallowExclude", usage = "usage_shallowExclude") + private List<String> shallowExcludes = new ArrayList<>(); + @Option(name = "--no-tags", usage = "usage_notags", aliases = { "-n" }) void notags(@SuppressWarnings("unused") final boolean ignored) { @@ -120,6 +131,15 @@ class Fetch extends AbstractFetchCommand implements FetchCommand.Callback { fetch.setTagOpt(tags.booleanValue() ? TagOpt.FETCH_TAGS : TagOpt.NO_TAGS); } + if (depth != null) { + fetch.setDepth(depth.intValue()); + } + if (shallowSince != null) { + fetch.setShallowSince(shallowSince); + } + for (String shallowExclude : shallowExcludes) { + fetch.addShallowExclude(shallowExclude); + } if (0 <= timeout) { fetch.setTimeout(timeout); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java index 490f800c0d..d07268b4c3 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java @@ -214,6 +214,7 @@ public class CLIText extends TranslationBundle { /***/ public String metaVar_filepattern; /***/ public String metaVar_gitDir; /***/ public String metaVar_hostName; + /***/ public String metaVar_instant; /***/ public String metaVar_lfsStorage; /***/ public String metaVar_linesOfContext; /***/ public String metaVar_message; diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java index 5d32e6561c..df0b39b52a 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java @@ -13,6 +13,7 @@ package org.eclipse.jgit.pgm.opt; import java.io.IOException; import java.io.Writer; import java.lang.reflect.Field; +import java.time.Instant; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -55,6 +56,7 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser { registry.registerHandler(RevCommit.class, RevCommitHandler.class); registry.registerHandler(RevTree.class, RevTreeHandler.class); registry.registerHandler(List.class, OptionWithValuesListHandler.class); + registry.registerHandler(Instant.class, InstantHandler.class); } private final Repository db; diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java new file mode 100644 index 0000000000..feee78e9b6 --- /dev/null +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2022, Harald Weiner 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.pgm.opt; + +import java.time.Instant; + +import org.eclipse.jgit.pgm.internal.CLIText; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Parameters; +import org.kohsuke.args4j.spi.Setter; + +/** + * Custom argument handler {@link java.time.Instant} from string values. + * <p> + * Assumes the parser has been initialized with a Repository. + * + * @since 6.5 + */ +public class InstantHandler extends OptionHandler<Instant> { + /** + * Create a new handler for the command name. + * <p> + * This constructor is used only by args4j. + * + * @param parser + * a {@link org.kohsuke.args4j.CmdLineParser} object. + * @param option + * a {@link org.kohsuke.args4j.OptionDef} object. + * @param setter + * a {@link org.kohsuke.args4j.spi.Setter} object. + */ + public InstantHandler(CmdLineParser parser, OptionDef option, + Setter<? super Instant> setter) { + super(parser, option, setter); + } + + /** {@inheritDoc} */ + @Override + public int parseArguments(Parameters params) throws CmdLineException { + Instant instant = Instant.parse(params.getParameter(0)); + setter.addValue(instant); + return 1; + } + + /** {@inheritDoc} */ + @Override + public String getDefaultMetaVariable() { + return CLIText.get().metaVar_instant; + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java index 5e87b8f59f..12773c2405 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java @@ -209,6 +209,20 @@ public class FileSnapshotTest { assertTrue(fs2.equals(fs1)); } + @Test + public void snapshotAndFileMissingIsNotModified() throws Exception { + File doesNotExist = trash.resolve("DOES_NOT_EXIST").toFile(); + FileSnapshot missing = FileSnapshot.save(doesNotExist); + assertFalse(missing.isModified(doesNotExist)); + } + + @Test + public void missingFileEquals() throws Exception { + FileSnapshot missing = FileSnapshot.save( + trash.resolve("DOES_NOT_EXIST").toFile()); + assertTrue(missing.equals(FileSnapshot.MISSING_FILE)); + } + @SuppressWarnings("boxing") @Test public void detectFileModified() throws IOException { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java index bb56c84e8e..0c09ad1510 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java @@ -83,6 +83,40 @@ public class GcCommitSelectionTest extends GcTestCase { } @Test + public void testBitmapDoesNotIncludeAnnotatedTags() throws Exception { + /* + * Make sure that the bitmap generated for the following commit + * graph does not include commit2 because it is not reachable by any + * heads, despite being reachable from tag1 through the annotated-tag1. + * + * refs/heads/main + * ^ + * | + * commit1 <-- commit2 <- annotated-tag1 <- tag1 + * ^ + * | + * commit0 + */ + String mainBranch = "refs/heads/main"; + BranchBuilder bb = tr.branch(mainBranch); + + String commitMsg = "commit msg"; + String fileBody = "file body"; + String tagName = "tag1"; + bb.commit().message(commitMsg + " 1").add("file1", fileBody).create(); + RevCommit commit1 = bb.commit().message(commitMsg + " 2").add("file2", fileBody).create(); + RevCommit commit2 = bb.commit().message(commitMsg + " 3").add("file3", fileBody).create(); + tr.lightweightTag(tagName, tr.tag(tagName, commit2)); + tr.branch(mainBranch).update(commit1); + + gc.setExpireAgeMillis(0); + gc.gc(); + + // Create only 2 bitmaps, for commit0 and commit1, excluding commit2 + assertEquals(2, gc.getStatistics().numberOfBitmaps); + } + + @Test public void testBitmapSpansWithMerges() throws Exception { /* * Commits that are merged. Since 55 is in the oldest history it is @@ -187,6 +221,24 @@ public class GcCommitSelectionTest extends GcTestCase { } @Test + public void testBitmapsForExcludedBranches() throws Exception { + createNewCommitOnNewBranch("main"); + createNewCommitOnNewBranch("other"); + PackConfig packConfig = new PackConfig(); + packConfig.setBitmapExcludedRefsPrefixes(new String[] { "refs/heads/other" }); + gc.setPackConfig(packConfig); + gc.gc(); + assertEquals(1, + gc.getStatistics().numberOfBitmaps); + } + + private void createNewCommitOnNewBranch(String branchName) throws Exception { + BranchBuilder bb = tr.branch("refs/heads/" + branchName); + String msg = "New branch " + branchName; + bb.commit().message(msg).add("some-filename.txt", msg).create(); + } + + @Test public void testSelectionOrderingWithChains() throws Exception { /*- * Create a history like this, where 'N' is the number of seconds from diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/TextProgressMonitorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/TextProgressMonitorTest.java new file mode 100644 index 0000000000..55ca2cdea3 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/TextProgressMonitorTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2023, SAP SE or an SAP affiliate company 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.lib; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class TextProgressMonitorTest { + + private TextProgressMonitor m; + + private ByteArrayOutputStream buf; + + @Before + public void setup() { + buf = new ByteArrayOutputStream(); + m = new TextProgressMonitor( + new OutputStreamWriter(buf, StandardCharsets.UTF_8)); + } + + @Test + public void testSimple() throws Exception { + m.beginTask("task", 10); + for (int i = 0; i < 10; i++) { + m.update(1); + } + m.endTask(); + Assert.assertArrayEquals( + new String[] { "", "task: 10% ( 1/10)", + "task: 20% ( 2/10)", + "task: 30% ( 3/10)", + "task: 40% ( 4/10)", + "task: 50% ( 5/10)", + "task: 60% ( 6/10)", + "task: 70% ( 7/10)", + "task: 80% ( 8/10)", + "task: 90% ( 9/10)", + "task: 100% (10/10)", + "task: 100% (10/10)\n" }, + bufLines()); + } + + @Test + public void testLargeNumbers() throws Exception { + m.beginTask("task", 1_000_000_000); + for (int i = 0; i < 10; i++) { + m.update(100_000_000); + } + m.endTask(); + Assert.assertArrayEquals( + new String[] { "", + "task: 10% ( 100000000/1000000000)", + "task: 20% ( 200000000/1000000000)", + "task: 30% ( 300000000/1000000000)", + "task: 40% ( 400000000/1000000000)", + "task: 50% ( 500000000/1000000000)", + "task: 60% ( 600000000/1000000000)", + "task: 70% ( 700000000/1000000000)", + "task: 80% ( 800000000/1000000000)", + "task: 90% ( 900000000/1000000000)", + "task: 100% (1000000000/1000000000)", + "task: 100% (1000000000/1000000000)\n" }, + bufLines()); + } + + String[] bufLines() throws UnsupportedEncodingException { + String s = new String(buf.toString(StandardCharsets.UTF_8.name())); + return s.split("\r"); + } +} diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index cc152f9047..107b7d5ea3 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -3,6 +3,12 @@ <resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants"> <filter id="1142947843"> <message_arguments> + <message_argument value="5.13.2"/> + <message_argument value="CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES"/> + </message_arguments> + </filter> + <filter id="1142947843"> + <message_arguments> <message_argument value="6.1.1"/> <message_argument value="CONFIG_KEY_TRUST_PACKED_REFS_STAT"/> </message_arguments> @@ -32,4 +38,38 @@ </message_arguments> </filter> </resource> + <resource path="src/org/eclipse/jgit/lib/Repository.java" type="org.eclipse.jgit.lib.Repository"> + <filter id="1142947843"> + <message_arguments> + <message_argument value="5.13.2"/> + <message_argument value="getReflogReader(Ref)"/> + </message_arguments> + </filter> + </resource> + <resource path="src/org/eclipse/jgit/storage/pack/PackConfig.java" type="org.eclipse.jgit.storage.pack.PackConfig"> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.storage.pack.PackConfig"/> + <message_argument value="DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES"/> + </message_arguments> + </filter> + <filter id="1142947843"> + <message_arguments> + <message_argument value="5.13.2"/> + <message_argument value="DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES"/> + </message_arguments> + </filter> + <filter id="1142947843"> + <message_arguments> + <message_argument value="5.13.2"/> + <message_argument value="getBitmapExcludedRefsPrefixes()"/> + </message_arguments> + </filter> + <filter id="1142947843"> + <message_arguments> + <message_argument value="5.13.2"/> + <message_argument value="setBitmapExcludedRefsPrefixes(String[])"/> + </message_arguments> + </filter> + </resource> </component> diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java index e7a8be0432..3c772c2765 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java @@ -151,6 +151,9 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { if (fetchHead == null) { return; } + if (revWalk.parseAny(fetchHead).getType() == Constants.OBJ_BLOB) { + return; + } walk.setTree(revWalk.parseTree(fetchHead)); while (walk.next()) { try (Repository submoduleRepo = walk.getRepository()) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java index 3ebce6c409..3e92cddacd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java @@ -31,6 +31,7 @@ import java.util.Locale; import java.util.Objects; import java.util.Set; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.attributes.AttributesNode; @@ -530,6 +531,12 @@ public class FileRepository extends Repository { return new ReflogReaderImpl(this, ref.getName()); } + @Override + public @NonNull ReflogReader getReflogReader(@NonNull Ref ref) + throws IOException { + return new ReflogReaderImpl(this, ref.getName()); + } + /** {@inheritDoc} */ @Override public AttributesNodeProvider createAttributesNodeProvider() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java index 273d658a13..d41aea4fdd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java @@ -800,6 +800,10 @@ public class GC { Set<ObjectId> tagTargets = new HashSet<>(); Set<ObjectId> indexObjects = listNonHEADIndexObjects(); + Set<ObjectId> refsToExcludeFromBitmap = repo.getRefDatabase() + .getRefsByPrefix(pconfig.getBitmapExcludedRefsPrefixes()) + .stream().map(Ref::getObjectId).collect(Collectors.toSet()); + for (Ref ref : refsBefore) { checkCancelled(); nonHeads.addAll(listRefLogObjects(ref, 0)); @@ -844,7 +848,7 @@ public class GC { Pack heads = null; if (!allHeadsAndTags.isEmpty()) { heads = writePack(allHeadsAndTags, PackWriter.NONE, allTags, - tagTargets, excluded); + refsToExcludeFromBitmap, tagTargets, excluded); if (heads != null) { ret.add(heads); excluded.add(0, heads.getIndex()); @@ -852,13 +856,13 @@ public class GC { } if (!nonHeads.isEmpty()) { Pack rest = writePack(nonHeads, allHeadsAndTags, PackWriter.NONE, - tagTargets, excluded); + PackWriter.NONE, tagTargets, excluded); if (rest != null) ret.add(rest); } if (!txnHeads.isEmpty()) { Pack txn = writePack(txnHeads, PackWriter.NONE, PackWriter.NONE, - null, excluded); + PackWriter.NONE, null, excluded); if (txn != null) ret.add(txn); } @@ -1127,10 +1131,7 @@ public class GC { * @throws IOException */ private Set<ObjectId> listRefLogObjects(Ref ref, long minTime) throws IOException { - ReflogReader reflogReader = repo.getReflogReader(ref.getName()); - if (reflogReader == null) { - return Collections.emptySet(); - } + ReflogReader reflogReader = repo.getReflogReader(ref); List<ReflogEntry> rlEntries = reflogReader .getReverseEntries(); if (rlEntries == null || rlEntries.isEmpty()) @@ -1234,6 +1235,7 @@ public class GC { private Pack writePack(@NonNull Set<? extends ObjectId> want, @NonNull Set<? extends ObjectId> have, @NonNull Set<ObjectId> tags, + @NonNull Set<ObjectId> excludedRefsTips, Set<ObjectId> tagTargets, List<ObjectIdSet> excludeObjects) throws IOException { checkCancelled(); @@ -1265,7 +1267,8 @@ public class GC { if (excludeObjects != null) for (ObjectIdSet idx : excludeObjects) pw.excludeObjects(idx); - pw.preparePack(pm, want, have, PackWriter.NONE, tags); + pw.preparePack(pm, want, have, PackWriter.NONE, + union(tags, excludedRefsTips)); if (pw.getObjectCount() == 0) return null; checkCancelled(); @@ -1378,6 +1381,15 @@ public class GC { } } + private Set<? extends ObjectId> union(Set<ObjectId> tags, + Set<ObjectId> excludedRefsHeadsTips) { + HashSet<ObjectId> unionSet = new HashSet<>( + tags.size() + excludedRefsHeadsTips.size()); + unionSet.addAll(tags); + unionSet.addAll(excludedRefsHeadsTips); + return unionSet; + } + private void checkCancelled() throws CancelledException { if (pm.isCancelled() || Thread.currentThread().isInterrupted()) { throw new CancelledException(JGitText.get().operationCanceled); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java index 33621a1e9f..b9af83d24d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java @@ -14,6 +14,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.StandardCopyOption; @@ -24,6 +25,8 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.FileObjectDatabase.InsertLooseObjectResult; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; @@ -52,15 +55,22 @@ class LooseObjects { private final UnpackedObjectCache unpackedObjectCache; + private final boolean trustFolderStat; + /** * Initialize a reference to an on-disk object directory. * + * @param config + * configuration for the loose objects handler. * @param dir * the location of the <code>objects</code> directory. */ - LooseObjects(File dir) { + LooseObjects(Config config, File dir) { directory = dir; unpackedObjectCache = new UnpackedObjectCache(); + trustFolderStat = config.getBoolean( + ConfigConstants.CONFIG_CORE_SECTION, + ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); } /** @@ -98,6 +108,19 @@ class LooseObjects { * @return {@code true} if the specified object is stored as a loose object. */ boolean has(AnyObjectId objectId) { + boolean exists = hasWithoutRefresh(objectId); + if (trustFolderStat || exists) { + return exists; + } + try (InputStream stream = Files.newInputStream(directory.toPath())) { + // refresh directory to work around NFS caching issue + } catch (IOException e) { + return false; + } + return hasWithoutRefresh(objectId); + } + + private boolean hasWithoutRefresh(AnyObjectId objectId) { return fileFor(objectId).exists(); } @@ -183,6 +206,22 @@ class LooseObjects { */ ObjectLoader getObjectLoader(WindowCursor curs, File path, AnyObjectId id) throws IOException { + try { + return getObjectLoaderWithoutRefresh(curs, path, id); + } catch (FileNotFoundException e) { + if (trustFolderStat) { + throw e; + } + try (InputStream stream = Files + .newInputStream(directory.toPath())) { + // refresh directory to work around NFS caching issues + } + return getObjectLoaderWithoutRefresh(curs, path, id); + } + } + + private ObjectLoader getObjectLoaderWithoutRefresh(WindowCursor curs, + File path, AnyObjectId id) throws IOException { try (FileInputStream in = new FileInputStream(path)) { unpackedObjectCache().add(id); return UnpackedObject.open(in, path, id, curs); @@ -203,16 +242,34 @@ class LooseObjects { } long getSize(WindowCursor curs, AnyObjectId id) throws IOException { + try { + return getSizeWithoutRefresh(curs, id); + } catch (FileNotFoundException noFile) { + try { + if (trustFolderStat) { + throw noFile; + } + try (InputStream stream = Files + .newInputStream(directory.toPath())) { + // refresh directory to work around NFS caching issue + } + return getSizeWithoutRefresh(curs, id); + } catch (FileNotFoundException e) { + if (fileFor(id).exists()) { + throw noFile; + } + unpackedObjectCache().remove(id); + return -1; + } + } + } + + private long getSizeWithoutRefresh(WindowCursor curs, AnyObjectId id) + throws IOException { File f = fileFor(id); try (FileInputStream in = new FileInputStream(f)) { unpackedObjectCache().add(id); return UnpackedObject.getSize(in, id, curs); - } catch (FileNotFoundException noFile) { - if (f.exists()) { - throw noFile; - } - unpackedObjectCache().remove(id); - return -1; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java index 6be3620856..e34167450d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java @@ -126,7 +126,7 @@ public class ObjectDirectory extends FileObjectDatabase { File packDirectory = new File(objects, "pack"); //$NON-NLS-1$ File preservedDirectory = new File(packDirectory, "preserved"); //$NON-NLS-1$ alternatesFile = new File(objects, Constants.INFO_ALTERNATES); - loose = new LooseObjects(objects); + loose = new LooseObjects(config, objects); packed = new PackDirectory(config, packDirectory); preserved = new PackDirectory(config, preservedDirectory); fileCommitGraph = new FileCommitGraph(objects); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java index f32909f44d..a7f28c6778 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java @@ -63,12 +63,12 @@ class PackDirectory { private static final PackList NO_PACKS = new PackList(FileSnapshot.DIRTY, new Pack[0]); - private final Config config; - private final File directory; private final AtomicReference<PackList> packList; + private final boolean trustFolderStat; + /** * Initialize a reference to an on-disk 'pack' directory. * @@ -78,9 +78,16 @@ class PackDirectory { * the location of the {@code pack} directory. */ PackDirectory(Config config, File directory) { - this.config = config; this.directory = directory; packList = new AtomicReference<>(NO_PACKS); + + // Whether to trust the pack folder's modification time. If set to false + // we will always scan the .git/objects/pack folder to check for new + // pack files. If set to true (default) we use the folder's size, + // modification time, and key (inode) and assume that no new pack files + // can be in this folder if these attributes have not changed. + trustFolderStat = config.getBoolean(ConfigConstants.CONFIG_CORE_SECTION, + ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); } /** @@ -331,16 +338,6 @@ class PackDirectory { } boolean searchPacksAgain(PackList old) { - // Whether to trust the pack folder's modification time. If set - // to false we will always scan the .git/objects/pack folder to - // check for new pack files. If set to true (default) we use the - // lastmodified attribute of the folder and assume that no new - // pack files can be in this folder if his modification time has - // not changed. - boolean trustFolderStat = config.getBoolean( - ConfigConstants.CONFIG_CORE_SECTION, - ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); - return ((!trustFolderStat) || old.snapshot.isModified(directory)) && old != scanPacks(old); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java index 38930c302f..7f8f56bba8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java @@ -174,6 +174,10 @@ public class RefDirectory extends RefDatabase { private List<Integer> retrySleepMs = RETRY_SLEEP_MS; + private final boolean trustFolderStat; + + private final TrustPackedRefsStat trustPackedRefsStat; + RefDirectory(FileRepository db) { final FS fs = db.getFS(); parent = db; @@ -185,6 +189,13 @@ public class RefDirectory extends RefDatabase { looseRefs.set(RefList.<LooseRef> emptyList()); packedRefs.set(NO_PACKED_REFS); + trustFolderStat = db.getConfig() + .getBoolean(ConfigConstants.CONFIG_CORE_SECTION, + ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); + trustPackedRefsStat = db.getConfig() + .getEnum(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_TRUST_PACKED_REFS_STAT, + TrustPackedRefsStat.UNSET); } Repository getRepository() { @@ -886,16 +897,6 @@ public class RefDirectory extends RefDatabase { } PackedRefList getPackedRefs() throws IOException { - boolean trustFolderStat = getRepository().getConfig().getBoolean( - ConfigConstants.CONFIG_CORE_SECTION, - ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); - TrustPackedRefsStat trustPackedRefsStat = - getRepository().getConfig().getEnum( - ConfigConstants.CONFIG_CORE_SECTION, - null, - ConfigConstants.CONFIG_KEY_TRUST_PACKED_REFS_STAT, - TrustPackedRefsStat.UNSET); - final PackedRefList curList = packedRefs.get(); switch (trustPackedRefsStat) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java index 771d574bd4..5a18f1e567 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java @@ -408,6 +408,9 @@ class PackWriterBitmapPreparer { List<RevCommit> newWantsByNewest = new ArrayList<>(want.size()); Set<RevCommit> newWants = new HashSet<>(want.size()); for (AnyObjectId objectId : want) { + if(excludeFromBitmapSelection.contains(objectId)) { + continue; + } RevObject ro = rw.peel(rw.parseAny(objectId)); if (!(ro instanceof RevCommit) || reuse.contains(ro) || excludeFromBitmapSelection.contains(ro)) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java index 2caefa4d97..49e295aed8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java @@ -176,7 +176,7 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { } } else { // Display once per second or when 1% is done. - int currPercent = lastWork * 100 / totalWork; + int currPercent = Math.round(lastWork * 100F / totalWork); if (display) { pm.onUpdate(taskName, lastWork, totalWork, currPercent); output = true; @@ -201,8 +201,8 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { if (totalWork == UNKNOWN) { pm.onEndTask(taskName, lastWork); } else { - int pDone = lastWork * 100 / totalWork; - pm.onEndTask(taskName, lastWork, totalWork, pDone); + int currPercent = Math.round(lastWork * 100F / totalWork); + pm.onEndTask(taskName, lastWork, totalWork, currPercent); } } if (timerFuture != null) 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 f63f31041e..ed4bf315e2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -721,6 +721,12 @@ public final class ConfigConstants { public static final String CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT = "bitmapexcessivebranchcount"; /** + * The "pack.bitmapExcludedRefsPrefixes" key + * @since 5.13.2 + */ + public static final String CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES = "bitmapexcludedrefsprefixes"; + + /** * The "pack.bitmapInactiveBranchAgeInDays" key * @since 5.8 */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index e594e528be..db2571c673 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -1695,6 +1695,22 @@ public abstract class Repository implements AutoCloseable { throws IOException; /** + * Get the reflog reader. Subclasses should override this method and provide + * a more efficient implementation. + * + * @param ref + * a Ref + * @return a {@link org.eclipse.jgit.lib.ReflogReader} for the supplied ref, + * or {@code null} if the ref does not exist. + * @throws IOException + * @since 5.13.2 + */ + public @Nullable ReflogReader getReflogReader(@NonNull Ref ref) + throws IOException { + return getReflogReader(ref.getName()); + } + + /** * Return the information stored in the file $GIT_DIR/MERGE_MSG. In this * file operations triggering a merge will store a template for the commit * message of the merge commit. 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 6aa8be642d..a10f6cf88a 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 @@ -16,6 +16,7 @@ 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_EXCLUDED_REFS_PREFIXES; 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; @@ -226,6 +227,14 @@ public class PackConfig { public static final int DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS = 90; /** + * Default refs prefixes excluded from the calculation of pack bitmaps. + * + * @see #setBitmapExcludedRefsPrefixes(String[]) + * @since 5.13.2 + */ + public static final String[] DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES = new String[0]; + + /** * Default max time to spend during the search for reuse phase. This * optimization is disabled by default: {@value} * @@ -285,6 +294,8 @@ public class PackConfig { private int bitmapInactiveBranchAgeInDays = DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS; + private String[] bitmapExcludedRefsPrefixes = DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES; + private Duration searchForReuseTimeout = DEFAULT_SEARCH_FOR_REUSE_TIMEOUT; private boolean cutDeltaChains; @@ -1145,6 +1156,27 @@ public class PackConfig { } /** + * Get the refs prefixes excluded from the Bitmap. + * + * @return the refs prefixes excluded from the Bitmap. + * @since 5.13.2 + */ + public String[] getBitmapExcludedRefsPrefixes() { + return bitmapExcludedRefsPrefixes; + } + + /** + * Set the refs prefixes excluded from the Bitmap. + * + * @param excludedRefsPrefixes + * the refs prefixes excluded from the Bitmap. + * @since 5.13.2 + */ + public void setBitmapExcludedRefsPrefixes(String[] excludedRefsPrefixes) { + bitmapExcludedRefsPrefixes = excludedRefsPrefixes; + } + + /** * Set the max time to spend during the search for reuse phase. * * @param timeout @@ -1220,6 +1252,12 @@ public class PackConfig { setBitmapInactiveBranchAgeInDays(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS, getBitmapInactiveBranchAgeInDays())); + String[] excludedRefsPrefixesArray = rc.getStringList(CONFIG_PACK_SECTION, + null, + CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES); + if(excludedRefsPrefixesArray.length > 0) { + setBitmapExcludedRefsPrefixes(excludedRefsPrefixesArray); + } setSearchForReuseTimeout(Duration.ofSeconds(rc.getTimeUnit( CONFIG_PACK_SECTION, null, CONFIG_KEY_SEARCH_FOR_REUSE_TIMEOUT, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index 28c3b6a0fa..e0eb126440 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -47,6 +47,7 @@ import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.revwalk.ObjectWalk; +import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.util.StringUtils; @@ -387,11 +388,19 @@ class FetchProcess { private boolean askForIsComplete() throws TransportException { try { try (ObjectWalk ow = new ObjectWalk(transport.local)) { - for (ObjectId want : askFor.keySet()) - ow.markStart(ow.parseAny(want)); - for (Ref ref : localRefs().values()) - ow.markUninteresting(ow.parseAny(ref.getObjectId())); - ow.checkConnectivity(); + boolean hasCommitObject = false; + for (ObjectId want : askFor.keySet()) { + RevObject obj = ow.parseAny(want); + ow.markStart(obj); + hasCommitObject |= obj.getType() == Constants.OBJ_COMMIT; + } + // Checking connectivity makes sense on commits only + if (hasCommitObject) { + for (Ref ref : localRefs().values()) { + ow.markUninteresting(ow.parseAny(ref.getObjectId())); + } + ow.checkConnectivity(); + } } return transport.getDepth() == null; // if depth is set we need to request objects that are already available } catch (MissingObjectException e) { @@ -163,20 +163,19 @@ <osgi-core-version>6.0.0</osgi-core-version> <servlet-api-version>4.0.0</servlet-api-version> <jetty-version>10.0.13</jetty-version> - <japicmp-version>0.15.3</japicmp-version> + <japicmp-version>0.17.1</japicmp-version> <httpclient-version>4.5.14</httpclient-version> <httpcore-version>4.4.16</httpcore-version> <slf4j-version>1.7.30</slf4j-version> - <maven-javadoc-plugin-version>3.3.1</maven-javadoc-plugin-version> - <tycho-extras-version>2.6.0</tycho-extras-version> + <maven-javadoc-plugin-version>3.4.1</maven-javadoc-plugin-version> <gson-version>2.10</gson-version> <bouncycastle-version>1.72</bouncycastle-version> - <spotbugs-maven-plugin-version>4.3.0</spotbugs-maven-plugin-version> - <maven-project-info-reports-plugin-version>3.1.2</maven-project-info-reports-plugin-version> - <maven-jxr-plugin-version>3.1.1</maven-jxr-plugin-version> - <maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version> + <spotbugs-maven-plugin-version>4.7.3.0</spotbugs-maven-plugin-version> + <maven-project-info-reports-plugin-version>3.4.2</maven-project-info-reports-plugin-version> + <maven-jxr-plugin-version>3.3.0</maven-jxr-plugin-version> + <maven-surefire-plugin-version>3.0.0-M8</maven-surefire-plugin-version> <maven-surefire-report-plugin-version>${maven-surefire-plugin-version}</maven-surefire-report-plugin-version> - <maven-compiler-plugin-version>3.8.1</maven-compiler-plugin-version> + <maven-compiler-plugin-version>3.10.1</maven-compiler-plugin-version> <plexus-compiler-version>2.12.1</plexus-compiler-version> <hamcrest-version>2.2</hamcrest-version> <assertj-version>3.20.2</assertj-version> @@ -223,7 +222,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.2.0</version> + <version>3.3.0</version> <configuration> <archive> <manifestEntries> @@ -242,25 +241,25 @@ <plugin> <artifactId>maven-clean-plugin</artifactId> - <version>3.1.0</version> + <version>3.2.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> - <version>3.2.4</version> + <version>3.4.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> - <version>3.0.0</version> + <version>3.1.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> - <version>3.2.0</version> + <version>3.5.0</version> </plugin> <plugin> @@ -289,7 +288,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>3.2.0</version> + <version>3.3.0</version> </plugin> <plugin> @@ -312,7 +311,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> - <version>3.15.0</version> + <version>3.20.0</version> <configuration> <sourceEncoding>utf-8</sourceEncoding> <minimumTokens>100</minimumTokens> @@ -335,17 +334,17 @@ <plugin> <groupId>org.eclipse.cbi.maven.plugins</groupId> <artifactId>eclipse-jarsigner-plugin</artifactId> - <version>1.3.2</version> + <version>1.3.5</version> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.7</version> + <version>0.8.8</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> - <version>3.9.1</version> + <version>4.0.0-M4</version> <dependencies> <dependency><!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> @@ -372,12 +371,12 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> - <version>3.0.0-M1</version> + <version>3.0.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> - <version>3.0.0-M1</version> + <version>3.1.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -387,12 +386,12 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> - <version>3.2.0</version> + <version>3.3.0</version> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> - <version>2.5.4</version> + <version>2.7.7</version> </plugin> <plugin> <groupId>org.eclipse.dash</groupId> @@ -406,7 +405,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> - <version>3.0.0</version> + <version>3.1.0</version> <executions> <execution> <id>enforce-maven</id> |