Browse Source

Merge branch 'master' into next

* master:
  Remove unused imports
  Silence API warnings
  Remove erraneously merged source features
  Add support for reading symrefs from pack capabilities
  Prepare 5.3.9-SNAPSHOT builds
  JGit v5.3.8.202011260953-r
  Prepare 5.1.15-SNAPSHOT builds
  JGit v5.1.14.202011251942-r
  GC#deleteOrphans: log warning for deleted orphaned files
  GC#deleteOrphans: handle failure to list files in pack directory
  Ensure that GC#deleteOrphans respects pack lock
  Prepare 5.10.0-SNAPSHOT builds
  JGit v5.10.0.202011251205-m3
  PacketLineIn: ensure that END != DELIM
  Update Orbit to S20201118210000 and add target for 4.18
  PacketLineIn: ensure that END != DELIM
  PacketLineIn: ensure that END != DELIM
  Allow to resolve a conflict by checking out a file
  Update Orbit to I20201111205634
  Document that setLastModified sets time of symlink target
  Fix bug in PerformanceLogContext
  Fix IOException occurring during gc
  Prepare 5.10.0-SNAPSHOT builds
  JGit v5.10.0.202011041322-m2
  Revert "Client-side protocol V2 support for fetching"
  Close Repository to fix tests failing on Windows
  Client-side protocol V2 support for fetching
  Update slf4j to 1.7.30
  Update Orbit to S20201027182932 (2020-12 M2)
  Fix formatting of config option values
  Document options in core section supported by JGit
  Ensure .gitmodules is loaded when accessing submodule name
  Export new package org.eclipse.jgit.logging and import it where used
  Ensure GC.deleteOrphans() can delete read-only orphaned files on Windows
  Add new performance logging
  Implement git describe --all
  Compute time differences with Duration
  Override config http.userAgent from environment GIT_HTTP_USER_AGENT
  Upgrade spotbugs-maven-plugin to 4.1.3
  Fix OperatorPrecedence warning flagged by error prone
  UploadPackTest#testUploadRedundantBytes: ensure test repo is closed
  ObjectDirectory#selectObjectRepresentation: fix formatting
  Upgrade ecj to 3.23.0
  Support "http.userAgent" and "http.extraHeader" from the git config
  sshd: better error report when user cancels authentication
  API filters for PackStatistics.Accumulator
  Add TypedConfigGetter.getPath()
  Make Javadoc consistent for PackStatistics fields
  Measure time taken for reachability checks
  Measure time taken for negotiation in protocol V2
  IndexDiffFilter: handle path prefixes correctly
  sshd: support the ProxyJump ssh config
  Upgrade jacoco-maven-plugin to 0.8.6
  ReceivePackStats: Add size and count of unnecessary pushed objects
  Upgrade maven-project-info-reports-plugin to 3.1.1
  Prepare 5.9.1-SNAPSHOT builds
  JGit v5.9.0.202009080501-r
  [releng] Enable japicmp for the fragments added in 5.8.0
  GitlinkMergeTest: fix boxing warnings
  Remove unused API problem filters
  Add missing since tag on BundleWriter#addObjectsAsIs
  SshdSession: close channel gracefully
  GPG: include signer's user ID in the signature
  jgit: Add DfsBundleWriter
  Bump Bazel version to 3.5.0
  Upgrade maven-resources-plugin to 3.2.0
  Upgrade plexus-compiler version to 2.8.8
  [bazel] Add missing dependency to slf4j-api
  [errorprone] DirCacheEntry: make clear operator precedence
  [errorprone] PackWriter#parallelDeltaSearch: avoid suppressed exception
  [errorprone] Declare DirCache#version final
  Add jgit-4.17-staging target platform for 2020-09
  Update target platform to R20200831200620
  Prepare 5.10.0-SNAPSHOT builds
  Prepare 5.9.0-SNAPSHOT builds
  ResolveMerger: do not content-merge gitlinks on del/mod conflicts
  ResolveMerger: Adding test cases for GITLINK deletion
  ResolveMerger: choose OURS on gitlink when ignoreConflicts
  ResolveMerger: improving content merge readability
  ResolveMerger: extracting createGitLinksMergeResult method
  ResolveMerger: Adding test cases for GITLINK merge
  JGit v5.9.0.202008260805-m3
  Fix possible NegativeArraySizeException in PackIndexV1
  FS: use binary search to determine filesystem timestamp resolution
  Do not prematurely create directory of jgit's XDG config file
  FS: write to JGit config in a background thread
  FS: don't cache fallback if running in background
  Keep line endings for text files committed with CR/LF on text=auto
  Delay WindowCache statistics JMX MBean registration
  [releng] Update plexus-compiler to 2.8.7
  DirCache: support index V4
  Update javadoc for RemoteSession and SshSessionFactory
  Fix JSchProcess.waitFor() with time-out
  sshd: work around a race condition in Apache MINA sshd 2.4.0/2.5.x
  sshd: store per-session data on the sshd session object
  FilterSpec: Use BigInteger.ZERO instead of valueOf(0)
  Do not send empty blob in response to blob:none filter
  Add support for tree filters when fetching
  sshd: use PropertyResolver in test
  FS_POSIX: avoid prompt to install the XCode tools on OS X
  Remove dependency on JSch from SSH test framework
  Use LinkedBlockingQueue for executor determining filesystem attributes
  Update API warning filters
  Remove unused imports
  Bazel: Add workspace status command to stamp final artifact
  DiffFormatter: correctly deal with tracked files in ignored folders
  Prepare 5.8.2-SNAPSHOT builds
  JGit v5.8.1.202007141445-r
  Update Jetty to 9.4.30.v20200611
  Fix writing GPG signatures with trailing newline
  Rename a test method
  Add a test for upstream bug SSHD-1028
  Improve error message when receive.maxCommandBytes is exceeded
  LfsConnectionFactory#getLfsUrl: Fix unconditional break in for-loop
  DiffFormatterTest: Add a test to confirm the default rename detection settings
  Upgrade maven-site-plugin to 3.9.1
  Upgrade build-helper-maven-plugin to 3.2.0
  Upgrade spotbugs to 4.0.4
  MergedReftable: Include the last reftable in determining minUpdateIndex
  Add new osgi fragments to maven-central deploy scripts
  PackBitmapIndex: Not buffer inflated bitmap during bitmap creation.
  Do not require org.assertj.core.annotations
  Upgrade ecj to 3.22.0
  Remove workaround for signing jars using Tycho plugins
  Use https for URL of jgit website
  Fix CI information in pom.xml
  Use gitiles as scm url in pom.xml for browsing source code
  Update API baseline to 5.8.0.202006091008-r
  Remove trailing whitespace

Change-Id: Ie6bc6954741a47cfbd32c0886bdbd7b594f08b31
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
changes/67/172967/2
Matthias Sohn 3 years ago
parent
commit
286ad23cb5
100 changed files with 3842 additions and 887 deletions
  1. 1
    0
      .bazelrc
  2. 1
    1
      .bazelversion
  3. 38
    6
      Documentation/config-options.md
  4. 19
    19
      WORKSPACE
  5. 1
    1
      org.eclipse.jgit.benchmarks/pom.xml
  6. 1
    2
      org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
  7. 0
    4
      org.eclipse.jgit.gpg.bc/pom.xml
  8. 34
    5
      org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java
  9. 1
    1
      org.eclipse.jgit.junit.ssh/BUILD
  10. 1
    2
      org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
  11. 0
    10
      org.eclipse.jgit.junit.ssh/pom.xml
  12. 45
    4
      org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestBase.java
  13. 135
    11
      org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java
  14. 57
    32
      org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java
  15. 24
    0
      org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
  16. 1
    0
      org.eclipse.jgit.lfs.test/BUILD
  17. 1
    1
      org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
  18. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
  19. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
  20. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
  21. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
  22. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
  23. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd
  24. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target
  25. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd
  26. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target
  27. 2
    2
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd
  28. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target
  29. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd
  30. 0
    8
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.tpd
  31. 94
    0
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target
  32. 8
    0
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd
  33. 94
    0
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target
  34. 8
    0
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd
  35. 30
    30
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18-staging.target
  36. 8
    0
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18-staging.tpd
  37. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
  38. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
  39. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
  40. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
  41. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
  42. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
  43. 29
    29
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
  44. 1
    1
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
  45. 12
    12
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200831200620-2020-09.tpd
  46. 66
    0
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20201118210000.tpd
  47. 17
    17
      org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd
  48. 1
    1
      org.eclipse.jgit.packaging/pom.xml
  49. 19
    1
      org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsRemoteTest.java
  50. 2
    0
      org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
  51. 4
    0
      org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java
  52. 15
    0
      org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
  53. 3
    0
      org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
  54. 438
    6
      org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
  55. 1
    0
      org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
  56. 9
    1
      org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
  57. 30
    0
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/AuthenticationCanceledException.java
  58. 257
    0
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
  59. 1
    3
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java
  60. 78
    35
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
  61. 48
    21
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java
  62. 0
    41
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java
  63. 8
    0
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
  64. 5
    46
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpParser.java
  65. 61
    11
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/IdentityPasswordProvider.java
  66. 197
    48
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
  67. 21
    10
      org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
  68. 0
    4
      org.eclipse.jgit.ssh.jsch/pom.xml
  69. 1
    1
      org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java
  70. 1
    0
      org.eclipse.jgit.test/META-INF/MANIFEST.MF
  71. 1
    1
      org.eclipse.jgit.test/build.properties
  72. BIN
      org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/gitgit.index.v4
  73. BIN
      org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idx
  74. BIN
      org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idxV2
  75. 36
    25
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
  76. 46
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java
  77. 48
    72
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java
  78. 25
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java
  79. 12
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
  80. 21
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java
  81. 68
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
  82. 134
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheAfterCloneTest.java
  83. 31
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java
  84. 141
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
  85. 27
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
  86. 85
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriterTest.java
  87. 23
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcBasicPackingTest.java
  88. 20
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
  89. 22
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java
  90. 5
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV1Test.java
  91. 5
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV2Test.java
  92. 16
    16
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
  93. 53
    37
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitBuilderTest.java
  94. 85
    32
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
  95. 95
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java
  96. 368
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java
  97. 43
    1
      org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java
  98. 1
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java
  99. 233
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BasePackConnectionTest.java
  100. 0
    0
      org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpConfigTest.java

+ 1
- 0
.bazelrc View File

@@ -1,3 +1,4 @@
build --workspace_status_command="python ./tools/workspace_status.py"
build --repository_cache=~/.gerritcodereview/bazel-cache/repository
build --experimental_strict_action_env
build --action_env=PATH

+ 1
- 1
.bazelversion View File

@@ -1 +1 @@
3.1.0
3.5.0

+ 38
- 6
Documentation/config-options.md View File

@@ -11,15 +11,47 @@

| option | default | git option | description |
|---------|---------|------------|-------------|
| `core.bigFileThreshold` | `52428800` (50 MiB) | &#x2705; | 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) | &#x2705; | 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.|
| `core.attributesFile` | | &#x2705; | In addition to `.gitattributes` (per-directory) and `.git/info/attributes`, Git looks into this file for attributes . Path expansions are made the same way as for `core.excludesFile`. |
| `core.autocrlf` | `false` | &#x2705; | Setting this variable to `true` is the same as setting the text attribute to `auto` on all files and `core.eol` to `crlf`. Set to `true` if you want to have CRLF line endings in your working directory and the repository has LF line endings. This variable can be set to `input`, in which case no output conversion is performed. |
| `core.bare` | set automatically on init or clone | &#x2705; | If true this repository is assumed to be bare and has no working directory associated with it. If this is the case a number of commands that require a working directory will be disabled |
| `core.bigFileThreshold` | `50 MiB` | &#x2705; | Files larger than this size are stored deflated, without attempting delta compression. Storing large files without delta compression avoids excessive memory usage, at the slight expense of increased disk usage. Additionally files larger than this size are always treated as binary. |
| `core.checkstat` | | &#x2705; | When missing or is set to `default`, many fields in the stat structure are checked to detect if a file has been modified since Git looked at it. Checks as much of the dircache stat info as possible (in JGit limited by Java filesystem API). When set to `minimum` only checks the size and whole second part of time stamp when comparing the stat info in the dircache with actual file stat info. |
| `core.compression` | `-1` (zlib default) | &#x2705; | 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.|
| `core.deltaBaseCacheLimit` | `10 MiB` | &#x2705; | Maximum number of bytes to reserve for caching base objects that multiple deltafied objects reference. By storing the entire decompressed base object in a cache Git is able to avoid unpacking and decompressing frequently used base objects multiple times. |
| `core.dfs.blockLimit` | `30 MiB` | &#x20DE; | Maximum number bytes of heap memory to dedicate to caching pack file data in DFS block cache. |
| `core.dfs.blockSize` | `64 kiB` | &#x20DE; | Size in bytes of a single window read in from the pack file into the DFS block cache. |
| `core.dfs.concurrencyLevel` | `32` | &#x20DE; | The estimated number of threads concurrently accessing the DFS block cache. |
| `core.dfs.deltaBaseCacheLimit` | `10 MiB` | &#x20DE; | Maximum number of bytes to hold in per-reader DFS delta base cache. |
| `core.dfs.streamFileThreshold` | `50 MiB` | &#x20DE; | The size threshold beyond which objects must be streamed. |
| `core.dfs.streamBuffer` | Block size of the pack | &#x20DE; | Number of bytes to use for buffering when streaming a pack file during copying. If 0 the block size of the pack is used|
| `core.dfs.streamRatio` | `0.30` | &#x20DE; | Ratio of DFS block cache to occupy with a copied pack. Values between `0` and `1.0`. |
| `core.dirNoGitLinks` | `false` | &#x20DE; | If set to `true` avoid checking for submodules. See [bug 436200](https://bugs.eclipse.org/bugs/show_bug.cgi?id=436200). |
| `core.eol` | `native` | &#x2705; | Sets the line ending type to use in the working directory for files that are marked as text (either by having the text attribute set, or by having `text=auto` and Git auto-detecting the contents as text). Alternatives are `lf`, `crlf` and `native`, which uses the platform’s native line ending. |
| `core.excludesFile` | | &#x2705; | Specifies the pathname to the file that contains patterns to describe paths that are not meant to be tracked, in addition to `.gitignore` (per-directory) and `.git/info/exclude`. |
| `core.fileMode` | Auto detects if file modes are supported | &#x2705; | Tells Git if the executable bit of files in the working tree is to be honored. |
| `core.hideDotFiles` | `dotGitOnly` | &#x2705; | Windows only. If `true`, mark newly-created directories and files whose name starts with a dot as hidden. If `dotGitOnly`, only the `.git/` directory is hidden, but no other files starting with a dot. |
| `core.hooksPath` | `$GIT_DIR/hooks` | &#x2705; | Path to look for hooks. |
| `core.logAllRefUpdates` | `true` in a repository with working tree, `false` in bare repository | &#x2705; | Enable the reflog. |
| `core.packedGitLimit` | `10 MiB` | &#x2705; | Maximum number of bytes to cache in memory from pack files. |
| `core.packedGitMmap` | `false` | &#x2705; | Whether to use Java NIO virtual memory mapping for JGit buffer cache. When set to `true` enables use of Java NIO virtual memory mapping for cache windows, `false` reads entire window into a `byte[]` with standard read calls. `true` is experimental and may cause instabilities and crashes since Java doesn't support explicit unmapping of file regions mapped to virtual memory. |
| `core.packedGitOpenFiles` | `128` | &#x20DE; | Maximum number of streams to open at a time. Open packs count against the process limits. |
| `core.packedGitUseStrongRefs` | `false` | &#x20DE; | Whether the window cache should use strong references (`true`) or SoftReferences (`false`). When `false` the JVM will drop data cached in the JGit block cache when heap usage comes close to the maximum heap size. |
| `core.packedGitWindowSize` | `8 kiB` | &#x2705; | Number of bytes of a pack file to load into memory in a single read operation. This is the "page size" of the JGit buffer cache, used for all pack access operations. All disk IO occurs as single window reads. Setting this too large may cause the process to load more data than is required; setting this too small may increase the frequency of read() system calls. |
| `core.precomposeUnicode` | `true` on Mac OS | &#x2705; | MacOS only. When `true`, JGit reverts the unicode decomposition of filenames done by Mac OS. |
| `core.quotePath` | `true` | &#x2705; | Commands that output paths (e.g. ls-files, diff), will quote "unusual" characters in the pathname by enclosing the pathname in double-quotes and escaping those characters with backslashes in the same way C escapes control characters (e.g. `\t` for TAB, `\n` for LF, `\\` for backslash) or bytes with values larger than `0x80` (e.g. octal `\302\265` for "micro" in UTF-8). |
| `core.repositoryFormatVersion` | `1` | &#x20DE; | Internal version identifying the repository format and layout version. Don't set manually. |
| `core.streamFileThreshold` | `50 MiB` | &#x20DE; | The size threshold beyond which objects must be streamed. |
| `core.supportsAtomicFileCreation` | `true` | &#x20DE; | Whether the filesystem supports atomic file creation. |
| `core.symlinks` | Auto detect if filesystem supports symlinks| &#x2705; | If false, symbolic links are checked out as small plain files that contain the link text. |
| `core.trustFolderStat` | `true` | &#x20DE; | Whether to trust the pack folder's modification time. If `false` JGit will always scan the `.git/objects/pack` folder to check for new pack files. This can help to workaround caching issues on NFS, but reduces performance. If set to `true` it uses the `lastmodified` attribute of the folder and assumes that no new pack files can be in this folder if its modification time has not changed. |
| `core.worktree` | Root directory of the working tree if it is not the parent directory of the `.git` directory | &#x2705; | The path to the root of the working tree. |

## __gc__ options

| option | default | git option | description |
|---------|---------|------------|-------------|
| `gc.aggressiveDepth` | 50 | &#x2705; | The depth parameter used in the delta compression algorithm used by aggressive garbage collection. |
| `gc.aggressiveWindow` | 250 | &#x2705; | The window size parameter used in the delta compression algorithm used by aggressive garbage collection. |
| `gc.aggressiveDepth` | `50` | &#x2705; | The depth parameter used in the delta compression algorithm used by aggressive garbage collection. |
| `gc.aggressiveWindow` | `250` | &#x2705; | The window size parameter used in the delta compression algorithm used by aggressive garbage collection. |
| `gc.auto` | `6700` | &#x2705; | 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` | &#x2705; | Make auto gc return immediately and run in background. |
| `gc.autoPackLimit` | `50` | &#x2705; | 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. |
@@ -41,11 +73,11 @@
| `pack.compression` | `core.compression` | &#x2705; | Compression level applied to objects in the pack. |
| `pack.cutDeltaChains` | `false` | &#x20DE; | Whether existing delta chains should be cut at {@link #getMaxDeltaDepth() |
| `pack.deltaCacheLimit` | `100` | &#x2705; | Maximum size in bytes of a delta to cache. |
| `pack.deltaCacheSize` | `52428800` (50 MiB) | &#x2705; | Size of the in-memory delta cache. |
| `pack.deltaCacheSize` | `50 MiB` | &#x2705; | Size of the in-memory delta cache. |
| `pack.deltaCompression` | `true` | &#x20DE; | 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` | &#x2705; | Maximum depth of delta chain set up for the pack writer. |
| `pack.indexVersion` | `2` | &#x2705; | Pack index file format version. |
| `pack.minSizePreventRacyPack` | `104857600` (100 MiB) | &#x20DE; | 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.minSizePreventRacyPack` | `100 MiB` | &#x20DE; | 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` | &#x20DE; | Whether to preserve old packs in a preserved directory. |
| `prunePreserved`, only via API of PackConfig | `false` | &#x20DE; | Whether to remove preserved pack files in a preserved directory. |
| `pack.reuseDeltas` | `true` |&#x20DE; | Whether to reuse deltas existing in repository. |

+ 19
- 19
WORKSPACE View File

@@ -107,8 +107,8 @@ maven_jar(

maven_jar(
name = "commons-codec",
artifact = "commons-codec:commons-codec:1.13",
sha1 = "3f18e1aa31031d89db6f01ba05d501258ce69d2c",
artifact = "commons-codec:commons-codec:1.14",
sha1 = "3cb1181b2141a7e752f5bdc998b7ef1849f726cf",
)

maven_jar(
@@ -119,14 +119,14 @@ maven_jar(

maven_jar(
name = "log-api",
artifact = "org.slf4j:slf4j-api:1.7.2",
sha1 = "0081d61b7f33ebeab314e07de0cc596f8e858d97",
artifact = "org.slf4j:slf4j-api:1.7.30",
sha1 = "b5a4b6d16ab13e34a88fae84c35cd5d68cac922c",
)

maven_jar(
name = "slf4j-simple",
artifact = "org.slf4j:slf4j-simple:1.7.2",
sha1 = "760055906d7353ba4f7ce1b8908bc6b2e91f39fa",
artifact = "org.slf4j:slf4j-simple:1.7.30",
sha1 = "e606eac955f55ecf1d8edcccba04eb8ac98088dd",
)

maven_jar(
@@ -209,48 +209,48 @@ maven_jar(
sha1 = "3edcfe49d2c6053a70a2a47e4e1c2f94998a49cf",
)

JETTY_VER = "9.4.28.v20200408"
JETTY_VER = "9.4.30.v20200611"

maven_jar(
name = "jetty-servlet",
artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
sha1 = "7df27a6d73e3094ad94ea4f32e3e6597cecbdf38",
src_sha1 = "49da8455dd5760b7c5961df3b1e7d1490ff9723e",
sha1 = "ca3dea2cd34ee88cec017001603af0c9e74781d6",
src_sha1 = "6908f24428060bd542bddfa3e89e03d0dbbc2a6d",
)

maven_jar(
name = "jetty-security",
artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
sha1 = "d5fe6851f14d1375e4b4ab1818475bfd929cf517",
src_sha1 = "204f19ac7e4df9f6f68df1910154d7667ecd78e8",
sha1 = "1a5261f6ad4081ad9e9bb01416d639931d391273",
src_sha1 = "6ca41b34aa4f84c267603edd4b069122bd5f17d3",
)

maven_jar(
name = "jetty-server",
artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
sha1 = "9c2cbd96426be38b1273ec87ae21e2696688a737",
src_sha1 = "83454098deb880ecc7168252578f712c06a5504b",
sha1 = "e5ede3724d062717d0c04e4c77f74fe8115c2a6f",
src_sha1 = "c8b02a47a35c1f083b310cbd202738cf08bc1d55",
)

maven_jar(
name = "jetty-http",
artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
sha1 = "dd56750ea7410c925f1fbae973c0a19cce5a0a68",
src_sha1 = "1ef8d10cb5ce5694f12650cbb49b31008c673182",
sha1 = "cd6223382e4f82b9ea807d8cdb04a23e5d629f1c",
src_sha1 = "00520c04b10609b981159b5ca284b5a158c077a9",
)

maven_jar(
name = "jetty-io",
artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
sha1 = "adda6786588a922f834e9c33c7db5f1484310f44",
src_sha1 = "4e7756e00b97b439d404e6a682bb1cdeb36fc887",
sha1 = "9c360d08e903b2dbd5d1f8e889a32046948628ce",
src_sha1 = "dac8f8a3f84afdd3686d36f58b5ccb276961b8ce",
)

maven_jar(
name = "jetty-util",
artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
sha1 = "118d2a44721885a04238aee21a5055dc1ab3818a",
src_sha1 = "e2e6d7c90e4126645d2667014d02f0732c08c948",
sha1 = "39ec6aa4745952077f5407cb1394d8ba2db88b13",
src_sha1 = "f41f9391f91884a79350f3ad9b09b8e46c9be0ec",
)

BOUNCYCASTLE_VER = "1.65"

+ 1
- 1
org.eclipse.jgit.benchmarks/pom.xml View File

@@ -179,7 +179,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.1</version>
</plugin>
</plugins>
</pluginManagement>

+ 1
- 2
org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF View File

@@ -8,8 +8,7 @@ Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-Version: 6.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.assertj.core.annotations;version="3.14.0",
org.bouncycastle.bcpg;version="[1.65.0,2.0.0)",
Import-Package: org.bouncycastle.bcpg;version="[1.65.0,2.0.0)",
org.bouncycastle.gpg;version="[1.65.0,2.0.0)",
org.bouncycastle.gpg.keybox;version="[1.65.0,2.0.0)",
org.bouncycastle.gpg.keybox.jcajce;version="[1.65.0,2.0.0)",

+ 0
- 4
org.eclipse.jgit.gpg.bc/pom.xml View File

@@ -128,7 +128,6 @@
</configuration>
</plugin>

<!-- No previous version to compare to
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
@@ -170,13 +169,11 @@
</execution>
</executions>
</plugin>
-->
</plugins>
</build>

<reporting>
<plugins>
<!-- No previous version to compare to
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
@@ -217,7 +214,6 @@
<skip>false</skip>
</configuration>
</plugin>
-->
</plugins>
</reporting>
</project>

+ 34
- 5
org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java View File

@@ -15,6 +15,7 @@ import java.net.URISyntaxException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Iterator;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream;
@@ -22,6 +23,7 @@ import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
@@ -38,6 +40,7 @@ import org.eclipse.jgit.lib.GpgSignature;
import org.eclipse.jgit.lib.GpgSigner;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.util.StringUtils;

/**
* GPG Signer using BouncyCastle library
@@ -126,17 +129,32 @@ public class BouncyCastleGpgSigner extends GpgSigner {
privateKey = secretKey
.extractPrivateKey(decryptorBuilder.build(passphrase));
}
PGPPublicKey publicKey = secretKey.getPublicKey();
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
new JcaPGPContentSignerBuilder(
secretKey.getPublicKey().getAlgorithm(),
publicKey.getAlgorithm(),
HashAlgorithmTags.SHA256).setProvider(
BouncyCastleProvider.PROVIDER_NAME));
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
PGPSignatureSubpacketGenerator subpacketGenerator = new PGPSignatureSubpacketGenerator();
subpacketGenerator.setIssuerFingerprint(false,
secretKey.getPublicKey());
PGPSignatureSubpacketGenerator subpackets = new PGPSignatureSubpacketGenerator();
subpackets.setIssuerFingerprint(false, publicKey);
// Also add the signer's user ID. Note that GPG uses only the e-mail
// address part.
String userId = committer.getEmailAddress();
Iterator<String> userIds = publicKey.getUserIDs();
if (userIds.hasNext()) {
String keyUserId = userIds.next();
if (!StringUtils.isEmptyOrNull(keyUserId)
&& (userId == null || !keyUserId.contains(userId))) {
// Not the committer's key?
userId = extractSignerId(keyUserId);
}
}
if (userId != null) {
subpackets.setSignerUserID(false, userId);
}
signatureGenerator
.setHashedSubpackets(subpacketGenerator.generate());
.setHashedSubpackets(subpackets.generate());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try (BCPGOutputStream out = new BCPGOutputStream(
new ArmoredOutputStream(buffer))) {
@@ -149,4 +167,15 @@ public class BouncyCastleGpgSigner extends GpgSigner {
throw new JGitInternalException(e.getMessage(), e);
}
}

private String extractSignerId(String pgpUserId) {
int from = pgpUserId.indexOf('<');
if (from >= 0) {
int to = pgpUserId.indexOf('>', from + 1);
if (to > from + 1) {
return pgpUserId.substring(from + 1, to);
}
}
return pgpUserId;
}
}

+ 1
- 1
org.eclipse.jgit.junit.ssh/BUILD View File

@@ -13,8 +13,8 @@ java_library(
"//org.eclipse.jgit.ssh.jsch.test:__pkg__",
],
deps = [
"//lib:jsch",
"//lib:junit",
"//lib:slf4j-api",
"//lib:sshd-osgi",
"//lib:sshd-sftp",
# We want these deps to be provided_deps

+ 1
- 2
org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF View File

@@ -8,8 +8,7 @@ Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.jcraft.jsch;version="0.1.55",
org.apache.sshd.common;version="[2.4.0,2.5.0)",
Import-Package: org.apache.sshd.common;version="[2.4.0,2.5.0)",
org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)",
org.apache.sshd.common.file.virtualfs;version="[2.4.0,2.5.0)",
org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)",

+ 0
- 10
org.eclipse.jgit.junit.ssh/pom.xml View File

@@ -57,16 +57,6 @@
<version>${apache-sshd-version}</version>
</dependency>

<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
</dependency>

<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jzlib</artifactId>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

+ 45
- 4
org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestBase.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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
@@ -14,6 +14,7 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

@@ -22,9 +23,14 @@ import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.errors.CommandFailedException;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SshSupport;
import org.junit.Test;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theory;
@@ -67,10 +73,45 @@ public abstract class SshTestBase extends SshTestHarness {
defaultCloneDir = new File(getTemporaryDirectory(), "cloned");
}

@Test(expected = TransportException.class)
@Test
public void testSshWithoutConfig() throws Exception {
cloneWith("ssh://" + TEST_USER + "@localhost:" + testPort
+ "/doesntmatter", defaultCloneDir, null);
assertThrows(TransportException.class,
() -> cloneWith("ssh://" + TEST_USER + "@localhost:" + testPort
+ "/doesntmatter", defaultCloneDir, null));
}

@Test
public void testSingleCommand() throws Exception {
installConfig("IdentityFile " + privateKey1.getAbsolutePath());
String command = SshTestGitServer.ECHO_COMMAND + " 1 without timeout";
long start = System.nanoTime();
String reply = SshSupport.runSshCommand(
new URIish("ssh://" + TEST_USER + "@localhost:" + testPort),
null, FS.DETECTED, command, 0); // 0 == no timeout
long elapsed = System.nanoTime() - start;
assertEquals(command, reply);
// Now that we have an idea how long this takes on the test
// infrastructure, try again with a timeout.
command = SshTestGitServer.ECHO_COMMAND + " 1 expecting no timeout";
// Still use a generous timeout.
int timeout = 10 * ((int) TimeUnit.NANOSECONDS.toSeconds(elapsed) + 1);
reply = SshSupport.runSshCommand(
new URIish("ssh://" + TEST_USER + "@localhost:" + testPort),
null, FS.DETECTED, command, timeout);
assertEquals(command, reply);
}

@Test
public void testSingleCommandWithTimeoutExpired() throws Exception {
installConfig("IdentityFile " + privateKey1.getAbsolutePath());
String command = SshTestGitServer.ECHO_COMMAND + " 2 EXPECTING TIMEOUT";

CommandFailedException e = assertThrows(CommandFailedException.class,
() -> SshSupport.runSshCommand(new URIish(
"ssh://" + TEST_USER + "@localhost:" + testPort), null,
FS.DETECTED, command, 1));
assertTrue(e.getMessage().contains(command));
assertTrue(e.getMessage().contains("time"));
}

@Test

+ 135
- 11
org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java View File

@@ -12,6 +12,8 @@ package org.eclipse.jgit.junit.ssh;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
@@ -22,8 +24,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
@@ -66,6 +70,16 @@ import org.eclipse.jgit.transport.UploadPack;
*/
public class SshTestGitServer {

/**
* Simple echo test command. Replies with the command string as passed. If
* of the form "echo [int] anything", takes the integer value as a delay in
* seconds before replying, which may be useful to test various
* timeout-related things.
*
* @since 5.9
*/
public static final String ECHO_COMMAND = "echo";

@NonNull
protected final String testUser;

@@ -90,8 +104,7 @@ public class SshTestGitServer {
* @param testUser
* user name of the test user
* @param testKey
* <em>private</em> key file of the test user; the server will
* only user the public key from it
* public key file of the test user
* @param repository
* to serve
* @param hostKey
@@ -102,17 +115,54 @@ public class SshTestGitServer {
public SshTestGitServer(@NonNull String testUser, @NonNull Path testKey,
@NonNull Repository repository, @NonNull byte[] hostKey)
throws IOException, GeneralSecurityException {
this(testUser, readPublicKey(testKey), repository,
readKeyPair(hostKey));
}

/**
* Creates a ssh git <em>test</em> server. It serves one single repository,
* and accepts public-key authentication for exactly one test user.
*
* @param testUser
* user name of the test user
* @param testKey
* public key file of the test user
* @param repository
* to serve
* @param hostKey
* the unencrypted private key to use as host key
* @throws IOException
* @throws GeneralSecurityException
* @since 5.9
*/
public SshTestGitServer(@NonNull String testUser, @NonNull Path testKey,
@NonNull Repository repository, @NonNull KeyPair hostKey)
throws IOException, GeneralSecurityException {
this(testUser, readPublicKey(testKey), repository, hostKey);
}

/**
* Creates a ssh git <em>test</em> server. It serves one single repository,
* and accepts public-key authentication for exactly one test user.
*
* @param testUser
* user name of the test user
* @param testKey
* the {@link PublicKey} of the test user
* @param repository
* to serve
* @param hostKey
* the {@link KeyPair} to use as host key
* @since 5.9
*/
public SshTestGitServer(@NonNull String testUser,
@NonNull PublicKey testKey, @NonNull Repository repository,
@NonNull KeyPair hostKey) {
this.testUser = testUser;
setTestUserPublicKey(testKey);
this.repository = repository;
server = SshServer.setUpDefaultServer();
// Set host key
try (ByteArrayInputStream in = new ByteArrayInputStream(hostKey)) {
SecurityUtils.loadKeyPairIdentities(null, null, in, null)
.forEach((k) -> hostKeys.add(k));
} catch (IOException | GeneralSecurityException e) {
// Ignore.
}
hostKeys.add(hostKey);
server.setKeyPairProvider((session) -> hostKeys);

configureAuthentication();
@@ -129,11 +179,27 @@ public class SshTestGitServer {
return new GitUploadPackCommand(command, executorService);
} else if (command.startsWith(RemoteConfig.DEFAULT_RECEIVE_PACK)) {
return new GitReceivePackCommand(command, executorService);
} else if (command.startsWith(ECHO_COMMAND)) {
return new EchoCommand(command, executorService);
}
return new UnknownCommand(command);
});
}

private static PublicKey readPublicKey(Path key)
throws IOException, GeneralSecurityException {
return AuthorizedKeyEntry.readAuthorizedKeys(key).get(0)
.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
}

private static KeyPair readKeyPair(byte[] keyMaterial)
throws IOException, GeneralSecurityException {
try (ByteArrayInputStream in = new ByteArrayInputStream(keyMaterial)) {
return SecurityUtils.loadKeyPairIdentities(null, null, in, null)
.iterator().next();
}
}

private static class FakeUserAuthGSS extends UserAuthGSS {
@Override
protected Boolean doAuth(Buffer buffer, boolean initial)
@@ -297,6 +363,17 @@ public class SshTestGitServer {
DefaultKeyboardInteractiveAuthenticator.INSTANCE);
}

/**
* Retrieves the server's {@link PropertyResolver}, giving access to server
* properties.
*
* @return the {@link PropertyResolver}
* @since 5.9
*/
public PropertyResolver getPropertyResolver() {
return server;
}

/**
* Starts the test server, listening on a random port.
*
@@ -331,8 +408,7 @@ public class SshTestGitServer {
*/
public void setTestUserPublicKey(Path key)
throws IOException, GeneralSecurityException {
this.testKey = AuthorizedKeyEntry.readAuthorizedKeys(key).get(0)
.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
this.testKey = readPublicKey(key);
}

/**
@@ -414,4 +490,52 @@ public class SshTestGitServer {
}

}

/**
* Simple echo command that echoes back the command string. If the first
* argument is a positive integer, it's taken as a delay (in seconds) before
* replying. Assumes UTF-8 character encoding.
*/
private static class EchoCommand extends AbstractCommandSupport {

protected EchoCommand(String command,
CloseableExecutorService executorService) {
super(command, ThreadUtils.noClose(executorService));
}

@Override
public void run() {
String[] parts = getCommand().split(" ");
int timeout = 0;
if (parts.length >= 2) {
try {
timeout = Integer.parseInt(parts[1]);
} catch (NumberFormatException e) {
// No timeout.
}
if (timeout > 0) {
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(timeout));
} catch (InterruptedException e) {
// Ignore.
}
}
}
try {
doEcho(getCommand(), getOutputStream());
onExit(0);
} catch (IOException e) {
log.warn(
MessageFormat.format("Could not run {0}", getCommand()),
e);
onExit(-1, e.toString());
}
}

private void doEcho(String text, OutputStream stream)
throws IOException {
stream.write(text.getBytes(StandardCharsets.UTF_8));
stream.flush();
}
}
}

+ 57
- 32
org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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
@@ -9,27 +9,31 @@
*/
package org.eclipse.jgit.junit.ssh;

import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.sshd.common.config.keys.PublicKeyEntry;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
@@ -48,9 +52,6 @@ import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FS;
import org.junit.After;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.KeyPair;

/**
* Root class for ssh tests. Sets up the ssh test server. A set of pre-computed
* keys for testing is provided in the bundle and can be used in test cases via
@@ -75,6 +76,8 @@ public abstract class SshTestHarness extends RepositoryTestCase {

protected File publicKey1;

protected File publicKey2;

protected SshTestGitServer server;

private SshSessionFactory factory;
@@ -104,50 +107,71 @@ public abstract class SshTestHarness extends RepositoryTestCase {
File serverDir = new File(getTemporaryDirectory(), "srv");
assertTrue(serverDir.mkdir());
// Create two key pairs. Let's not call them "id_rsa".
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
privateKey1 = new File(sshDir, "first_key");
privateKey2 = new File(sshDir, "second_key");
publicKey1 = createKeyPair(privateKey1);
createKeyPair(privateKey2);
ByteArrayOutputStream publicHostKey = new ByteArrayOutputStream();
publicKey1 = createKeyPair(generator.generateKeyPair(), privateKey1);
publicKey2 = createKeyPair(generator.generateKeyPair(), privateKey2);
// Create a host key
KeyPair hostKey = generator.generateKeyPair();
// Start a server with our test user and the first key.
server = new SshTestGitServer(TEST_USER, publicKey1.toPath(), db,
createHostKey(publicHostKey));
hostKey);
testPort = server.start();
assertTrue(testPort > 0);
knownHosts = new File(sshDir, "known_hosts");
Files.write(knownHosts.toPath(), Collections.singleton("[localhost]:"
+ testPort + ' '
+ publicHostKey.toString(US_ASCII.name())));
StringBuilder knownHostsLine = new StringBuilder();
knownHostsLine.append("[localhost]:").append(testPort).append(' ');
PublicKeyEntry.appendPublicKeyEntry(knownHostsLine,
hostKey.getPublic());
Files.write(knownHosts.toPath(),
Collections.singleton(knownHostsLine.toString()));
factory = createSessionFactory();
SshSessionFactory.setInstance(factory);
}

private static File createKeyPair(File privateKeyFile) throws Exception {
// Found no way to do this with MINA sshd except rolling it all
// ourselves...
JSch jsch = new JSch();
KeyPair pair = KeyPair.genKeyPair(jsch, KeyPair.RSA, 2048);
try (OutputStream out = new FileOutputStream(privateKeyFile)) {
pair.writePrivateKey(out);
private static File createKeyPair(KeyPair newKey, File privateKeyFile)
throws Exception {
// Write PKCS#8 PEM unencrypted. Both JSch and sshd can read that.
PrivateKey privateKey = newKey.getPrivate();
String format = privateKey.getFormat();
if (!"PKCS#8".equalsIgnoreCase(format)) {
throw new IOException("Cannot write " + privateKey.getAlgorithm()
+ " key in " + format + " format");
}
try (BufferedWriter writer = Files.newBufferedWriter(
privateKeyFile.toPath(), StandardCharsets.US_ASCII)) {
writer.write("-----BEGIN PRIVATE KEY-----");
writer.newLine();
write(writer, privateKey.getEncoded(), 64);
writer.write("-----END PRIVATE KEY-----");
writer.newLine();
}
File publicKeyFile = new File(privateKeyFile.getParentFile(),
privateKeyFile.getName() + ".pub");
StringBuilder builder = new StringBuilder();
PublicKeyEntry.appendPublicKeyEntry(builder, newKey.getPublic());
builder.append(' ').append(TEST_USER);
try (OutputStream out = new FileOutputStream(publicKeyFile)) {
pair.writePublicKey(out, TEST_USER);
out.write(builder.toString().getBytes(StandardCharsets.US_ASCII));
}
return publicKeyFile;
}

private static byte[] createHostKey(OutputStream publicKey)
throws Exception {
JSch jsch = new JSch();
KeyPair pair = KeyPair.genKeyPair(jsch, KeyPair.RSA, 2048);
pair.writePublicKey(publicKey, "");
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
pair.writePrivateKey(out);
out.flush();
return out.toByteArray();
private static void write(BufferedWriter out, byte[] bytes, int lineLength)
throws IOException {
String data = Base64.getEncoder().encodeToString(bytes);
int last = data.length();
for (int i = 0; i < last; i += lineLength) {
if (i + lineLength <= last) {
out.write(data.substring(i, i + lineLength));
} else {
out.write(data.substring(i));
}
out.newLine();
}
Arrays.fill(bytes, (byte) 0);
}

/**
@@ -167,7 +191,8 @@ public abstract class SshTestHarness extends RepositoryTestCase {
*/
protected static String createKnownHostsFile(File file, String host,
int port, File publicKey) throws IOException {
List<String> lines = Files.readAllLines(publicKey.toPath(), UTF_8);
List<String> lines = Files.readAllLines(publicKey.toPath(),
StandardCharsets.UTF_8);
assertEquals("Public key has too many lines", 1, lines.size());
String pubKey = lines.get(0);
// Strip off the comment.

+ 24
- 0
org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java View File

@@ -34,6 +34,7 @@ import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheCheckout;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
@@ -45,6 +46,7 @@ import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.junit.After;
import org.junit.Before;

/**
@@ -186,6 +188,13 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
trash = db.getWorkTree();
}

@Override
@After
public void tearDown() throws Exception {
db.close();
super.tearDown();
}

/**
* Represent the state of the index in one String. This representation is
* useful when writing tests which do assertions on the state of the index.
@@ -512,6 +521,21 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
return entry;
}

/**
* Create <code>DirCacheEntry</code>
*
* @param path
* @param objectId
* @return the DirCacheEntry
*/
protected DirCacheEntry createGitLink(String path, AnyObjectId objectId) {
final DirCacheEntry entry = new DirCacheEntry(path,
DirCacheEntry.STAGE_0);
entry.setFileMode(FileMode.GITLINK);
entry.setObjectId(objectId);
return entry;
}

/**
* Assert files are equal
*

+ 1
- 0
org.eclipse.jgit.lfs.test/BUILD View File

@@ -13,6 +13,7 @@ junit_tests(
deps = [
":helpers",
"//lib:junit",
"//lib:slf4j-api",
"//org.eclipse.jgit:jgit",
"//org.eclipse.jgit.junit:junit",
"//org.eclipse.jgit.lfs:jgit-lfs",

+ 1
- 1
org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java View File

@@ -112,8 +112,8 @@ public class LfsConnectionFactory {
remoteUrl = config.getString(
ConfigConstants.CONFIG_KEY_REMOTE, remote,
ConfigConstants.CONFIG_KEY_URL);
break;
}
break;
}
if (lfsUrl == null && remoteUrl != null) {
try {

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.10" sequenceNumber="1590935844">
<target name="jgit-4.10" sequenceNumber="1605866255">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.10" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2018-12/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.11" sequenceNumber="1590935852">
<target name="jgit-4.11" sequenceNumber="1605866333">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.11" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2019-03/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.12" sequenceNumber="1590935859">
<target name="jgit-4.12" sequenceNumber="1605866333">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.12" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2019-06/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.13" sequenceNumber="1590935871">
<target name="jgit-4.13" sequenceNumber="1605866333">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.13" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2019-09/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.14-staging" sequenceNumber="1590935878">
<target name="jgit-4.14" sequenceNumber="1605866331">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 2
- 2
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.14-staging" with source configurePhase
target "jgit-4.14" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2019-12/201912181000/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.15" sequenceNumber="1590935883">
<target name="jgit-4.15" sequenceNumber="1605866331">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.15" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2020-03/202003181000/" {
org.eclipse.osgi lazy

+ 0
- 8
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.tpd View File

@@ -1,8 +0,0 @@
target "jgit-4.15" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"

location "https://download.eclipse.org/staging/2020-06/" {
org.eclipse.osgi lazy
}

+ 94
- 0
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.16" sequenceNumber="1605866333">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
<unit id="com.google.gson.source" version="2.8.2.v20180104-1110"/>
<unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
<unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
<unit id="javaewah" version="1.1.7.v20200107-0831"/>
<unit id="javaewah.source" version="1.1.7.v20200107-0831"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcpg.source" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcpkix" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcpkix.source" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcprov" version="1.65.1.v20200529-1514"/>
<unit id="org.bouncycastle.bcprov.source" version="1.65.1.v20200529-1514"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
<unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
<unit id="org.junit" version="4.13.0.v20200204-1500"/>
<unit id="org.junit.source" version="4.13.0.v20200204-1500"/>
<unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
<unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
<unit id="org.mockito" version="2.23.0.v20200310-1642"/>
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
<repository location="https://download.eclipse.org/releases/2020-06/"/>
</location>
</locations>
</target>

+ 8
- 0
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd View File

@@ -0,0 +1,8 @@
target "jgit-4.16" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2020-06/" {
org.eclipse.osgi lazy
}

+ 94
- 0
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target View File

@@ -0,0 +1,94 @@
<?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="1605866541">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
<unit id="com.google.gson.source" version="2.8.2.v20180104-1110"/>
<unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
<unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
<unit id="javaewah" version="1.1.7.v20200107-0831"/>
<unit id="javaewah.source" version="1.1.7.v20200107-0831"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcpg.source" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcpkix" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcpkix.source" version="1.65.0.v20200527-1955"/>
<unit id="org.bouncycastle.bcprov" version="1.65.1.v20200529-1514"/>
<unit id="org.bouncycastle.bcprov.source" version="1.65.1.v20200529-1514"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
<unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
<unit id="org.junit" version="4.13.0.v20200204-1500"/>
<unit id="org.junit.source" version="4.13.0.v20200204-1500"/>
<unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
<unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
<unit id="org.mockito" version="2.23.0.v20200310-1642"/>
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
<repository location="https://download.eclipse.org/releases/2020-09/"/>
</location>
</locations>
</target>

+ 8
- 0
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd View File

@@ -0,0 +1,8 @@
target "jgit-4.17" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2020-09/" {
org.eclipse.osgi lazy
}

org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.target → org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18-staging.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.15" sequenceNumber="1590935890">
<target name="jgit-4.18-staging" sequenceNumber="1605866541">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,17 +78,17 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
<repository location="https://download.eclipse.org/staging/2020-06/"/>
<repository location="https://download.eclipse.org/staging/2020-12/"/>
</location>
</locations>
</target>

+ 8
- 0
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18-staging.tpd View File

@@ -0,0 +1,8 @@
target "jgit-4.18-staging" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/staging/2020-12/" {
org.eclipse.osgi lazy
}

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.6" sequenceNumber="1590935806">
<target name="jgit-4.6" sequenceNumber="1605866347">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.6" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/neon/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.7" sequenceNumber="1590935820">
<target name="jgit-4.7" sequenceNumber="1605866338">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.7" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/oxygen/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.8" sequenceNumber="1590935828">
<target name="jgit-4.8" sequenceNumber="1605866333">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.8" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/photon/" {
org.eclipse.osgi lazy

+ 29
- 29
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.9" sequenceNumber="1590935836">
<target name="jgit-4.9" sequenceNumber="1605866333">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
<repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
<unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,16 +39,16 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
<unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
<unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -78,13 +78,13 @@
<unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
<unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
<unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
<unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
<unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/>
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

+ 1
- 1
org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd View File

@@ -1,7 +1,7 @@
target "jgit-4.9" with source configurePhase

include "projects/jetty-9.4.x.tpd"
include "orbit/R20200529191137-2020-06.tpd"
include "orbit/S20201118210000.tpd"

location "https://download.eclipse.org/releases/2018-09/" {
org.eclipse.osgi lazy

org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20200519202422.tpd → org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200831200620-2020-09.tpd View File

@@ -1,7 +1,7 @@
target "S20200519202422" with source configurePhase
target "R20200831200620-2020-09" with source configurePhase
// see https://download.eclipse.org/tools/orbit/downloads/

location "https://download.eclipse.org/tools/orbit/downloads/drops/S20200519202422/repository" {
location "https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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]
@@ -20,14 +20,14 @@ location "https://download.eclipse.org/tools/orbit/downloads/drops/S202005192024
net.i2p.crypto.eddsa.source [0.3.0.v20181102-1323,0.3.0.v20181102-1323]
org.apache.ant [1.10.8.v20200515-1239,1.10.8.v20200515-1239]
org.apache.ant.source [1.10.8.v20200515-1239,1.10.8.v20200515-1239]
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.codec [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
org.apache.commons.codec.source [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
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.httpclient [4.5.10.v20200830-2311,4.5.10.v20200830-2311]
org.apache.httpcomponents.httpclient.source [4.5.10.v20200830-2311,4.5.10.v20200830-2311]
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]
@@ -38,12 +38,12 @@ location "https://download.eclipse.org/tools/orbit/downloads/drops/S202005192024
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.bouncycastle.bcpg [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcpg.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcpkix [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcpkix.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcprov [1.65.1.v20200529-1514,1.65.1.v20200529-1514]
org.bouncycastle.bcprov.source [1.65.1.v20200529-1514,1.65.1.v20200529-1514]
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]

+ 66
- 0
org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20201118210000.tpd View File

@@ -0,0 +1,66 @@
target "S20201118210000" with source configurePhase
// see https://download.eclipse.org/tools/orbit/downloads/

location "https://download.eclipse.org/tools/orbit/downloads/drops/S20201118210000/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.9.v20201106-1946,1.10.9.v20201106-1946]
org.apache.ant.source [1.10.9.v20201106-1946,1.10.9.v20201106-1946]
org.apache.commons.codec [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
org.apache.commons.codec.source [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
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.v20200830-2311,4.5.10.v20200830-2311]
org.apache.httpcomponents.httpclient.source [4.5.10.v20200830-2311,4.5.10.v20200830-2311]
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.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcpg.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcpkix [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcpkix.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
org.bouncycastle.bcprov [1.65.1.v20200529-1514,1.65.1.v20200529-1514]
org.bouncycastle.bcprov.source [1.65.1.v20200529-1514,1.65.1.v20200529-1514]
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.30.v20200204-2150,1.7.30.v20200204-2150]
org.slf4j.api.source [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
org.slf4j.binding.log4j12 [1.7.30.v20201108-2042,1.7.30.v20201108-2042]
org.slf4j.binding.log4j12.source [1.7.30.v20201108-2042,1.7.30.v20201108-2042]
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]
}

+ 17
- 17
org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd View File

@@ -1,20 +1,20 @@
target "jetty-9.4.x" with source configurePhase

location jetty-9.4.25 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/" {
org.eclipse.jetty.client [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.client.source [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.continuation [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.continuation.source [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.http [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.http.source [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.io [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.io.source [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.security [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.security.source [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.server [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.server.source [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.servlet [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.servlet.source [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.util [9.4.28.v20200408,9.4.28.v20200408]
org.eclipse.jetty.util.source [9.4.28.v20200408,9.4.28.v20200408]
location jetty-9.4.30 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/" {
org.eclipse.jetty.client [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.client.source [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.continuation [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.continuation.source [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.http [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.http.source [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.io [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.io.source [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.security [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.security.source [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.server [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.server.source [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.servlet [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.servlet.source [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.util [9.4.30.v20200611,9.4.30.v20200611]
org.eclipse.jetty.util.source [9.4.30.v20200611,9.4.30.v20200611]
}

+ 1
- 1
org.eclipse.jgit.packaging/pom.xml View File

@@ -212,7 +212,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<version>3.2.0</version>
<configuration>
<encoding>ISO-8859-1</encoding>
</configuration>

+ 19
- 1
org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsRemoteTest.java View File

@@ -33,7 +33,7 @@ public class LsRemoteTest extends CLIRepositoryTestCase {
git.add().addFilepattern("Test.txt").call();
git.commit().setMessage("Initial commit").call();

// create a master branch and switch to it
// create a test branch and switch to it
git.branchCreate().setName("test").call();
RefUpdate rup = db.updateRef(Constants.HEAD);
rup.link("refs/heads/test");
@@ -104,4 +104,22 @@ public class LsRemoteTest extends CLIRepositoryTestCase {
"" }, result.toArray());
}

@Test
public void testLsRemoteSymRefs() throws Exception {
final List<String> result = CLIGitCommand.execute(
"git ls-remote --symref " + shellQuote(db.getDirectory()), db);
assertArrayEquals(new String[] {
"ref: refs/heads/test HEAD",
"d0b1ef2b3dea02bb2ca824445c04e6def012c32c HEAD",
"d0b1ef2b3dea02bb2ca824445c04e6def012c32c refs/heads/master",
"d0b1ef2b3dea02bb2ca824445c04e6def012c32c refs/heads/test",
"efc02078d83a5226986ae917323acec7e1e8b7cb refs/tags/tag1",
"d0b1ef2b3dea02bb2ca824445c04e6def012c32c refs/tags/tag1^{}",
"4e4b837e0fd4ba83c003678b03592dc1509a4115 refs/tags/tag2",
"d0b1ef2b3dea02bb2ca824445c04e6def012c32c refs/tags/tag2^{}",
"489384bf8ace47522fe32093d2ceb85b65a6cbb1 refs/tags/tag3",
"d0b1ef2b3dea02bb2ca824445c04e6def012c32c refs/tags/tag3^{}",
"" }, result.toArray());
}

}

+ 2
- 0
org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties View File

@@ -256,6 +256,7 @@ usage_LsFiles=Show information about files in the index and the working tree
usage_LsRemote=List references in a remote repository
usage_lsRemoteHeads=Show only refs starting with refs/heads
usage_lsRemoteTags=Show only refs starting with refs/tags
usage_lsRemoteSymref=In addition to the object pointed at, show the underlying ref pointed at when showing a symbolic ref.
usage_LsTree=List the contents of a tree object
usage_MakeCacheTree=Show the current cache tree structure
usage_Match=Only consider tags matching the given glob(7) pattern or patterns, excluding the "refs/tags/" prefix.
@@ -294,6 +295,7 @@ usage_Status=Show the working tree status
usage_StopTrackingAFile=Stop tracking a file
usage_TextHashFunctions=Scan repository to compute maximum number of collisions for hash functions
usage_UpdateRemoteRepositoryFromLocalRefs=Update remote repository from local refs
usage_UseAll=Use all refs found in refs/
usage_UseTags=Use any tag including lightweight tags
usage_WriteDirCache=Write the DirCache
usage_abbrevCommits=abbreviate commits to N + 1 digits

+ 4
- 0
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java View File

@@ -32,6 +32,9 @@ class Describe extends TextBuiltin {
@Option(name = "--long", usage = "usage_LongFormat")
private boolean longDesc;

@Option(name = "--all", usage = "usage_UseTags")
private boolean useAll;

@Option(name = "--tags", usage = "usage_UseTags")
private boolean useTags;

@@ -50,6 +53,7 @@ class Describe extends TextBuiltin {
cmd.setTarget(tree);
}
cmd.setLong(longDesc);
cmd.setAll(useAll);
cmd.setTags(useTags);
cmd.setAlways(always);
cmd.setMatch(patterns.toArray(new String[0]));

+ 15
- 0
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java View File

@@ -34,6 +34,9 @@ class LsRemote extends TextBuiltin {
@Option(name = "--timeout", metaVar = "metaVar_service", usage = "usage_abortConnectionIfNoActivity")
int timeout = -1;

@Option(name = "--symref", usage = "usage_lsRemoteSymref")
private boolean symref;

@Argument(index = 0, metaVar = "metaVar_uriish", required = true)
private String remote;

@@ -47,6 +50,9 @@ class LsRemote extends TextBuiltin {
try {
refs.addAll(command.call());
for (Ref r : refs) {
if (symref && r.isSymbolic()) {
show(r.getTarget(), r.getName());
}
show(r.getObjectId(), r.getName());
if (r.getPeeledObjectId() != null) {
show(r.getPeeledObjectId(), r.getName() + "^{}"); //$NON-NLS-1$
@@ -70,4 +76,13 @@ class LsRemote extends TextBuiltin {
outw.print(name);
outw.println();
}

private void show(Ref ref, String name)
throws IOException {
outw.print("ref: ");
outw.print(ref.getName());
outw.print('\t');
outw.print(name);
outw.println();
}
}

+ 3
- 0
org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF View File

@@ -15,6 +15,9 @@ Import-Package: org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)",
org.apache.sshd.common.session;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)",
org.apache.sshd.server;version="[2.4.0,2.5.0)",
org.apache.sshd.server.forward;version="[2.4.0,2.5.0)",
org.eclipse.jgit.api;version="[6.0.0,6.1.0)",
org.eclipse.jgit.api.errors;version="[6.0.0,6.1.0)",
org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.0.0,6.1.0)",
org.eclipse.jgit.junit;version="[6.0.0,6.1.0)",

+ 438
- 6
org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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
@@ -11,16 +11,40 @@ package org.eclipse.jgit.transport.sshd;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.sshd.client.config.hosts.KnownHostEntry;
import org.apache.sshd.client.config.hosts.KnownHostHashValue;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.config.keys.PublicKeyEntry;
import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.apache.sshd.server.ServerAuthenticationManager;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.forward.StaticDecisionForwardingFilter;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.junit.ssh.SshTestBase;
import org.eclipse.jgit.lib.Constants;
@@ -156,7 +180,7 @@ public class ApacheSshTest extends SshTestBase {
"IdentityFile " + privateKey1.getAbsolutePath());
}

@Test (expected = TransportException.class)
@Test
public void testHugePreamble() throws Exception {
// Test that the connection fails when the preamble is longer than 64k.
StringBuilder b = new StringBuilder();
@@ -169,10 +193,418 @@ public class ApacheSshTest extends SshTestBase {
lines[i] = line;
}
server.setPreamble(lines);
cloneWith(
"ssh://" + TEST_USER + "@localhost:" + testPort
+ "/doesntmatter",
defaultCloneDir, null,
TransportException e = assertThrows(TransportException.class,
() -> cloneWith(
"ssh://" + TEST_USER + "@localhost:" + testPort
+ "/doesntmatter",
defaultCloneDir, null,
"IdentityFile " + privateKey1.getAbsolutePath()));
// The assertions test that we don't run into bug 565394 / SSHD-1050
assertFalse(e.getMessage().contains("timeout"));
assertTrue(e.getMessage().contains("65536")
|| e.getMessage().contains("closed"));
}

/**
* Test for SSHD-1028. If the server doesn't close sessions, the second
* fetch will fail. Occurs on sshd 2.5.[01].
*
* @throws Exception
* on errors
* @see <a href=
* "https://issues.apache.org/jira/projects/SSHD/issues/SSHD-1028">SSHD-1028</a>
*/
@Test
public void testCloneAndFetchWithSessionLimit() throws Exception {
PropertyResolverUtils.updateProperty(server.getPropertyResolver(),
ServerFactoryManager.MAX_CONCURRENT_SESSIONS, 2);
File localClone = cloneWith("ssh://localhost/doesntmatter",
defaultCloneDir, null, //
"Host localhost", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath());
// Fetch a couple of times
try (Git git = Git.open(localClone)) {
git.fetch().call();
git.fetch().call();
}
}

/**
* Creates a simple proxy server. Accepts only publickey authentication from
* the given user with the given key, allows all forwardings. Adds the
* proxy's host key to {@link #knownHosts}.
*
* @param user
* to accept
* @param userKey
* public key of that user at this server
* @param report
* single-element array to report back the forwarded address.
* @return the started server
* @throws Exception
*/
private SshServer createProxy(String user, File userKey,
SshdSocketAddress[] report) throws Exception {
SshServer proxy = SshServer.setUpDefaultServer();
// Give the server its own host key
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
KeyPair proxyHostKey = generator.generateKeyPair();
proxy.setKeyPairProvider(
session -> Collections.singletonList(proxyHostKey));
// Allow (only) publickey authentication
proxy.setUserAuthFactories(Collections.singletonList(
ServerAuthenticationManager.DEFAULT_USER_AUTH_PUBLIC_KEY_FACTORY));
// Install the user's public key
PublicKey userProxyKey = AuthorizedKeyEntry
.readAuthorizedKeys(userKey.toPath()).get(0)
.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
proxy.setPublickeyAuthenticator(
(userName, publicKey, session) -> user.equals(userName)
&& KeyUtils.compareKeys(userProxyKey, publicKey));
// Allow forwarding
proxy.setForwardingFilter(new StaticDecisionForwardingFilter(true) {

@Override
protected boolean checkAcceptance(String request, Session session,
SshdSocketAddress target) {
report[0] = target;
return super.checkAcceptance(request, session, target);
}
});
proxy.start();
// Add the proxy's host key to knownhosts
try (BufferedWriter writer = Files.newBufferedWriter(
knownHosts.toPath(), StandardCharsets.US_ASCII,
StandardOpenOption.WRITE, StandardOpenOption.APPEND)) {
writer.append('\n');
KnownHostHashValue.appendHostPattern(writer, "localhost",
proxy.getPort());
writer.append(',');
KnownHostHashValue.appendHostPattern(writer, "127.0.0.1",
proxy.getPort());
writer.append(' ');
PublicKeyEntry.appendPublicKeyEntry(writer,
proxyHostKey.getPublic());
writer.append('\n');
}
return proxy;
}

@Test
public void testJumpHost() throws Exception {
SshdSocketAddress[] forwarded = { null };
try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
forwarded)) {
try {
// Now try to clone via the proxy
cloneWith("ssh://server/doesntmatter", defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump " + TEST_USER + "X@proxy:" + proxy.getPort(), //
"", //
"Host proxy", //
"Hostname localhost", //
"IdentityFile " + privateKey2.getAbsolutePath());
assertNotNull(forwarded[0]);
assertEquals(testPort, forwarded[0].getPort());
} finally {
proxy.stop();
}
}
}

@Test
public void testJumpHostWrongKeyAtProxy() throws Exception {
// Test that we find the proxy server's URI in the exception message
SshdSocketAddress[] forwarded = { null };
try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
forwarded)) {
try {
// Now try to clone via the proxy
TransportException e = assertThrows(TransportException.class,
() -> cloneWith("ssh://server/doesntmatter",
defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(),
"ProxyJump " + TEST_USER + "X@proxy:"
+ proxy.getPort(), //
"", //
"Host proxy", //
"Hostname localhost", //
"IdentityFile "
+ privateKey1.getAbsolutePath()));
String message = e.getMessage();
assertTrue(message.contains("localhost:" + proxy.getPort()));
assertTrue(message.contains("proxy:" + proxy.getPort()));
} finally {
proxy.stop();
}
}
}

@Test
public void testJumpHostWrongKeyAtServer() throws Exception {
// Test that we find the target server's URI in the exception message
SshdSocketAddress[] forwarded = { null };
try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
forwarded)) {
try {
// Now try to clone via the proxy
TransportException e = assertThrows(TransportException.class,
() -> cloneWith("ssh://server/doesntmatter",
defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey2.getAbsolutePath(),
"ProxyJump " + TEST_USER + "X@proxy:"
+ proxy.getPort(), //
"", //
"Host proxy", //
"Hostname localhost", //
"IdentityFile "
+ privateKey2.getAbsolutePath()));
String message = e.getMessage();
assertTrue(message.contains("localhost:" + testPort));
assertTrue(message.contains("ssh://server"));
} finally {
proxy.stop();
}
}
}

@Test
public void testJumpHostNonSsh() throws Exception {
SshdSocketAddress[] forwarded = { null };
try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
forwarded)) {
try {
TransportException e = assertThrows(TransportException.class,
() -> cloneWith("ssh://server/doesntmatter",
defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump http://" + TEST_USER + "X@proxy:"
+ proxy.getPort(), //
"", //
"Host proxy", //
"Hostname localhost", //
"IdentityFile "
+ privateKey2.getAbsolutePath()));
// Find the expected message
Throwable t = e;
while (t != null) {
if (t instanceof URISyntaxException) {
break;
}
t = t.getCause();
}
assertNotNull(t);
assertTrue(t.getMessage().contains("Non-ssh"));
} finally {
proxy.stop();
}
}
}

@Test
public void testJumpHostWithPath() throws Exception {
SshdSocketAddress[] forwarded = { null };
try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
forwarded)) {
try {
TransportException e = assertThrows(TransportException.class,
() -> cloneWith("ssh://server/doesntmatter",
defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump ssh://" + TEST_USER + "X@proxy:"
+ proxy.getPort() + "/wrongPath", //
"", //
"Host proxy", //
"Hostname localhost", //
"IdentityFile "
+ privateKey2.getAbsolutePath()));
// Find the expected message
Throwable t = e;
while (t != null) {
if (t instanceof URISyntaxException) {
break;
}
t = t.getCause();
}
assertNotNull(t);
assertTrue(t.getMessage().contains("wrongPath"));
} finally {
proxy.stop();
}
}
}

@Test
public void testJumpHostWithPathShort() throws Exception {
SshdSocketAddress[] forwarded = { null };
try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
forwarded)) {
try {
TransportException e = assertThrows(TransportException.class,
() -> cloneWith("ssh://server/doesntmatter",
defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump " + TEST_USER + "X@proxy:wrongPath", //
"", //
"Host proxy", //
"Hostname localhost", //
"Port " + proxy.getPort(), //
"IdentityFile "
+ privateKey2.getAbsolutePath()));
// Find the expected message
Throwable t = e;
while (t != null) {
if (t instanceof URISyntaxException) {
break;
}
t = t.getCause();
}
assertNotNull(t);
assertTrue(t.getMessage().contains("wrongPath"));
} finally {
proxy.stop();
}
}
}

@Test
public void testJumpHostChain() throws Exception {
SshdSocketAddress[] forwarded1 = { null };
SshdSocketAddress[] forwarded2 = { null };
try (SshServer proxy1 = createProxy(TEST_USER + 'X', publicKey2,
forwarded1);
SshServer proxy2 = createProxy("foo", publicKey1, forwarded2)) {
try {
// Clone proxy1 -> proxy2 -> server
cloneWith("ssh://server/doesntmatter", defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump proxy2," + TEST_USER + "X@proxy:"
+ proxy1.getPort(), //
"", //
"Host proxy", //
"Hostname localhost", //
"IdentityFile " + privateKey2.getAbsolutePath(), //
"", //
"Host proxy2", //
"Hostname localhost", //
"User foo", //
"Port " + proxy2.getPort(), //
"IdentityFile " + privateKey1.getAbsolutePath());
assertNotNull(forwarded1[0]);
assertEquals(proxy2.getPort(), forwarded1[0].getPort());
assertNotNull(forwarded2[0]);
assertEquals(testPort, forwarded2[0].getPort());
} finally {
proxy1.stop();
proxy2.stop();
}
}
}

@Test
public void testJumpHostCascade() throws Exception {
SshdSocketAddress[] forwarded1 = { null };
SshdSocketAddress[] forwarded2 = { null };
try (SshServer proxy1 = createProxy(TEST_USER + 'X', publicKey2,
forwarded1);
SshServer proxy2 = createProxy("foo", publicKey1, forwarded2)) {
try {
// Clone proxy2 -> proxy1 -> server
cloneWith("ssh://server/doesntmatter", defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump " + TEST_USER + "X@proxy", //
"", //
"Host proxy", //
"Hostname localhost", //
"Port " + proxy1.getPort(), //
"ProxyJump ssh://proxy2:" + proxy2.getPort(), //
"IdentityFile " + privateKey2.getAbsolutePath(), //
"", //
"Host proxy2", //
"Hostname localhost", //
"User foo", //
"IdentityFile " + privateKey1.getAbsolutePath());
assertNotNull(forwarded1[0]);
assertEquals(testPort, forwarded1[0].getPort());
assertNotNull(forwarded2[0]);
assertEquals(proxy1.getPort(), forwarded2[0].getPort());
} finally {
proxy1.stop();
proxy2.stop();
}
}
}

@Test
public void testJumpHostRecursion() throws Exception {
SshdSocketAddress[] forwarded1 = { null };
SshdSocketAddress[] forwarded2 = { null };
try (SshServer proxy1 = createProxy(TEST_USER + 'X', publicKey2,
forwarded1);
SshServer proxy2 = createProxy("foo", publicKey1, forwarded2)) {
try {
TransportException e = assertThrows(TransportException.class,
() -> cloneWith(
"ssh://server/doesntmatter", defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump " + TEST_USER + "X@proxy", //
"", //
"Host proxy", //
"Hostname localhost", //
"Port " + proxy1.getPort(), //
"ProxyJump ssh://proxy2:" + proxy2.getPort(), //
"IdentityFile " + privateKey2.getAbsolutePath(), //
"", //
"Host proxy2", //
"Hostname localhost", //
"User foo", //
"ProxyJump " + TEST_USER + "X@proxy", //
"IdentityFile " + privateKey1.getAbsolutePath()));
assertTrue(e.getMessage().contains("proxy"));
} finally {
proxy1.stop();
proxy2.stop();
}
}
}
}

+ 1
- 0
org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF View File

@@ -45,6 +45,7 @@ Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
org.apache.sshd.client.future;version="[2.4.0,2.5.0)",
org.apache.sshd.client.keyverifier;version="[2.4.0,2.5.0)",
org.apache.sshd.client.session;version="[2.4.0,2.5.0)",
org.apache.sshd.client.session.forward;version="[2.4.0,2.5.0)",
org.apache.sshd.client.subsystem.sftp;version="[2.4.0,2.5.0)",
org.apache.sshd.common;version="[2.4.0,2.5.0)",
org.apache.sshd.common.auth;version="[2.4.0,2.5.0)",

+ 9
- 1
org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties View File

@@ -1,10 +1,14 @@
authenticationCanceled=Authentication canceled: no password
authenticationCanceled=SSH authentication canceled: no password given
authenticationOnClosedSession=Authentication canceled: session is already closing or closed
closeListenerFailed=Ssh session close listener failed
configInvalidPath=Invalid path in ssh config key {0}: {1}
configInvalidPattern=Invalid pattern in ssh config key {0}: {1}
configInvalidPositive=Ssh config entry {0} must be a strictly positive number but is ''{1}''
configInvalidProxyJump=Ssh config, host ''{0}'': Cannot parse ProxyJump ''{1}''
configNoKnownHostKeyAlgorithms=No implementations for any of the algorithms ''{0}'' given in HostKeyAlgorithms in the ssh config; using the default.
configNoRemainingHostKeyAlgorithms=Ssh config removed all host key algorithms: HostKeyAlgorithms ''{0}''
configProxyJumpNotSsh=Non-ssh URI in ProxyJump ssh config
configProxyJumpWithPath=ProxyJump ssh config: jump host specification must not have a path
ftpCloseFailed=Closing the SFTP channel failed
gssapiFailure=GSS-API error for mechanism OID {0}
gssapiInitFailure=GSS-API initialization failure for mechanism {0}
@@ -45,12 +49,14 @@ knownHostsUnknownKeyPrompt=Accept and store this key, and continue connecting?
knownHostsUnknownKeyType=Cannot read server key from known hosts file {0}; line {1}
knownHostsUserAskCreationMsg=File {0} does not exist.
knownHostsUserAskCreationPrompt=Create file {0} ?
loginDenied=Cannot log in at {0}:{1}
passwordPrompt=Password
proxyCannotAuthenticate=Cannot authenticate to proxy {0}
proxyHttpFailure=HTTP Proxy connection to {0} failed with code {1}: {2}
proxyHttpInvalidUserName=HTTP proxy connection {0} with invalid user name; must not contain colons: {1}
proxyHttpUnexpectedReply=Unexpected HTTP proxy response from {0}: {1}
proxyHttpUnspecifiedFailureReason=unspecified reason
proxyJumpAbort=ProxyJump chain too long at {0}
proxyPasswordPrompt=Proxy password
proxySocksAuthenticationFailed=Authentication to SOCKS5 proxy {0} failed
proxySocksFailureForbidden=SOCKS5 proxy {0}: connection to {1} not allowed by ruleset
@@ -75,7 +81,9 @@ serverIdNotReceived=No server identification received within {0} bytes
serverIdTooLong=Server identification is longer than 255 characters (including line ending): {0}
serverIdWithNul=Server identification contains a NUL character: {0}
sessionCloseFailed=Closing the session failed
sessionWithoutUsername=SSH session created without user name; cannot authenticate
sshClosingDown=Apache MINA sshd session factory is closing down; cannot create new ssh sessions on this factory
sshCommandTimeout={0} timed out after {1} seconds while opening the channel
sshProcessStillRunning={0} is not yet completed, cannot get exit code
sshProxySessionCloseFailed=Error while closing proxy session {0}
unknownProxyProtocol=Ignoring unknown proxy protocol {0}

+ 30
- 0
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/AuthenticationCanceledException.java View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> 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.internal.transport.sshd;

import java.util.concurrent.CancellationException;

/**
* An exception to report that the user canceled the SSH authentication.
*/
public class AuthenticationCanceledException extends CancellationException {

// If this is not a CancellationException sshd will try other authentication
// mechanisms.

private static final long serialVersionUID = 1L;

/**
* Creates a new {@link AuthenticationCanceledException}.
*/
public AuthenticationCanceledException() {
super(SshdText.get().authenticationCanceled);
}
}

+ 257
- 0
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java View File

@@ -18,21 +18,30 @@ import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.apache.sshd.client.ClientFactoryManager;
import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.future.AuthFuture;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.client.session.ClientSessionImpl;
import org.apache.sshd.client.session.ClientUserAuthService;
import org.apache.sshd.common.AttributeRepository;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
import org.apache.sshd.common.kex.KexState;
import org.apache.sshd.common.util.Readable;
import org.apache.sshd.common.util.buffer.Buffer;
import org.eclipse.jgit.errors.InvalidPatternException;
@@ -67,6 +76,17 @@ public class JGitClientSession extends ClientSessionImpl {

private volatile StatefulProxyConnector proxyHandler;

/**
* Work-around for bug 565394 / SSHD-1050; remove when using sshd 2.6.0.
*/
private volatile AuthFuture authFuture;

/** Records exceptions before there is an authFuture. */
private List<Throwable> earlyErrors = new ArrayList<>();

/** Guards setting an earlyError and the authFuture together. */
private final Object errorLock = new Object();

/**
* @param manager
* @param session
@@ -77,6 +97,125 @@ public class JGitClientSession extends ClientSessionImpl {
super(manager, session);
}

// BEGIN Work-around for bug 565394 / SSHD-1050
// Remove when using sshd 2.6.0.

@Override
public AuthFuture auth() throws IOException {
if (getUsername() == null) {
throw new IllegalStateException(
SshdText.get().sessionWithoutUsername);
}
ClientUserAuthService authService = getUserAuthService();
String serviceName = nextServiceName();
List<Throwable> errors = null;
AuthFuture future;
// Guard both getting early errors and setting authFuture
synchronized (errorLock) {
future = authService.auth(serviceName);
if (future == null) {
// Internal error; no translation.
throw new IllegalStateException(
"No auth future generated by service '" //$NON-NLS-1$
+ serviceName + '\'');
}
errors = earlyErrors;
earlyErrors = null;
authFuture = future;
}
if (errors != null && !errors.isEmpty()) {
Iterator<Throwable> iter = errors.iterator();
Throwable first = iter.next();
iter.forEachRemaining(t -> {
if (t != first && t != null) {
first.addSuppressed(t);
}
});
// Mark the future as having had an exception; just to be on the
// safe side. Actually, there shouldn't be anyone waiting on this
// future yet.
future.setException(first);
if (log.isDebugEnabled()) {
log.debug("auth({}) early exception type={}: {}", //$NON-NLS-1$
this, first.getClass().getSimpleName(),
first.getMessage());
}
if (first instanceof SshException) {
throw new SshException(
((SshException) first).getDisconnectCode(),
first.getMessage(), first);
}
throw new IOException(first.getMessage(), first);
}
return future;
}

@Override
protected void signalAuthFailure(AuthFuture future, Throwable t) {
signalAuthFailure(t);
}

private void signalAuthFailure(Throwable t) {
AuthFuture future = authFuture;
if (future == null) {
synchronized (errorLock) {
if (earlyErrors != null) {
earlyErrors.add(t);
}
future = authFuture;
}
}
if (future != null) {
future.setException(t);
}
if (log.isDebugEnabled()) {
boolean signalled = future != null && t == future.getException();
log.debug("signalAuthFailure({}) type={}, signalled={}: {}", this, //$NON-NLS-1$
t.getClass().getSimpleName(), Boolean.valueOf(signalled),
t.getMessage());
}
}

@Override
public void exceptionCaught(Throwable t) {
signalAuthFailure(t);
super.exceptionCaught(t);
}

@Override
protected void preClose() {
signalAuthFailure(
new SshException(SshdText.get().authenticationOnClosedSession));
super.preClose();
}

@Override
protected void handleDisconnect(int code, String msg, String lang,
Buffer buffer) throws Exception {
signalAuthFailure(new SshException(code, msg));
super.handleDisconnect(code, msg, lang, buffer);
}

@Override
protected <C extends Collection<ClientSessionEvent>> C updateCurrentSessionState(
C newState) {
if (closeFuture.isClosed()) {
newState.add(ClientSessionEvent.CLOSED);
}
if (isAuthenticated()) { // authFuture.isSuccess()
newState.add(ClientSessionEvent.AUTHED);
}
if (KexState.DONE.equals(getKexState())) {
AuthFuture future = authFuture;
if (future == null || future.isFailure()) {
newState.add(ClientSessionEvent.WAIT_AUTH);
}
}
return newState;
}

// END Work-around for bug 565394 / SSHD-1050

/**
* Retrieves the {@link HostConfigEntry} this session was created for.
*
@@ -419,4 +558,122 @@ public class JGitClientSession extends ClientSessionImpl {
return b.toString();
}

@Override
public <T> T getAttribute(AttributeKey<T> key) {
T value = super.getAttribute(key);
if (value == null) {
IoSession ioSession = getIoSession();
if (ioSession != null) {
Object obj = ioSession.getAttribute(AttributeRepository.class);
if (obj instanceof AttributeRepository) {
AttributeRepository sessionAttributes = (AttributeRepository) obj;
value = sessionAttributes.resolveAttribute(key);
}
}
}
return value;
}

@Override
public PropertyResolver getParentPropertyResolver() {
IoSession ioSession = getIoSession();
if (ioSession != null) {
Object obj = ioSession.getAttribute(AttributeRepository.class);
if (obj instanceof PropertyResolver) {
return (PropertyResolver) obj;
}
}
return super.getParentPropertyResolver();
}

/**
* An {@link AttributeRepository} that chains together two other attribute
* sources in a hierarchy.
*/
public static class ChainingAttributes implements AttributeRepository {

private final AttributeRepository delegate;

private final AttributeRepository parent;

/**
* Create a new {@link ChainingAttributes} attribute source.
*
* @param self
* to search for attributes first
* @param parent
* to search for attributes if not found in {@code self}
*/
public ChainingAttributes(AttributeRepository self,
AttributeRepository parent) {
this.delegate = self;
this.parent = parent;
}

@Override
public int getAttributesCount() {
return delegate.getAttributesCount();
}

@Override
public <T> T getAttribute(AttributeKey<T> key) {
return delegate.getAttribute(Objects.requireNonNull(key));
}

@Override
public Collection<AttributeKey<?>> attributeKeys() {
return delegate.attributeKeys();
}

@Override
public <T> T resolveAttribute(AttributeKey<T> key) {
T value = getAttribute(Objects.requireNonNull(key));
if (value == null) {
return parent.getAttribute(key);
}
return value;
}
}

/**
* A {@link ChainingAttributes} repository that doubles as a
* {@link PropertyResolver}. The property map can be set via the attribute
* key {@link SessionAttributes#PROPERTIES}.
*/
public static class SessionAttributes extends ChainingAttributes
implements PropertyResolver {

/** Key for storing a map of properties in the attributes. */
public static final AttributeKey<Map<String, Object>> PROPERTIES = new AttributeKey<>();

private final PropertyResolver parentProperties;

/**
* Creates a new {@link SessionAttributes} attribute and property
* source.
*
* @param self
* to search for attributes first
* @param parent
* to search for attributes if not found in {@code self}
* @param parentProperties
* to search for properties if not found in {@code self}
*/
public SessionAttributes(AttributeRepository self,
AttributeRepository parent, PropertyResolver parentProperties) {
super(self, parent);
this.parentProperties = parentProperties;
}

@Override
public PropertyResolver getParentPropertyResolver() {
return parentProperties;
}

@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = getAttribute(PROPERTIES);
return props == null ? Collections.emptyMap() : props;
}
}
}

+ 1
- 3
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java View File

@@ -9,8 +9,6 @@
*/
package org.eclipse.jgit.internal.transport.sshd;

import java.util.concurrent.CancellationException;

import org.apache.sshd.client.ClientAuthenticationManager;
import org.apache.sshd.client.auth.keyboard.UserInteraction;
import org.apache.sshd.client.auth.password.UserAuthPassword;
@@ -49,7 +47,7 @@ public class JGitPasswordAuthentication extends UserAuthPassword {
}
String password = getPassword(session, interaction);
if (password == null) {
throw new CancellationException();
throw new AuthenticationCanceledException();
}
// sendPassword takes a buffer as first argument, but actually doesn't
// use it and creates its own buffer...

+ 78
- 35
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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
@@ -23,12 +23,16 @@ import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.sshd.client.ClientAuthenticationManager;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.future.ConnectFuture;
@@ -45,6 +49,9 @@ import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.session.SessionContext;
import org.apache.sshd.common.session.helpers.AbstractSession;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.eclipse.jgit.internal.transport.sshd.JGitClientSession.ChainingAttributes;
import org.eclipse.jgit.internal.transport.sshd.JGitClientSession.SessionAttributes;
import org.eclipse.jgit.internal.transport.sshd.proxy.HttpClientConnector;
import org.eclipse.jgit.internal.transport.sshd.proxy.Socks5ClientConnector;
import org.eclipse.jgit.transport.CredentialsProvider;
@@ -52,6 +59,7 @@ import org.eclipse.jgit.transport.SshConstants;
import org.eclipse.jgit.transport.sshd.KeyCache;
import org.eclipse.jgit.transport.sshd.ProxyData;
import org.eclipse.jgit.transport.sshd.ProxyDataFactory;
import org.eclipse.jgit.util.StringUtils;

/**
* Customized {@link SshClient} for JGit. It creates specialized
@@ -75,6 +83,16 @@ public class JGitSshClient extends SshClient {
*/
public static final AttributeKey<String> PREFERRED_AUTHENTICATIONS = new AttributeKey<>();

/**
* An attribute key for storing an alternate local address to connect to if
* a local forward from a ProxyJump ssh config is present. If set,
* {@link #connect(HostConfigEntry, AttributeRepository, SocketAddress)}
* will not connect to the address obtained from the {@link HostConfigEntry}
* but to the address stored in this key (which is assumed to forward the
* {@code HostConfigEntry} address).
*/
public static final AttributeKey<SshdSocketAddress> LOCAL_FORWARD_ADDRESS = new AttributeKey<>();

private KeyCache keyCache;

private CredentialsProvider credentialsProvider;
@@ -95,40 +113,72 @@ public class JGitSshClient extends SshClient {
throw new IllegalStateException("SshClient not started."); //$NON-NLS-1$
}
Objects.requireNonNull(hostConfig, "No host configuration"); //$NON-NLS-1$
String host = ValidateUtils.checkNotNullAndNotEmpty(
String originalHost = ValidateUtils.checkNotNullAndNotEmpty(
hostConfig.getHostName(), "No target host"); //$NON-NLS-1$
int port = hostConfig.getPort();
ValidateUtils.checkTrue(port > 0, "Invalid port: %d", port); //$NON-NLS-1$
int originalPort = hostConfig.getPort();
ValidateUtils.checkTrue(originalPort > 0, "Invalid port: %d", //$NON-NLS-1$
originalPort);
InetSocketAddress originalAddress = new InetSocketAddress(originalHost,
originalPort);
InetSocketAddress targetAddress = originalAddress;
String userName = hostConfig.getUsername();
InetSocketAddress address = new InetSocketAddress(host, port);
ConnectFuture connectFuture = new DefaultConnectFuture(
userName + '@' + address, null);
String id = userName + '@' + originalAddress;
AttributeRepository attributes = chain(context, this);
SshdSocketAddress localForward = attributes
.resolveAttribute(LOCAL_FORWARD_ADDRESS);
if (localForward != null) {
targetAddress = new InetSocketAddress(localForward.getHostName(),
localForward.getPort());
id += '/' + targetAddress.toString();
}
ConnectFuture connectFuture = new DefaultConnectFuture(id, null);
SshFutureListener<IoConnectFuture> listener = createConnectCompletionListener(
connectFuture, userName, address, hostConfig);
// sshd needs some entries from the host config already in the
// constructor of the session. Put those as properties on this client,
// where it will find them. We can set the host config only once the
// session object has been created.
copyProperty(
hostConfig.getProperty(SshConstants.PREFERRED_AUTHENTICATIONS,
getAttribute(PREFERRED_AUTHENTICATIONS)),
PREFERRED_AUTHS);
setAttribute(HOST_CONFIG_ENTRY, hostConfig);
setAttribute(ORIGINAL_REMOTE_ADDRESS, address);
connectFuture, userName, originalAddress, hostConfig);
attributes = sessionAttributes(attributes, hostConfig, originalAddress);
// Proxy support
ProxyData proxy = getProxyData(address);
if (proxy != null) {
address = configureProxy(proxy, address);
proxy.clearPassword();
if (localForward == null) {
ProxyData proxy = getProxyData(targetAddress);
if (proxy != null) {
targetAddress = configureProxy(proxy, targetAddress);
proxy.clearPassword();
}
}
connector.connect(address, this, localAddress).addListener(listener);
connector.connect(targetAddress, attributes, localAddress)
.addListener(listener);
return connectFuture;
}

private void copyProperty(String value, String key) {
if (value != null && !value.isEmpty()) {
getProperties().put(key, value);
private AttributeRepository chain(AttributeRepository self,
AttributeRepository parent) {
if (self == null) {
return Objects.requireNonNull(parent);
}
if (parent == null || parent == self) {
return self;
}
return new ChainingAttributes(self, parent);
}

private AttributeRepository sessionAttributes(AttributeRepository parent,
HostConfigEntry hostConfig, InetSocketAddress originalAddress) {
// sshd needs some entries from the host config already in the
// constructor of the session. Put those into a dedicated
// AttributeRepository for the new session where it will find them.
// We can set the host config only once the session object has been
// created.
Map<AttributeKey<?>, Object> data = new HashMap<>();
data.put(HOST_CONFIG_ENTRY, hostConfig);
data.put(ORIGINAL_REMOTE_ADDRESS, originalAddress);
String preferredAuths = hostConfig.getProperty(
SshConstants.PREFERRED_AUTHENTICATIONS,
resolveAttribute(PREFERRED_AUTHENTICATIONS));
if (!StringUtils.isEmptyOrNull(preferredAuths)) {
data.put(SessionAttributes.PROPERTIES,
Collections.singletonMap(PREFERRED_AUTHS, preferredAuths));
}
return new SessionAttributes(
AttributeRepository.ofAttributesMap(data),
parent, this);
}

private ProxyData getProxyData(InetSocketAddress remoteAddress) {
@@ -219,11 +269,6 @@ public class JGitSshClient extends SshClient {
int numberOfPasswordPrompts = getNumberOfPasswordPrompts(hostConfig);
session.getProperties().put(PASSWORD_PROMPTS,
Integer.valueOf(numberOfPasswordPrompts));
FilePasswordProvider passwordProvider = getFilePasswordProvider();
if (passwordProvider instanceof RepeatingFilePasswordProvider) {
((RepeatingFilePasswordProvider) passwordProvider)
.setAttempts(numberOfPasswordPrompts);
}
List<Path> identities = hostConfig.getIdentities().stream()
.map(s -> {
try {
@@ -237,6 +282,7 @@ public class JGitSshClient extends SshClient {
.collect(Collectors.toList());
CachingKeyPairProvider ourConfiguredKeysProvider = new CachingKeyPairProvider(
identities, keyCache);
FilePasswordProvider passwordProvider = getFilePasswordProvider();
ourConfiguredKeysProvider.setPasswordFinder(passwordProvider);
if (hostConfig.isIdentitiesOnly()) {
session.setKeyIdentityProvider(ourConfiguredKeysProvider);
@@ -265,9 +311,7 @@ public class JGitSshClient extends SshClient {
log.warn(format(SshdText.get().configInvalidPositive,
SshConstants.NUMBER_OF_PASSWORD_PROMPTS, prompts));
}
// Default for NumberOfPasswordPrompts according to
// https://man.openbsd.org/ssh_config
return 3;
return ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS;
}

/**
@@ -408,6 +452,5 @@ public class JGitSshClient extends SshClient {

};
}

}
}

+ 48
- 21
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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
@@ -16,8 +16,12 @@ import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;

import org.apache.sshd.client.ClientAuthenticationManager;
import org.apache.sshd.common.AttributeRepository.AttributeKey;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.session.SessionContext;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.transport.CredentialsProvider;
@@ -25,39 +29,61 @@ import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;

/**
* A bridge from sshd's {@link RepeatingFilePasswordProvider} to our
* A bridge from sshd's {@link FilePasswordProvider} to our per-session
* {@link KeyPasswordProvider} API.
*/
public class PasswordProviderWrapper implements RepeatingFilePasswordProvider {
public class PasswordProviderWrapper implements FilePasswordProvider {

private final KeyPasswordProvider delegate;
private static final AttributeKey<PerSessionState> STATE = new AttributeKey<>();

private Map<String, AtomicInteger> counts = new ConcurrentHashMap<>();
private static class PerSessionState {

Map<String, AtomicInteger> counts = new ConcurrentHashMap<>();

KeyPasswordProvider delegate;

/**
* @param delegate
*/
public PasswordProviderWrapper(@NonNull KeyPasswordProvider delegate) {
this.delegate = delegate;
}

@Override
public void setAttempts(int numberOfPasswordPrompts) {
delegate.setAttempts(numberOfPasswordPrompts);
private final Supplier<KeyPasswordProvider> factory;

/**
* Creates a new {@link PasswordProviderWrapper}.
*
* @param factory
* to use to create per-session {@link KeyPasswordProvider}s
*/
public PasswordProviderWrapper(
@NonNull Supplier<KeyPasswordProvider> factory) {
this.factory = factory;
}

@Override
public int getAttempts() {
return delegate.getAttempts();
private PerSessionState getState(SessionContext context) {
PerSessionState state = context.getAttribute(STATE);
if (state == null) {
state = new PerSessionState();
state.delegate = factory.get();
Integer maxNumberOfAttempts = context
.getInteger(ClientAuthenticationManager.PASSWORD_PROMPTS);
if (maxNumberOfAttempts != null
&& maxNumberOfAttempts.intValue() > 0) {
state.delegate.setAttempts(maxNumberOfAttempts.intValue());
} else {
state.delegate.setAttempts(
ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS);
}
context.setAttribute(STATE, state);
}
return state;
}

@Override
public String getPassword(SessionContext session, NamedResource resource,
int attemptIndex) throws IOException {
String key = resource.getName();
int attempt = counts
PerSessionState state = getState(session);
int attempt = state.counts
.computeIfAbsent(key, k -> new AtomicInteger()).get();
char[] passphrase = delegate.getPassphrase(toUri(key), attempt);
char[] passphrase = state.delegate.getPassphrase(toUri(key), attempt);
if (passphrase == null) {
return null;
}
@@ -74,18 +100,19 @@ public class PasswordProviderWrapper implements RepeatingFilePasswordProvider {
String password, Exception err)
throws IOException, GeneralSecurityException {
String key = resource.getName();
AtomicInteger count = counts.get(key);
PerSessionState state = getState(session);
AtomicInteger count = state.counts.get(key);
int numberOfAttempts = count == null ? 0 : count.incrementAndGet();
ResourceDecodeResult result = null;
try {
if (delegate.keyLoaded(toUri(key), numberOfAttempts, err)) {
if (state.delegate.keyLoaded(toUri(key), numberOfAttempts, err)) {
result = ResourceDecodeResult.RETRY;
} else {
result = ResourceDecodeResult.TERMINATE;
}
} finally {
if (result != ResourceDecodeResult.RETRY) {
counts.remove(key);
state.counts.remove(key);
}
}
return result;

+ 0
- 41
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java View File

@@ -1,41 +0,0 @@
/*
* Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> 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.internal.transport.sshd;

import org.apache.sshd.common.config.keys.FilePasswordProvider;

/**
* A {@link FilePasswordProvider} augmented to support repeatedly asking for
* passwords.
*
*/
public interface RepeatingFilePasswordProvider extends FilePasswordProvider {

/**
* Define the maximum number of attempts to get a password that should be
* attempted for one identity resource through this provider.
*
* @param numberOfPasswordPrompts
* number of times to ask for a password;
* {@link IllegalArgumentException} may be thrown if <= 0
*/
void setAttempts(int numberOfPasswordPrompts);

/**
* Gets the maximum number of attempts to get a password that should be
* attempted for one identity resource through this provider.
*
* @return the maximum number of attempts to try, always >= 1.
*/
default int getAttempts() {
return 1;
}

}

+ 8
- 0
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java View File

@@ -19,12 +19,16 @@ public final class SshdText extends TranslationBundle {

// @formatter:off
/***/ public String authenticationCanceled;
/***/ public String authenticationOnClosedSession;
/***/ public String closeListenerFailed;
/***/ public String configInvalidPath;
/***/ public String configInvalidPattern;
/***/ public String configInvalidPositive;
/***/ public String configInvalidProxyJump;
/***/ public String configNoKnownHostKeyAlgorithms;
/***/ public String configNoRemainingHostKeyAlgorithms;
/***/ public String configProxyJumpNotSsh;
/***/ public String configProxyJumpWithPath;
/***/ public String ftpCloseFailed;
/***/ public String gssapiFailure;
/***/ public String gssapiInitFailure;
@@ -57,12 +61,14 @@ public final class SshdText extends TranslationBundle {
/***/ public String knownHostsUnknownKeyType;
/***/ public String knownHostsUserAskCreationMsg;
/***/ public String knownHostsUserAskCreationPrompt;
/***/ public String loginDenied;
/***/ public String passwordPrompt;
/***/ public String proxyCannotAuthenticate;
/***/ public String proxyHttpFailure;
/***/ public String proxyHttpInvalidUserName;
/***/ public String proxyHttpUnexpectedReply;
/***/ public String proxyHttpUnspecifiedFailureReason;
/***/ public String proxyJumpAbort;
/***/ public String proxyPasswordPrompt;
/***/ public String proxySocksAuthenticationFailed;
/***/ public String proxySocksFailureForbidden;
@@ -87,9 +93,11 @@ public final class SshdText extends TranslationBundle {
/***/ public String serverIdTooLong;
/***/ public String serverIdWithNul;
/***/ public String sessionCloseFailed;
/***/ public String sessionWithoutUsername;
/***/ public String sshClosingDown;
/***/ public String sshCommandTimeout;
/***/ public String sshProcessStillRunning;
/***/ public String sshProxySessionCloseFailed;
/***/ public String unknownProxyProtocol;

}

+ 5
- 46
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpParser.java View File

@@ -13,6 +13,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jgit.util.HttpSupport;

/**
* A basic parser for HTTP response headers. Handles status lines and
* authentication headers (WWW-Authenticate, Proxy-Authenticate).
@@ -135,7 +137,7 @@ public final class HttpParser {
int length = header.length();
for (int i = 0; i < length;) {
int start = skipWhiteSpace(header, i);
int end = scanToken(header, start);
int end = HttpSupport.scanToken(header, start);
if (end <= start) {
break;
}
@@ -156,7 +158,7 @@ public final class HttpParser {
// optional legacy whitespace around the equals sign), where the
// value can be either a token or a quoted string.
start = skipWhiteSpace(header, start);
int end = scanToken(header, start);
int end = HttpSupport.scanToken(header, start);
if (end == start) {
// Nothing found. Either at end or on a comma.
if (start < header.length() && header.charAt(start) == ',') {
@@ -222,7 +224,7 @@ public final class HttpParser {
challenge.addArgument(header.substring(start, end), value);
start = nextEnd[0];
} else {
int nextEnd = scanToken(header, nextStart);
int nextEnd = HttpSupport.scanToken(header, nextStart);
challenge.addArgument(header.substring(start, end),
header.substring(nextStart, nextEnd));
start = nextEnd;
@@ -244,49 +246,6 @@ public final class HttpParser {
return i;
}

private static int scanToken(String header, int from) {
int length = header.length();
int i = from;
while (i < length) {
char c = header.charAt(i);
switch (c) {
case '!':
case '#':
case '$':
case '%':
case '&':
case '\'':
case '*':
case '+':
case '-':
case '.':
case '^':
case '_':
case '`':
case '|':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
i++;
break;
default:
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
i++;
break;
}
return i;
}
}
return i;
}

private static String scanQuotedString(String header, int from, int[] to) {
StringBuilder result = new StringBuilder();
int length = header.length();

+ 61
- 11
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/IdentityPasswordProvider.java View File

@@ -19,13 +19,14 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CancellationException;

import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.internal.transport.sshd.AuthenticationCanceledException;
import org.eclipse.jgit.internal.transport.sshd.SshdText;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.StringUtils;

/**
* A {@link KeyPasswordProvider} based on a {@link CredentialsProvider}.
@@ -155,34 +156,83 @@ public class IdentityPasswordProvider implements KeyPasswordProvider {
state.incCount();
String message = state.count == 1 ? SshdText.get().keyEncryptedMsg
: SshdText.get().keyEncryptedRetry;
char[] pass = getPassword(uri, message);
char[] pass = getPassword(uri, format(message, uri));
state.setPassword(pass);
return pass;
}

private char[] getPassword(URIish uri, String message) {
/**
* Retrieves the JGit {@link CredentialsProvider} to use for user
* interaction.
*
* @return the {@link CredentialsProvider} or {@code null} if none
* configured
* @since 5.10
*/
protected CredentialsProvider getCredentialsProvider() {
return provider;
}

/**
* Obtains the passphrase/password for an encrypted private key via the
* {@link #getCredentialsProvider() configured CredentialsProvider}.
*
* @param uri
* identifying the resource to obtain a password for
* @param message
* optional message text to display; may be {@code null} or empty
* if none
* @return the password entered, or {@code null} if no
* {@link CredentialsProvider} is configured or none was entered
* @throws java.util.concurrent.CancellationException
* if the user canceled the operation
* @since 5.10
*/
protected char[] getPassword(URIish uri, String message) {
if (provider == null) {
return null;
}
List<CredentialItem> items = new ArrayList<>(2);
items.add(new CredentialItem.InformationalMessage(
format(message, uri)));
boolean haveMessage = !StringUtils.isEmptyOrNull(message);
List<CredentialItem> items = new ArrayList<>(haveMessage ? 2 : 1);
if (haveMessage) {
items.add(new CredentialItem.InformationalMessage(message));
}
CredentialItem.Password password = new CredentialItem.Password(
SshdText.get().keyEncryptedPrompt);
items.add(password);
try {
provider.get(uri, items);
boolean completed = provider.get(uri, items);
char[] pass = password.getValue();
if (pass == null) {
throw new CancellationException(
SshdText.get().authenticationCanceled);
if (!completed) {
cancelAuthentication();
return null;
}
return pass.clone();
return pass == null ? null : pass.clone();
} finally {
password.clear();
}
}

/**
* Cancels the authentication process. Called by
* {@link #getPassword(URIish, String)} when the user interaction has been
* canceled. If this throws a
* {@link java.util.concurrent.CancellationException}, the authentication
* process is aborted; otherwise it may continue with the next configured
* authentication mechanism, if any.
* <p>
* This default implementation always throws a
* {@link java.util.concurrent.CancellationException}.
* </p>
*
* @throws java.util.concurrent.CancellationException
* always
* @since 5.10
*/
protected void cancelAuthentication() {
throw new AuthenticationCanceledException();
}

/**
* Invoked to inform the password provider about the decoding result.
*

+ 197
- 48
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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
@@ -10,37 +10,53 @@
package org.eclipse.jgit.transport.sshd;

import static java.text.MessageFormat.format;
import static org.apache.sshd.common.SshConstants.SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.regex.Pattern;

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.future.ConnectFuture;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.client.session.forward.PortForwardingTracker;
import org.apache.sshd.client.subsystem.sftp.SftpClient;
import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle;
import org.apache.sshd.client.subsystem.sftp.SftpClient.CopyMode;
import org.apache.sshd.client.subsystem.sftp.SftpClientFactory;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.AttributeRepository;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.subsystem.sftp.SftpException;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.transport.sshd.JGitSshClient;
import org.eclipse.jgit.internal.transport.sshd.SshdText;
import org.eclipse.jgit.transport.FtpChannel;
import org.eclipse.jgit.transport.RemoteSession;
import org.eclipse.jgit.transport.SshConstants;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@@ -54,6 +70,11 @@ public class SshdSession implements RemoteSession {
private static final Logger LOG = LoggerFactory
.getLogger(SshdSession.class);

private static final Pattern SHORT_SSH_FORMAT = Pattern
.compile("[-\\w.]+(?:@[-\\w.]+)?(?::\\d+)?"); //$NON-NLS-1$

private static final int MAX_DEPTH = 10;

private final CopyOnWriteArrayList<SessionCloseListener> listeners = new CopyOnWriteArrayList<>();

private final URIish uri;
@@ -72,32 +93,169 @@ public class SshdSession implements RemoteSession {
client.start();
}
try {
String username = uri.getUser();
String host = uri.getHost();
int port = uri.getPort();
long t = timeout.toMillis();
if (t <= 0) {
session = client.connect(username, host, port).verify()
.getSession();
} else {
session = client.connect(username, host, port)
.verify(timeout.toMillis()).getSession();
}
session.addSessionListener(new SessionListener() {
session = connect(uri, Collections.emptyList(),
future -> notifyCloseListeners(), timeout, MAX_DEPTH);
} catch (IOException e) {
disconnect(e);
throw e;
}
}

@Override
public void sessionClosed(Session s) {
notifyCloseListeners();
private ClientSession connect(URIish target, List<URIish> jumps,
SshFutureListener<CloseFuture> listener, Duration timeout,
int depth) throws IOException {
if (--depth < 0) {
throw new IOException(
format(SshdText.get().proxyJumpAbort, target));
}
HostConfigEntry hostConfig = getHostConfig(target.getUser(),
target.getHost(), target.getPort());
String host = hostConfig.getHostName();
int port = hostConfig.getPort();
List<URIish> hops = determineHops(jumps, hostConfig, target.getHost());
ClientSession resultSession = null;
ClientSession proxySession = null;
PortForwardingTracker portForward = null;
try {
if (!hops.isEmpty()) {
URIish hop = hops.remove(0);
if (LOG.isDebugEnabled()) {
LOG.debug("Connecting to jump host {}", hop); //$NON-NLS-1$
}
});
proxySession = connect(hop, hops, null, timeout, depth);
}
AttributeRepository context = null;
if (proxySession != null) {
SshdSocketAddress remoteAddress = new SshdSocketAddress(host,
port);
portForward = proxySession.createLocalPortForwardingTracker(
SshdSocketAddress.LOCALHOST_ADDRESS, remoteAddress);
// We must connect to the locally bound address, not the one
// from the host config.
context = AttributeRepository.ofKeyValuePair(
JGitSshClient.LOCAL_FORWARD_ADDRESS,
portForward.getBoundAddress());
}
resultSession = connect(hostConfig, context, timeout);
if (proxySession != null) {
final PortForwardingTracker tracker = portForward;
final ClientSession pSession = proxySession;
resultSession.addCloseFutureListener(future -> {
IoUtils.closeQuietly(tracker);
String sessionName = pSession.toString();
try {
pSession.close();
} catch (IOException e) {
LOG.error(format(
SshdText.get().sshProxySessionCloseFailed,
sessionName), e);
}
});
portForward = null;
proxySession = null;
}
if (listener != null) {
resultSession.addCloseFutureListener(listener);
}
// Authentication timeout is by default 2 minutes.
session.auth().verify(session.getAuthTimeout());
resultSession.auth().verify(resultSession.getAuthTimeout());
return resultSession;
} catch (IOException e) {
disconnect(e);
close(portForward, e);
close(proxySession, e);
close(resultSession, e);
if (e instanceof SshException && ((SshException) e)
.getDisconnectCode() == SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE) {
// Ensure the user gets to know on which URI the authentication
// was denied.
throw new TransportException(target,
format(SshdText.get().loginDenied, host,
Integer.toString(port)),
e);
}
throw e;
}
}

private ClientSession connect(HostConfigEntry config,
AttributeRepository context, Duration timeout)
throws IOException {
ConnectFuture connected = client.connect(config, context, null);
long timeoutMillis = timeout.toMillis();
if (timeoutMillis <= 0) {
connected = connected.verify();
} else {
connected = connected.verify(timeoutMillis);
}
return connected.getSession();
}

private void close(Closeable toClose, Throwable error) {
if (toClose != null) {
try {
toClose.close();
} catch (IOException e) {
error.addSuppressed(e);
}
}
}

private HostConfigEntry getHostConfig(String username, String host,
int port) throws IOException {
HostConfigEntry entry = client.getHostConfigEntryResolver()
.resolveEffectiveHost(host, port, null, username, null);
if (entry == null) {
if (SshdSocketAddress.isIPv6Address(host)) {
return new HostConfigEntry("", host, port, username); //$NON-NLS-1$
}
return new HostConfigEntry(host, host, port, username);
}
return entry;
}

private List<URIish> determineHops(List<URIish> currentHops,
HostConfigEntry hostConfig, String host) throws IOException {
if (currentHops.isEmpty()) {
String jumpHosts = hostConfig.getProperty(SshConstants.PROXY_JUMP);
if (!StringUtils.isEmptyOrNull(jumpHosts)) {
try {
return parseProxyJump(jumpHosts);
} catch (URISyntaxException e) {
throw new IOException(
format(SshdText.get().configInvalidProxyJump, host,
jumpHosts),
e);
}
}
}
return currentHops;
}

private List<URIish> parseProxyJump(String proxyJump)
throws URISyntaxException {
String[] hops = proxyJump.split(","); //$NON-NLS-1$
List<URIish> result = new LinkedList<>();
for (String hop : hops) {
// There shouldn't be any whitespace, but let's be lenient
hop = hop.trim();
if (SHORT_SSH_FORMAT.matcher(hop).matches()) {
// URIish doesn't understand the short SSH format
// user@host:port, only user@host:path
hop = SshConstants.SSH_SCHEME + "://" + hop; //$NON-NLS-1$
}
URIish to = new URIish(hop);
if (!SshConstants.SSH_SCHEME.equalsIgnoreCase(to.getScheme())) {
throw new URISyntaxException(hop,
SshdText.get().configProxyJumpNotSsh);
} else if (!StringUtils.isEmptyOrNull(to.getPath())) {
throw new URISyntaxException(hop,
SshdText.get().configProxyJumpWithPath);
}
result.add(to);
}
return result;
}

/**
* Adds a {@link SessionCloseListener} to this session. Has no effect if the
* given {@code listener} is already registered with this session.
@@ -134,28 +292,23 @@ public class SshdSession implements RemoteSession {
public Process exec(String commandName, int timeout) throws IOException {
@SuppressWarnings("resource")
ChannelExec exec = session.createExecChannel(commandName);
long timeoutMillis = TimeUnit.SECONDS.toMillis(timeout);
try {
if (timeout <= 0) {
if (timeout <= 0) {
try {
exec.open().verify();
} else {
long start = System.nanoTime();
exec.open().verify(timeoutMillis);
timeoutMillis -= TimeUnit.NANOSECONDS
.toMillis(System.nanoTime() - start);
} catch (IOException | RuntimeException e) {
exec.close(true);
throw e;
}
} else {
try {
exec.open().verify(TimeUnit.SECONDS.toMillis(timeout));
} catch (IOException | RuntimeException e) {
exec.close(true);
throw new IOException(format(SshdText.get().sshCommandTimeout,
commandName, Integer.valueOf(timeout)), e);
}
} catch (IOException | RuntimeException e) {
exec.close(true);
throw e;
}
if (timeout > 0 && timeoutMillis <= 0) {
// We have used up the whole timeout for opening the channel
exec.close(true);
throw new InterruptedIOException(
format(SshdText.get().sshCommandTimeout, commandName,
Integer.valueOf(timeout)));
}
return new SshdExecProcess(exec, commandName, timeoutMillis);
return new SshdExecProcess(exec, commandName);
}

/**
@@ -195,14 +348,10 @@ public class SshdSession implements RemoteSession {

private final ChannelExec channel;

private final long timeoutMillis;

private final String commandName;

public SshdExecProcess(ChannelExec channel, String commandName,
long timeoutMillis) {
public SshdExecProcess(ChannelExec channel, String commandName) {
this.channel = channel;
this.timeoutMillis = timeoutMillis > 0 ? timeoutMillis : -1L;
this.commandName = commandName;
}

@@ -223,7 +372,7 @@ public class SshdSession implements RemoteSession {

@Override
public int waitFor() throws InterruptedException {
if (waitFor(timeoutMillis, TimeUnit.MILLISECONDS)) {
if (waitFor(-1L, TimeUnit.MILLISECONDS)) {
return exitValue();
}
return -1;
@@ -252,7 +401,7 @@ public class SshdSession implements RemoteSession {
@Override
public void destroy() {
if (channel.isOpen()) {
channel.close(true);
channel.close(false);
}
}
}

+ 21
- 10
org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, 2019 Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.sshd.client.ClientBuilder;
@@ -33,6 +34,7 @@ import org.apache.sshd.client.auth.UserAuthFactory;
import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory;
import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory;
import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.compression.BuiltinCompressions;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions;
@@ -40,6 +42,7 @@ import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile;
import org.eclipse.jgit.internal.transport.sshd.AuthenticationCanceledException;
import org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider;
import org.eclipse.jgit.internal.transport.sshd.GssApiWithMicAuthFactory;
import org.eclipse.jgit.internal.transport.sshd.JGitPasswordAuthFactory;
@@ -194,12 +197,11 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable {
home, sshDir);
KeyIdentityProvider defaultKeysProvider = toKeyIdentityProvider(
getDefaultKeys(sshDir));
KeyPasswordProvider passphrases = createKeyPasswordProvider(
credentialsProvider);
SshClient client = ClientBuilder.builder()
.factory(JGitSshClient::new)
.filePasswordProvider(
createFilePasswordProvider(passphrases))
.filePasswordProvider(createFilePasswordProvider(
() -> createKeyPasswordProvider(
credentialsProvider)))
.hostConfigEntryResolver(configFile)
.serverKeyVerifier(new JGitServerKeyVerifier(
getServerKeyDatabase(home, sshDir)))
@@ -230,7 +232,16 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable {
return session;
} catch (Exception e) {
unregister(session);
throw new TransportException(uri, e.getMessage(), e);
if (e instanceof TransportException) {
throw (TransportException) e;
}
Throwable cause = e;
if (e instanceof SshException && e
.getCause() instanceof AuthenticationCanceledException) {
// Results in a nicer error message
cause = e.getCause();
}
throw new TransportException(uri, cause.getMessage(), cause);
}
}

@@ -536,14 +547,14 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable {
/**
* Creates a {@link FilePasswordProvider} for a new session.
*
* @param provider
* the {@link KeyPasswordProvider} to delegate to
* @param providerFactory
* providing the {@link KeyPasswordProvider} to delegate to
* @return a new {@link FilePasswordProvider}
*/
@NonNull
private FilePasswordProvider createFilePasswordProvider(
KeyPasswordProvider provider) {
return new PasswordProviderWrapper(provider);
Supplier<KeyPasswordProvider> providerFactory) {
return new PasswordProviderWrapper(providerFactory);
}

/**

+ 0
- 4
org.eclipse.jgit.ssh.jsch/pom.xml View File

@@ -123,7 +123,6 @@
</configuration>
</plugin>

<!-- No previous version to compare to
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
@@ -165,13 +164,11 @@
</execution>
</executions>
</plugin>
-->
</plugins>
</build>

<reporting>
<plugins>
<!-- No previous version to compare to
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
@@ -212,7 +209,6 @@
<skip>false</skip>
</configuration>
</plugin>
-->
</plugins>
</reporting>
</project>

+ 1
- 1
org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java View File

@@ -198,7 +198,7 @@ public class JschSession implements RemoteSession {
@Override
public int exitValue() {
if (isRunning())
throw new IllegalStateException();
throw new IllegalThreadStateException();
return channel.getExitStatus();
}


+ 1
- 0
org.eclipse.jgit.test/META-INF/MANIFEST.MF View File

@@ -48,6 +48,7 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
org.eclipse.jgit.lfs;version="[6.0.0,6.1.0)",
org.eclipse.jgit.lib;version="[6.0.0,6.1.0)",
org.eclipse.jgit.lib.internal;version="[6.0.0,6.1.0)",
org.eclipse.jgit.logging;version="[6.0.0,6.1.0)",
org.eclipse.jgit.merge;version="[6.0.0,6.1.0)",
org.eclipse.jgit.nls;version="[6.0.0,6.1.0)",
org.eclipse.jgit.notes;version="[6.0.0,6.1.0)",

+ 1
- 1
org.eclipse.jgit.test/build.properties View File

@@ -8,4 +8,4 @@ bin.includes = META-INF/,\
bin-tst/,\
bin/
additional.bundles = org.apache.log4j,\
org.slf4j.impl.log4j12
org.slf4j.binding.log4j12

BIN
org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/gitgit.index.v4 View File


BIN
org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idx View File


BIN
org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idxV2 View File


+ 36
- 25
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java View File

@@ -92,7 +92,6 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
ObjectId id = git2.getRepository().resolve("tag-for-blob");
assertNotNull(id);
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
@@ -277,8 +276,7 @@ public class CloneCommandTest extends RepositoryTestCase {
Git git2 = command.call();
addRepoToClose(git2.getRepository());

assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
assertEquals("refs/heads/master", git2.getRepository().getFullBranch());
assertEquals(
"refs/heads/master, refs/remotes/origin/master, refs/remotes/origin/test",
allRefNames(git2.branchList().setListMode(ListMode.ALL).call()));
@@ -293,7 +291,6 @@ public class CloneCommandTest extends RepositoryTestCase {
git2 = command.call();
addRepoToClose(git2.getRepository());

assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
assertEquals("refs/remotes/origin/master, refs/remotes/origin/test",
allRefNames(git2.branchList().setListMode(ListMode.ALL).call()));
@@ -308,8 +305,7 @@ public class CloneCommandTest extends RepositoryTestCase {
git2 = command.call();
addRepoToClose(git2.getRepository());

assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
assertEquals("refs/heads/master", git2.getRepository().getFullBranch());
assertEquals("refs/heads/master, refs/heads/test", allRefNames(git2
.branchList().setListMode(ListMode.ALL).call()));
}
@@ -324,7 +320,6 @@ public class CloneCommandTest extends RepositoryTestCase {
Git git2 = command.call();
addRepoToClose(git2.getRepository());

assertNotNull(git2);
assertEquals("refs/heads/test", git2.getRepository().getFullBranch());
}

@@ -338,7 +333,6 @@ public class CloneCommandTest extends RepositoryTestCase {
Git git2 = command.call();
addRepoToClose(git2.getRepository());

assertNotNull(git2);
ObjectId taggedCommit = db.resolve("tag-initial^{commit}");
assertEquals(taggedCommit.name(), git2
.getRepository().getFullBranch());
@@ -355,10 +349,9 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertNull(git2.getRepository().resolve("tag-for-blob"));
assertNotNull(git2.getRepository().resolve("tag-initial"));
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
assertEquals("refs/heads/master", git2.getRepository().getFullBranch());
assertEquals("refs/remotes/origin/master", allRefNames(git2
.branchList().setListMode(ListMode.REMOTE).call()));
RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
@@ -383,10 +376,9 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setBare(true);
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertNull(git2.getRepository().resolve("tag-for-blob"));
assertNotNull(git2.getRepository().resolve("tag-initial"));
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
assertEquals("refs/heads/master", git2.getRepository().getFullBranch());
assertEquals("refs/heads/master", allRefNames(git2.branchList()
.setListMode(ListMode.ALL).call()));
RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
@@ -409,11 +401,10 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertTrue(git2.getRepository().isBare());
assertNotNull(git2.getRepository().resolve("tag-for-blob"));
assertNotNull(git2.getRepository().resolve("tag-initial"));
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
assertEquals("refs/heads/master", git2.getRepository().getFullBranch());
assertEquals("refs/heads/master, refs/heads/test", allRefNames(
git2.branchList().setListMode(ListMode.ALL).call()));
assertNotNull(git2.getRepository().exactRef("refs/meta/foo/bar"));
@@ -436,7 +427,6 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertNull(git2.getRepository().resolve("tag-for-blob"));
assertNull(git2.getRepository().resolve("refs/heads/master"));
assertNotNull(git2.getRepository().resolve("tag-initial"));
@@ -464,8 +454,7 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
assertEquals("refs/heads/test", git2.getRepository().getFullBranch());
// Expect both remote branches to exist; setCloneAllBranches(true)
// should override any setBranchesToClone().
assertNotNull(
@@ -492,8 +481,7 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
assertEquals("refs/heads/test", git2.getRepository().getFullBranch());
// Expect only the test branch; allBranches was re-set to false
assertNull(git2.getRepository().resolve("refs/remotes/origin/master"));
assertNotNull(git2.getRepository().resolve("refs/remotes/origin/test"));
@@ -525,7 +513,6 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
// clone again
command = Git.cloneRepository();
command.setDirectory(directory);
@@ -551,7 +538,6 @@ public class CloneCommandTest extends RepositoryTestCase {
clone.setURI(fileUri());
Git git2 = clone.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);

assertEquals(Constants.MASTER, git2.getRepository().getBranch());
}
@@ -595,7 +581,6 @@ public class CloneCommandTest extends RepositoryTestCase {
clone.setURI(fileUri());
Git git2 = clone.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);

assertEquals(Constants.MASTER, git2.getRepository().getBranch());
assertTrue(new File(git2.getRepository().getWorkTree(), path
@@ -683,7 +668,6 @@ public class CloneCommandTest extends RepositoryTestCase {
clone.setURI(git.getRepository().getDirectory().toURI().toString());
Git git2 = clone.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);

assertEquals(Constants.MASTER, git2.getRepository().getBranch());
assertTrue(new File(git2.getRepository().getWorkTree(), path
@@ -813,7 +797,6 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setNoTags();
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertNotNull(git2.getRepository().resolve("refs/heads/test"));
assertNull(git2.getRepository().resolve("tag-initial"));
assertNull(git2.getRepository().resolve("tag-for-blob"));
@@ -833,13 +816,41 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setTagOption(TagOpt.FETCH_TAGS);
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertNull(git2.getRepository().resolve("refs/heads/test"));
assertNotNull(git2.getRepository().resolve("tag-initial"));
assertNotNull(git2.getRepository().resolve("tag-for-blob"));
assertTagOption(git2.getRepository(), TagOpt.FETCH_TAGS);
}

@Test
public void testCloneWithHeadSymRefIsMasterCopy() throws IOException, GitAPIException {
// create a branch with the same head as master and switch to it
git.checkout().setStartPoint("master").setCreateBranch(true).setName("master-copy").call();

// when we clone the HEAD symref->master-copy means we start on master-copy and not master
File directory = createTempDirectory("testCloneRepositorySymRef_master-copy");
CloneCommand command = Git.cloneRepository();
command.setDirectory(directory);
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertEquals("refs/heads/master-copy", git2.getRepository().getFullBranch());
}

@Test
public void testCloneWithHeadSymRefIsNonMasterCopy() throws IOException, GitAPIException {
// create a branch with the same head as test and switch to it
git.checkout().setStartPoint("test").setCreateBranch(true).setName("test-copy").call();

File directory = createTempDirectory("testCloneRepositorySymRef_test-copy");
CloneCommand command = Git.cloneRepository();
command.setDirectory(directory);
command.setURI(fileUri());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertEquals("refs/heads/test-copy", git2.getRepository().getFullBranch());
}

private void assertTagOption(Repository repo, TagOpt expectedTagOption)
throws URISyntaxException {
RemoteConfig remoteConfig = new RemoteConfig(

+ 46
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java View File

@@ -310,7 +310,7 @@ public class DescribeCommandTest extends RepositoryTestCase {
assertEquals(
"2 commits for describe commit increment expected since lightweight tag: c4 and c3",
"t2-2-g119892b", describe(c4)); // 2 commits: c4 and c3
} else if (!useAnnotatedTags && !describeUseAllTags) {
} else if (!useAnnotatedTags) {
assertEquals("no matching commits expected", null, describe(c4));
} else {
assertEquals(
@@ -405,6 +405,46 @@ public class DescribeCommandTest extends RepositoryTestCase {
}
}

@Test
public void testDescribeUseAllRefsMaster() throws Exception {
final ObjectId c1 = modify("aaa");
tag("t1");

if (useAnnotatedTags || describeUseAllTags) {
assertEquals("t1", describe(c1));
} else {
assertEquals(null, describe(c1));
}
assertEquals("heads/master", describeAll(c1));
}

/**
* Branch off from master and then tag
*
* <pre>
* c1 -+ -> c2
* |
* +-> t1
* </pre>
* @throws Exception
* */
@Test
public void testDescribeUseAllRefsBranch() throws Exception {
final ObjectId c1 = modify("aaa");
modify("bbb");

branch("b", c1);
final ObjectId c3 = modify("ccc");
tag("t1");

if (!useAnnotatedTags && !describeUseAllTags) {
assertEquals(null, describe(c3));
} else {
assertEquals("t1", describe(c3));
}
assertEquals("heads/b", describeAll(c3));
}

private ObjectId merge(ObjectId c2) throws GitAPIException {
return git.merge().include(c2).call().getNewHead();
}
@@ -444,6 +484,11 @@ public class DescribeCommandTest extends RepositoryTestCase {
return describe(c1, false, false);
}

private String describeAll(ObjectId c1) throws GitAPIException, IOException {
return git.describe().setTarget(c1).setTags(describeUseAllTags)
.setLong(false).setAlways(false).setAll(true).call();
}

private String describe(ObjectId c1, String... patterns) throws Exception {
return git.describe().setTarget(c1).setTags(describeUseAllTags)
.setMatch(patterns).call();

+ 48
- 72
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java View File

@@ -1,43 +1,11 @@
/*
* Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com>
* Copyright (C) 2015, 2020 Ivan Motsch <ivan.motsch@bsiag.com> and others
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
* 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.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SPDX-License-Identifier: BSD-3-Clause
*/

package org.eclipse.jgit.api;
@@ -90,16 +58,20 @@ public class EolStreamTypeUtilTest {
testCheckout(TEXT_LF, AUTO_LF, "\r", "\r");
testCheckout(TEXT_LF, AUTO_LF, "\n", "\n");

testCheckout(TEXT_LF, AUTO_LF, "\r\n", "\n");
testCheckout(TEXT_LF, null, "\r\n", "\n");
testCheckout(null, AUTO_LF, "\r\n", "\r\n");
testCheckout(TEXT_LF, AUTO_LF, "\n\r", "\n\r");

testCheckout(TEXT_LF, AUTO_LF, "\n\r\n", "\n\n");
testCheckout(TEXT_LF, AUTO_LF, "\r\n\r", "\n\r");
testCheckout(TEXT_LF, null, "\n\r\n", "\n\n");
testCheckout(null, AUTO_LF, "\n\r\n", "\n\r\n");
testCheckout(TEXT_LF, null, "\r\n\r", "\n\r");
testCheckout(null, AUTO_LF, "\r\n\r", "\r\n\r");

testCheckout(TEXT_LF, AUTO_LF, "a\nb\n", "a\nb\n");
testCheckout(TEXT_LF, AUTO_LF, "a\rb\r", "a\rb\r");
testCheckout(TEXT_LF, AUTO_LF, "a\n\rb\n\r", "a\n\rb\n\r");
testCheckout(TEXT_LF, AUTO_LF, "a\r\nb\r\n", "a\nb\n");
testCheckout(TEXT_LF, null, "a\r\nb\r\n", "a\nb\n");
testCheckout(null, AUTO_LF, "a\r\nb\r\n", "a\r\nb\r\n");
}

@Test
@@ -153,45 +125,49 @@ public class EolStreamTypeUtilTest {
byte[] outputBytes = output.getBytes(UTF_8);
byte[] expectedConversionBytes = expectedConversion.getBytes(UTF_8);

// test using output text and assuming it was declared TEXT
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeText)) {
out.write(outputBytes);
if (streamTypeText != null) {
// test using output text and assuming it was declared TEXT
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeText)) {
out.write(outputBytes);
}
assertArrayEquals(expectedConversionBytes, b.toByteArray());
}
assertArrayEquals(expectedConversionBytes, b.toByteArray());

// test using ouput text and assuming it was declared AUTO, using binary
// detection
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeWithBinaryCheck)) {
out.write(outputBytes);
if (streamTypeWithBinaryCheck != null) {
// test using output text and assuming it was declared AUTO, using
// binary detection
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeWithBinaryCheck)) {
out.write(outputBytes);
}
assertArrayEquals(expectedConversionBytes, b.toByteArray());
}
assertArrayEquals(expectedConversionBytes, b.toByteArray());

// now pollute output text with some binary bytes
outputBytes = extendWithBinaryData(outputBytes);
expectedConversionBytes = extendWithBinaryData(expectedConversionBytes);

// again, test using output text and assuming it was declared TEXT
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeText)) {
out.write(outputBytes);
if (streamTypeText != null) {
// again, test using output text and assuming it was declared TEXT
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeText)) {
out.write(outputBytes);
}
assertArrayEquals(expectedConversionBytes, b.toByteArray());
}
assertArrayEquals(expectedConversionBytes, b.toByteArray());

// again, test using ouput text and assuming it was declared AUTO, using
// binary
// detection
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeWithBinaryCheck)) {
out.write(outputBytes);
if (streamTypeWithBinaryCheck != null) {
// again, test using output text and assuming it was declared AUTO,
// using binary detection
b = new ByteArrayOutputStream();
try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
streamTypeWithBinaryCheck)) {
out.write(outputBytes);
}
// expect no conversion
assertArrayEquals(outputBytes, b.toByteArray());
}
// expect no conversion
assertArrayEquals(outputBytes, b.toByteArray());
}

@Test

+ 25
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java View File

@@ -11,9 +11,11 @@ package org.eclipse.jgit.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.Collection;
import java.util.Optional;

import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
@@ -34,7 +36,7 @@ public class LsRemoteCommandTest extends RepositoryTestCase {
git.add().addFilepattern("Test.txt").call();
git.commit().setMessage("Initial commit").call();

// create a master branch and switch to it
// create a test branch and switch to it
git.branchCreate().setName("test").call();
RefUpdate rup = db.updateRef(Constants.HEAD);
rup.link("refs/heads/test");
@@ -104,6 +106,28 @@ public class LsRemoteCommandTest extends RepositoryTestCase {
assertEquals(2, refs.size());
}

@Test
public void testLsRemoteWithSymRefs() throws Exception {
File directory = createTempDirectory("testRepository");
CloneCommand command = Git.cloneRepository();
command.setDirectory(directory);
command.setURI(fileUri());
command.setCloneAllBranches(true);
Git git2 = command.call();
addRepoToClose(git2.getRepository());


LsRemoteCommand lsRemoteCommand = git2.lsRemote();
Collection<Ref> refs = lsRemoteCommand.call();
assertNotNull(refs);
assertEquals(6, refs.size());

Optional<Ref> headRef = refs.stream().filter(ref -> ref.getName().equals(Constants.HEAD)).findFirst();
assertTrue("expected a HEAD Ref", headRef.isPresent());
assertTrue("expected HEAD Ref to be a Symbolic", headRef.get().isSymbolic());
assertEquals("refs/heads/test", headRef.get().getTarget().getName());
}

private String fileUri() {
return "file://" + git.getRepository().getWorkTree().getAbsolutePath();
}

+ 12
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011, Kevin Sawicki <kevin@github.com> and others
* Copyright (C) 2011, 2020 Kevin Sawicki <kevin@github.com> 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
@@ -24,6 +24,7 @@ import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.StoredConfig;
@@ -309,6 +310,16 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
assertStageOneToThree(FILE1);
}

@Test
public void testCheckoutFileWithConflict() throws Exception {
setupConflictingState();
assertEquals('[' + FILE1 + ']',
git.status().call().getConflicting().toString());
git.checkout().setStartPoint(Constants.HEAD).addPath(FILE1).call();
assertEquals("3", read(FILE1));
assertTrue(git.status().call().isClean());
}

@Test
public void testCheckoutOursWhenNoBase() throws Exception {
String file = "added.txt";

+ 21
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java View File

@@ -160,4 +160,25 @@ public class StatusCommandTest extends RepositoryTestCase {
assertTrue("Expected no differences", status.isClean());
}
}

@Test
public void testFolderPrefix() throws Exception {
// "audio" is a prefix of "audio-new" and "audio.new".
try (Git git = new Git(db)) {
// Order here is the git order, but that doesn't really matter.
// They are processed by StatusCommand in this order even if written
// in a different order. Bug 566799 would, when having processed
// audio/foo, remove previously recorded untracked folders that have
// "audio" as a prefix: audio-new and audio.new.
writeTrashFile("audi", "foo", "foo");
writeTrashFile("audio-new", "foo", "foo");
writeTrashFile("audio.new", "foo", "foo");
writeTrashFile("audio", "foo", "foo");
writeTrashFile("audio_new", "foo", "foo");
Status stat = git.status().call();
assertEquals(Sets.of("audi", "audio-new", "audio.new", "audio",
"audio_new"), stat.getUntrackedFolders());
}
}

}

+ 68
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010, 2013 Google Inc. and others
* Copyright (C) 2010, 2020 Google Inc. 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
@@ -11,12 +11,16 @@
package org.eclipse.jgit.diff;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.junit.RepositoryTestCase;
@@ -73,6 +77,17 @@ public class DiffFormatterTest extends RepositoryTestCase {
super.tearDown();
}

@Test
public void testDefaultRenameDetectorSettings() throws Exception {
RenameDetector rd = df.getRenameDetector();
assertNull(rd);
df.setDetectRenames(true);
rd = df.getRenameDetector();
assertNotNull(rd);
assertEquals(400, rd.getRenameLimit());
assertEquals(60, rd.getRenameScore());
}

@Test
public void testCreateFileHeader_Add() throws Exception {
ObjectId adId = blob("a\nd\n");
@@ -454,6 +469,58 @@ public class DiffFormatterTest extends RepositoryTestCase {
}
}

@Test
public void testTrackedFileInIgnoredFolderUnchanged()
throws Exception {
commitFile("empty/empty/foo", "", "master");
commitFile(".gitignore", "empty/*", "master");
try (Git git = new Git(db)) {
Status status = git.status().call();
assertTrue(status.isClean());
}
try (ByteArrayOutputStream os = new ByteArrayOutputStream();
DiffFormatter dfmt = new DiffFormatter(os)) {
dfmt.setRepository(db);
dfmt.format(new DirCacheIterator(db.readDirCache()),
new FileTreeIterator(db));
dfmt.flush();

String actual = os.toString("UTF-8");

assertEquals("", actual);
}
}

@Test
public void testTrackedFileInIgnoredFolderChanged()
throws Exception {
String expectedDiff = "diff --git a/empty/empty/foo b/empty/empty/foo\n"
+ "index e69de29..5ea2ed4 100644\n" //
+ "--- a/empty/empty/foo\n" //
+ "+++ b/empty/empty/foo\n" //
+ "@@ -0,0 +1 @@\n" //
+ "+changed\n";

commitFile("empty/empty/foo", "", "master");
commitFile(".gitignore", "empty/*", "master");
try (Git git = new Git(db)) {
Status status = git.status().call();
assertTrue(status.isClean());
}
try (ByteArrayOutputStream os = new ByteArrayOutputStream();
DiffFormatter dfmt = new DiffFormatter(os)) {
writeTrashFile("empty/empty/foo", "changed\n");
dfmt.setRepository(db);
dfmt.format(new DirCacheIterator(db.readDirCache()),
new FileTreeIterator(db));
dfmt.flush();

String actual = os.toString("UTF-8");

assertEquals(expectedDiff, actual);
}
}

@Test
public void testDiffAutoCrlfSmallFile() throws Exception {
String content = "01234\r\n01234\r\n01234\r\n";

+ 134
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheAfterCloneTest.java View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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.dircache;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.EnumSet;
import java.util.Set;

import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Test;

/**
* Tests for initial DirCache version after a clone or after a mixed or hard
* reset.
*/
public class DirCacheAfterCloneTest extends RepositoryTestCase {

@Override
public void setUp() throws Exception {
super.setUp();
try (Git git = new Git(db)) {
writeTrashFile("Test.txt", "Hello world");
git.add().addFilepattern("Test.txt").call();
git.commit().setMessage("Initial commit").call();
}
}

private DirCacheVersion cloneAndCheck(Set<DirCacheVersion> expected)
throws Exception {
File directory = createTempDirectory("testCloneRepository");
CloneCommand command = Git.cloneRepository();
command.setDirectory(directory);
command.setURI("file://" + db.getWorkTree().getAbsolutePath());
Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
DirCache dc = DirCache.read(git2.getRepository());
DirCacheVersion version = dc.getVersion();
assertTrue(expected.contains(version));
return version;
}

@Test
public void testCloneV3OrV2() throws Exception {
cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
DirCacheVersion.DIRC_VERSION_EXTENDED));
}

@Test
public void testCloneV4() throws Exception {
StoredConfig cfg = SystemReader.getInstance().getUserConfig();
cfg.load();
cfg.setInt("index", null, "version", 4);
cfg.save();
cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS));
}

@Test
public void testCloneV4manyFiles() throws Exception {
StoredConfig cfg = SystemReader.getInstance().getUserConfig();
cfg.load();
cfg.setBoolean("feature", null, "manyFiles", true);
cfg.save();
cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS));
}

@Test
public void testCloneV3CommitNoVersionChange() throws Exception {
DirCacheVersion initial = cloneAndCheck(
EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
DirCacheVersion.DIRC_VERSION_EXTENDED));
StoredConfig cfg = db.getConfig();
cfg.setInt("index", null, "version", 4);
cfg.save();
try (Git git = new Git(db)) {
writeTrashFile("Test.txt2", "Hello again");
git.add().addFilepattern("Test.txt2").call();
git.commit().setMessage("Second commit").call();
}
assertEquals("DirCache version should be unchanged", initial,
DirCache.read(db).getVersion());
}

@Test
public void testCloneV3ResetHardVersionChange() throws Exception {
cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
DirCacheVersion.DIRC_VERSION_EXTENDED));
StoredConfig cfg = db.getConfig();
cfg.setInt("index", null, "version", 4);
cfg.save();
FileUtils.delete(new File(db.getDirectory(), "index"));
try (Git git = new Git(db)) {
git.reset().setMode(ResetType.HARD).call();
}
assertEquals("DirCache version should have changed",
DirCacheVersion.DIRC_VERSION_PATHCOMPRESS,
DirCache.read(db).getVersion());
}

@Test
public void testCloneV3ResetMixedVersionChange() throws Exception {
cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
DirCacheVersion.DIRC_VERSION_EXTENDED));
StoredConfig cfg = db.getConfig();
cfg.setInt("index", null, "version", 4);
cfg.save();
FileUtils.delete(new File(db.getDirectory(), "index"));
try (Git git = new Git(db)) {
git.reset().setMode(ResetType.MIXED).call();
}
assertEquals("DirCache version should have changed",
DirCacheVersion.DIRC_VERSION_PATHCOMPRESS,
DirCache.read(db).getVersion());
}
}

+ 31
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2010, Google Inc. and others
* Copyright (C) 2008, 2020, Google Inc. 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
@@ -28,6 +28,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
@@ -188,6 +189,28 @@ public class DirCacheCGitCompatabilityTest extends LocalDiskRepositoryTestCase {
assertArrayEquals(expectedBytes, indexBytes);
}

@Test
public void testReadWriteV4() throws Exception {
final File file = pathOf("gitgit.index.v4");
final DirCache dc = new DirCache(file, FS.DETECTED);
dc.read();
assertEquals(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS,
dc.getVersion());
assertEquals(5, dc.getEntryCount());
assertV4TreeEntry(0, "src/org/eclipse/jgit/atest/foo.txt", false, dc);
assertV4TreeEntry(1, "src/org/eclipse/jgit/atest/foobar.txt", false,
dc);
assertV4TreeEntry(2, "src/org/eclipse/jgit/other/bar.txt", true, dc);
assertV4TreeEntry(3, "test.txt", false, dc);
assertV4TreeEntry(4, "test.txt2", false, dc);

final ByteArrayOutputStream bos = new ByteArrayOutputStream();
dc.writeTo(null, bos);
final byte[] indexBytes = bos.toByteArray();
final byte[] expectedBytes = IO.readFully(file);
assertArrayEquals(expectedBytes, indexBytes);
}

private static void assertV3TreeEntry(int indexPosition, String path,
boolean skipWorkTree, boolean intentToAdd, DirCache dc) {
final DirCacheEntry entry = dc.getEntry(indexPosition);
@@ -196,6 +219,13 @@ public class DirCacheCGitCompatabilityTest extends LocalDiskRepositoryTestCase {
assertEquals(intentToAdd, entry.isIntentToAdd());
}

private static void assertV4TreeEntry(int indexPosition, String path,
boolean skipWorkTree, DirCache dc) {
final DirCacheEntry entry = dc.getEntry(indexPosition);
assertEquals(path, entry.getPathString());
assertEquals(skipWorkTree, entry.isSkipWorkTree());
}

private static File pathOf(String name) {
return JGitTestUtil.getTestResourceFile(name);
}

+ 141
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009, Google Inc. and others
* Copyright (C) 2009, 2020 Google Inc. 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
@@ -11,14 +11,25 @@
package org.eclipse.jgit.dircache;

import static java.time.Instant.EPOCH;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.time.Instant;
import java.util.concurrent.TimeUnit;

import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.util.MutableInteger;
import org.junit.Test;

public class DirCacheEntryTest {
@@ -47,6 +58,95 @@ public class DirCacheEntryTest {
}
}

private static void checkPath(DirCacheVersion indexVersion,
DirCacheEntry previous, String name) throws IOException {
DirCacheEntry dce = new DirCacheEntry(name);
long now = System.currentTimeMillis();
long anHourAgo = now - TimeUnit.HOURS.toMillis(1);
dce.setLastModified(Instant.ofEpochMilli(anHourAgo));
ByteArrayOutputStream out = new ByteArrayOutputStream();
dce.write(out, indexVersion, previous);
byte[] raw = out.toByteArray();
MessageDigest md0 = Constants.newMessageDigest();
md0.update(raw);
ByteArrayInputStream in = new ByteArrayInputStream(raw);
MutableInteger infoAt = new MutableInteger();
byte[] sharedInfo = new byte[raw.length];
MessageDigest md = Constants.newMessageDigest();
DirCacheEntry read = new DirCacheEntry(sharedInfo, infoAt, in, md,
Instant.ofEpochMilli(now), indexVersion, previous);
assertEquals("Paths of length " + name.length() + " should match", name,
read.getPathString());
assertEquals("Should have been fully read", -1, in.read());
assertArrayEquals("Digests should match", md0.digest(),
md.digest());
}

@Test
public void testLongPath() throws Exception {
StringBuilder name = new StringBuilder(4094 + 16);
for (int i = 0; i < 4094; i++) {
name.append('a');
}
for (int j = 0; j < 16; j++) {
checkPath(DirCacheVersion.DIRC_VERSION_EXTENDED, null,
name.toString());
name.append('b');
}
}

@Test
public void testLongPathV4() throws Exception {
StringBuilder name = new StringBuilder(4094 + 16);
for (int i = 0; i < 4094; i++) {
name.append('a');
}
DirCacheEntry previous = new DirCacheEntry(name.toString());
for (int j = 0; j < 16; j++) {
checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
name.toString());
name.append('b');
}
}

@Test
public void testShortPath() throws Exception {
StringBuilder name = new StringBuilder(1 + 16);
name.append('a');
for (int j = 0; j < 16; j++) {
checkPath(DirCacheVersion.DIRC_VERSION_EXTENDED, null,
name.toString());
name.append('b');
}
}

@Test
public void testShortPathV4() throws Exception {
StringBuilder name = new StringBuilder(1 + 16);
name.append('a');
DirCacheEntry previous = new DirCacheEntry(name.toString());
for (int j = 0; j < 16; j++) {
checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
name.toString());
name.append('b');
}
}

@Test
public void testPathV4() throws Exception {
StringBuilder name = new StringBuilder();
for (int i = 0; i < 20; i++) {
name.append('a');
}
DirCacheEntry previous = new DirCacheEntry(name.toString());
for (int j = 0; j < 20; j++) {
name.setLength(name.length() - 1);
String newName = name.toString() + "bbb";
checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
newName);
}
}

@SuppressWarnings("unused")
@Test
public void testCreate_ByStringPath() {
@@ -141,6 +241,46 @@ public class DirCacheEntryTest {
}
}

@Test
public void testSetStage() {
DirCacheEntry e = new DirCacheEntry("some/path", DirCacheEntry.STAGE_1);
e.setAssumeValid(true);
e.setCreationTime(2L);
e.setFileMode(FileMode.EXECUTABLE_FILE);
e.setLastModified(EPOCH.plusMillis(3L));
e.setLength(100L);
e.setObjectId(ObjectId
.fromString("0123456789012345678901234567890123456789"));
e.setUpdateNeeded(true);
e.setStage(DirCacheEntry.STAGE_2);

assertTrue(e.isAssumeValid());
assertEquals(2L, e.getCreationTime());
assertEquals(
ObjectId.fromString("0123456789012345678901234567890123456789"),
e.getObjectId());
assertEquals(FileMode.EXECUTABLE_FILE, e.getFileMode());
assertEquals(EPOCH.plusMillis(3L), e.getLastModifiedInstant());
assertEquals(100L, e.getLength());
assertEquals(DirCacheEntry.STAGE_2, e.getStage());
assertTrue(e.isUpdateNeeded());
assertEquals("some/path", e.getPathString());

e.setStage(DirCacheEntry.STAGE_0);

assertTrue(e.isAssumeValid());
assertEquals(2L, e.getCreationTime());
assertEquals(
ObjectId.fromString("0123456789012345678901234567890123456789"),
e.getObjectId());
assertEquals(FileMode.EXECUTABLE_FILE, e.getFileMode());
assertEquals(EPOCH.plusMillis(3L), e.getLastModifiedInstant());
assertEquals(100L, e.getLength());
assertEquals(DirCacheEntry.STAGE_0, e.getStage());
assertTrue(e.isUpdateNeeded());
assertEquals("some/path", e.getPathString());
}

@Test
public void testCopyMetaDataWithStage() {
copyMetaDataHelper(false);

+ 27
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011, Robin Rosenberg and others
* Copyright (C) 2011, 2020 Robin Rosenberg 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
@@ -123,6 +123,32 @@ public class DirCachePathEditTest {
assertEquals(DirCacheEntry.STAGE_3, entries.get(2).getStage());
}

@Test
public void testPathEditWithStagesAndReset() throws Exception {
DirCache dc = DirCache.newInCore();
DirCacheBuilder builder = new DirCacheBuilder(dc, 3);
builder.add(createEntry("a", DirCacheEntry.STAGE_1));
builder.add(createEntry("a", DirCacheEntry.STAGE_2));
builder.add(createEntry("a", DirCacheEntry.STAGE_3));
builder.finish();

DirCacheEditor editor = dc.editor();
PathEdit edit = new PathEdit("a") {

@Override
public void apply(DirCacheEntry ent) {
ent.setStage(DirCacheEntry.STAGE_0);
}
};
editor.add(edit);
editor.finish();

assertEquals(1, dc.getEntryCount());
DirCacheEntry entry = dc.getEntry(0);
assertEquals("a", entry.getPathString());
assertEquals(DirCacheEntry.STAGE_0, entry.getStage());
}

@Test
public void testFileReplacesTree() throws Exception {
DirCache dc = DirCache.newInCore();

+ 85
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriterTest.java View File

@@ -0,0 +1,85 @@
/*
* 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
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.storage.dfs;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;

import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.TransportBundleStream;
import org.eclipse.jgit.transport.URIish;
import org.junit.Before;
import org.junit.Test;

public class DfsBundleWriterTest {
private TestRepository<InMemoryRepository> git;

private InMemoryRepository repo;

@Before
public void setUp() throws IOException {
DfsRepositoryDescription desc = new DfsRepositoryDescription("test");
git = new TestRepository<>(new InMemoryRepository(desc));
repo = git.getRepository();
}

@Test
public void testRepo() throws Exception {
RevCommit commit0 = git.commit().message("0").create();
RevCommit commit1 = git.commit().message("1").parent(commit0).create();
git.update("master", commit1);

RevCommit commit2 = git.commit().message("0").create();

byte[] bundle = makeBundle();
try (Repository newRepo = new InMemoryRepository(
new DfsRepositoryDescription("copy"))) {
fetchFromBundle(newRepo, bundle);
Ref ref = newRepo.exactRef("refs/heads/master");
assertNotNull(ref);
assertEquals(commit1.toObjectId(), ref.getObjectId());

// Unreferenced objects are included as well.
assertTrue(newRepo.getObjectDatabase().has(commit2));
}
}

private byte[] makeBundle() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DfsBundleWriter.writeEntireRepositoryAsBundle(
NullProgressMonitor.INSTANCE, out, repo);
return out.toByteArray();
}

private static FetchResult fetchFromBundle(Repository newRepo,
byte[] bundle) throws Exception {
URIish uri = new URIish("in-memory://");
ByteArrayInputStream in = new ByteArrayInputStream(bundle);
RefSpec rs = new RefSpec("refs/heads/*:refs/heads/*");
Set<RefSpec> refs = Collections.singleton(rs);
try (TransportBundleStream transport = new TransportBundleStream(
newRepo, uri, in)) {
return transport.fetch(NullProgressMonitor.INSTANCE, refs);
}
}
}

+ 23
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcBasicPackingTest.java View File

@@ -79,6 +79,29 @@ public class GcBasicPackingTest extends GcTestCase {
assertEquals(2, stats.numberOfBitmaps);
}

@Theory
public void testPack2Commits_noPackFolder(boolean aggressive) throws Exception {
File packDir = repo.getObjectDatabase().getPackDirectory();
assertTrue(packDir.delete());

BranchBuilder bb = tr.branch("refs/heads/master");
bb.commit().add("A", "A").add("B", "B").create();
bb.commit().add("A", "A2").add("B", "B2").create();

stats = gc.getStatistics();
assertEquals(8, stats.numberOfLooseObjects);
assertEquals(0, stats.numberOfPackedObjects);
configureGc(gc, aggressive);
gc.gc();
stats = gc.getStatistics();
assertEquals(0, stats.numberOfLooseObjects);
assertEquals(8, stats.numberOfPackedObjects);
assertEquals(1, stats.numberOfPackFiles);
assertEquals(2, stats.numberOfBitmaps);

assertTrue(packDir.exists());
}

@Theory
public void testPackAllObjectsInOnePack(boolean aggressive)
throws Exception {

+ 20
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java View File

@@ -24,10 +24,14 @@ public class GcOrphanFilesTest extends GcTestCase {

private static final String BITMAP_File_1 = PACK + "-1.bitmap";

private static final String BITMAP_File_2 = PACK + "-2.bitmap";

private static final String IDX_File_2 = PACK + "-2.idx";

private static final String IDX_File_malformed = PACK + "-1234idx";

private static final String KEEP_File_2 = PACK + "-2.keep";

private static final String PACK_File_2 = PACK + "-2.pack";

private static final String PACK_File_3 = PACK + "-3.pack";
@@ -72,6 +76,22 @@ public class GcOrphanFilesTest extends GcTestCase {
assertTrue(new File(packDir, IDX_File_malformed).exists());
}

@Test
public void keepPreventsDeletionOfIndexFilesForMissingPackFile()
throws Exception {
createFileInPackFolder(BITMAP_File_1);
createFileInPackFolder(IDX_File_2);
createFileInPackFolder(BITMAP_File_2);
createFileInPackFolder(KEEP_File_2);
createFileInPackFolder(PACK_File_3);
gc.gc();
assertFalse(new File(packDir, BITMAP_File_1).exists());
assertTrue(new File(packDir, BITMAP_File_2).exists());
assertTrue(new File(packDir, IDX_File_2).exists());
assertTrue(new File(packDir, KEEP_File_2).exists());
assertTrue(new File(packDir, PACK_File_3).exists());
}

private void createFileInPackFolder(String fileName) throws IOException {
if (!packDir.exists() || !packDir.isDirectory()) {
assertTrue(packDir.mkdirs());

+ 22
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java View File

@@ -12,13 +12,17 @@ package org.eclipse.jgit.internal.storage.file;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.junit.Test;
@@ -50,6 +54,13 @@ public abstract class PackIndexTestCase extends RepositoryTestCase {
*/
public abstract File getFileForPackdf2982f28();

/**
* Return file with appropriate index version for bad fanout table test.
*
* @return file with index
*/
public abstract File getFileForBadFanoutTable();

/**
* Verify CRC32 support.
*
@@ -158,4 +169,15 @@ public abstract class PackIndexTestCase extends RepositoryTestCase {
.name());
}

@Test
public void testBadFanoutTable() {
IOException ex = assertThrows(IOException.class, () -> {
try (FileInputStream fis = new FileInputStream(
getFileForBadFanoutTable())) {
PackIndex.read(fis);
}
});
assertEquals(JGitText.get().indexFileIsTooLargeForJgit,
ex.getMessage());
}
}

+ 5
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV1Test.java View File

@@ -35,6 +35,11 @@ public class PackIndexV1Test extends PackIndexTestCase {
"pack-df2982f284bbabb6bdb59ee3fcc6eb0983e20371.idx");
}

@Override
public File getFileForBadFanoutTable() {
return JGitTestUtil.getTestResourceFile("pack-bad-fanout-table.idx");
}

/**
* Verify CRC32 - V1 should not index anything.
*

+ 5
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV2Test.java View File

@@ -35,6 +35,11 @@ public class PackIndexV2Test extends PackIndexTestCase {
"pack-df2982f284bbabb6bdb59ee3fcc6eb0983e20371.idxV2");
}

@Override
public File getFileForBadFanoutTable() {
return JGitTestUtil.getTestResourceFile("pack-bad-fanout-table.idxV2");
}

/**
* Verify CRC32 indexing.
*

+ 16
- 16
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java View File

@@ -329,21 +329,21 @@ public class MergedReftableTest {
public void overlappedUpdateIndices() throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
ReftableWriter writer = new ReftableWriter(buf)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(3)
.setMinUpdateIndex(2)
.setMaxUpdateIndex(4)
.begin();
writer.writeRef(ref("refs/heads/a", 1), 1);
writer.writeRef(ref("refs/heads/b", 2), 3);
writer.writeRef(ref("refs/heads/a", 10), 2);
writer.writeRef(ref("refs/heads/b", 20), 4);
writer.finish();
byte[] base = buf.toByteArray();

buf = new ByteArrayOutputStream();
writer = new ReftableWriter(buf)
.setMinUpdateIndex(2)
.setMaxUpdateIndex(4)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(3)
.begin();
writer.writeRef(ref("refs/heads/a", 10), 2);
writer.writeRef(ref("refs/heads/b", 20), 4);
writer.writeRef(ref("refs/heads/a", 1), 1);
writer.writeRef(ref("refs/heads/b", 2), 3);
writer.finish();
byte[] delta = buf.toByteArray();

@@ -368,21 +368,21 @@ public class MergedReftableTest {
public void enclosedUpdateIndices() throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
ReftableWriter writer = new ReftableWriter(buf)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(4)
.setMinUpdateIndex(2)
.setMaxUpdateIndex(3)
.begin();
writer.writeRef(ref("refs/heads/a", 1), 1);
writer.writeRef(ref("refs/heads/b", 20), 4);
writer.writeRef(ref("refs/heads/a", 10), 2);
writer.writeRef(ref("refs/heads/b", 2), 3);
writer.finish();
byte[] base = buf.toByteArray();

buf = new ByteArrayOutputStream();
writer = new ReftableWriter(buf)
.setMinUpdateIndex(2)
.setMaxUpdateIndex(3)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(4)
.begin();
writer.writeRef(ref("refs/heads/a", 10), 2);
writer.writeRef(ref("refs/heads/b", 2), 3);
writer.writeRef(ref("refs/heads/a", 1), 1);
writer.writeRef(ref("refs/heads/b", 20), 4);
writer.finish();
byte[] delta = buf.toByteArray();


+ 53
- 37
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitBuilderTest.java View File

@@ -13,7 +13,7 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertThrows;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -24,6 +24,32 @@ import org.junit.Test;

public class CommitBuilderTest {

// @formatter:off
private static final String SIGNATURE = "-----BEGIN PGP SIGNATURE-----\n" +
"Version: BCPG v1.60\n" +
"\n" +
"iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
"opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
"gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
"uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
"3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
"IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
"=b9OI\n" +
"-----END PGP SIGNATURE-----";

private static final String EXPECTED = "-----BEGIN PGP SIGNATURE-----\n" +
" Version: BCPG v1.60\n" +
" \n" +
" iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
" opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
" gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
" uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
" 3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
" IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
" =b9OI\n" +
" -----END PGP SIGNATURE-----";
// @formatter:on

private void assertGpgSignatureStringOutcome(String signature,
String expectedOutcome) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -33,47 +59,37 @@ public class CommitBuilderTest {
}

@Test
public void writeGpgSignatureString_1() throws Exception {
// @formatter:off
String signature = "-----BEGIN PGP SIGNATURE-----\n" +
"Version: BCPG v1.60\n" +
"\n" +
"iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
"opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
"gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
"uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
"3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
"IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
"=b9OI\n" +
"-----END PGP SIGNATURE-----";
String expectedOutcome = "-----BEGIN PGP SIGNATURE-----\n" +
" Version: BCPG v1.60\n" +
" \n" +
" iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
" opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
" gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
" uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
" 3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
" IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
" =b9OI\n" +
" -----END PGP SIGNATURE-----";
// @formatter:on
assertGpgSignatureStringOutcome(signature, expectedOutcome);
public void writeGpgSignatureString() throws Exception {
assertGpgSignatureStringOutcome(SIGNATURE, EXPECTED);
}

@Test
public void writeGpgSignatureStringTrailingLF() throws Exception {
assertGpgSignatureStringOutcome(SIGNATURE + '\n', EXPECTED);
}

@Test
public void writeGpgSignatureStringCRLF() throws Exception {
assertGpgSignatureStringOutcome(SIGNATURE.replaceAll("\n", "\r\n"),
EXPECTED);
}

@Test
public void writeGpgSignatureStringTrailingCRLF() throws Exception {
assertGpgSignatureStringOutcome(
SIGNATURE.replaceAll("\n", "\r\n") + "\r\n", EXPECTED);
}

@Test
public void writeGpgSignatureString_failsForNonAscii() throws Exception {
String signature = "Ü Ä";
try {
CommitBuilder.writeGpgSignatureString(signature,
new ByteArrayOutputStream());
fail("Exception expected");
} catch (IllegalArgumentException e) {
// good
String message = MessageFormat.format(JGitText.get().notASCIIString,
signature);
assertEquals(message, e.getMessage());
}
IllegalArgumentException e = assertThrows(
IllegalArgumentException.class,
() -> CommitBuilder.writeGpgSignatureString(signature,
new ByteArrayOutputStream()));
String message = MessageFormat.format(JGitText.get().notASCIIString,
signature);
assertEquals(message, e.getMessage());
}

@Test

+ 85
- 32
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java View File

@@ -2,41 +2,13 @@
* Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
* Copyright (C) 2008-2011, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2008-2011, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2010-2011, Christian Halstrick <christian.halstrick@sap.com>
* and other copyright owners as documented in the project's IP log.
* Copyright (C) 2010, 2020 Christian Halstrick <christian.halstrick@sap.com> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v1.0 which accompanies this
* distribution, is reproduced below, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.lib;

@@ -85,6 +57,7 @@ import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.StringUtils;
import org.junit.Assume;
import org.junit.Test;

@@ -284,6 +257,86 @@ public class DirCacheCheckoutTest extends RepositoryTestCase {
}
}

private void checkoutLineEndings(String inIndex, String expected,
String attributes) throws Exception {
try (Git git = new Git(db);
TestRepository<Repository> db_t = new TestRepository<>(db)) {
BranchBuilder master = db_t.branch("master");
master.commit().add("f", inIndex).message("m0").create();
if (!StringUtils.isEmptyOrNull(attributes)) {
master.commit().add(".gitattributes", attributes)
.message("attributes").create();
}
File f = new File(db.getWorkTree(), "f");
assertFalse(f.exists());
git.checkout().setName("master").call();
assertTrue(f.exists());
checkFile(f, expected);
}
}

@Test
public void testCheckoutWithCRLF() throws Exception {
checkoutLineEndings("first line\r\nsecond line\r\n",
"first line\r\nsecond line\r\n", null);
}

@Test
public void testCheckoutWithCRLFAuto() throws Exception {
checkoutLineEndings("first line\r\nsecond line\r\n",
"first line\r\nsecond line\r\n", "f text=auto");
}

@Test
public void testCheckoutWithCRLFAutoEolLf() throws Exception {
checkoutLineEndings("first line\r\nsecond line\r\n",
"first line\r\nsecond line\r\n", "f text=auto eol=lf");
}

@Test
public void testCheckoutWithCRLFAutoEolNative() throws Exception {
checkoutLineEndings("first line\r\nsecond line\r\n",
"first line\r\nsecond line\r\n", "f text=auto eol=native");
}

@Test
public void testCheckoutWithCRLFAutoEolCrLf() throws Exception {
checkoutLineEndings("first line\r\nsecond line\r\n",
"first line\r\nsecond line\r\n", "f text=auto eol=crlf");
}

@Test
public void testCheckoutWithLF() throws Exception {
checkoutLineEndings("first line\nsecond line\n",
"first line\nsecond line\n", null);
}

@Test
public void testCheckoutWithLFAuto() throws Exception {
checkoutLineEndings("first line\nsecond line\n",
"first line\nsecond line\n", "f text=auto");
}

@Test
public void testCheckoutWithLFAutoEolLf() throws Exception {
checkoutLineEndings("first line\nsecond line\n",
"first line\nsecond line\n", "f text=auto eol=lf");
}

@Test
public void testCheckoutWithLFAutoEolNative() throws Exception {
checkoutLineEndings(
"first line\nsecond line\n", "first line\nsecond line\n"
.replaceAll("\n", System.lineSeparator()),
"f text=auto eol=native");
}

@Test
public void testCheckoutWithLFAutoEolCrLf() throws Exception {
checkoutLineEndings("first line\nsecond line\n",
"first line\r\nsecond line\r\n", "f text=auto eol=crlf");
}

private DirCacheCheckout resetHard(RevCommit commit)
throws NoWorkTreeException,
CorruptObjectException, IOException {

+ 95
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java View File

@@ -0,0 +1,95 @@
package org.eclipse.jgit.logging;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;
import java.util.List;

/**
* Tests for performance log context utilities.
*/
public class PerformanceLogContextTest {

@Test
public void testAddEvent() {
PerformanceLogRecord record = new PerformanceLogRecord("record", 0);
PerformanceLogContext.getInstance().addEvent(record);

List<PerformanceLogRecord> eventRecords = PerformanceLogContext
.getInstance().getEventRecords();
assertTrue(eventRecords.contains(record));
assertEquals(1, eventRecords.size());
}

@Test
public void testCleanEvents() {
PerformanceLogRecord record1 = new PerformanceLogRecord("record1", 0);
PerformanceLogContext.getInstance().addEvent(record1);

PerformanceLogRecord record2 = new PerformanceLogRecord("record2", 0);
PerformanceLogContext.getInstance().addEvent(record2);

PerformanceLogContext.getInstance().cleanEvents();
List<PerformanceLogRecord> eventRecords = PerformanceLogContext
.getInstance().getEventRecords();
assertEquals(0, eventRecords.size());
}

@Test
public void testAddEventsTwoThreads() throws InterruptedException {
TestRunnable runnable1 = new TestRunnable("record1", 1);
TestRunnable runnable2 = new TestRunnable("record2", 2);

Thread thread1 = new Thread(runnable1);
Thread thread2 = new Thread(runnable2);

thread1.start();
thread2.start();

thread1.join();
thread2.join();
assertEquals(1, runnable1.getEventRecordsCount());
assertEquals(1, runnable2.getEventRecordsCount());
assertFalse(runnable1.isThrown());
assertFalse(runnable2.isThrown());
}

private static class TestRunnable implements Runnable {
private String name;

private long durationMs;

private long eventRecordsCount;

private boolean thrown = false;

public TestRunnable(String name, long durationMs) {
this.name = name;
this.durationMs = durationMs;
}

public boolean isThrown() {
return thrown;
}

public long getEventRecordsCount() {
return eventRecordsCount;
}

@Override
public void run() {
PerformanceLogRecord record = new PerformanceLogRecord(name,
durationMs);
try {
PerformanceLogContext.getInstance().addEvent(record);
eventRecordsCount = PerformanceLogContext.getInstance()
.getEventRecords().size();
PerformanceLogContext.getInstance().cleanEvents();
} catch (Exception e) {
thrown = true;
}
}
}
}

+ 368
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java View File

@@ -0,0 +1,368 @@
/*
* 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
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

package org.eclipse.jgit.merge;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.IOException;

import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.junit.Test;

public class GitlinkMergeTest extends SampleDataRepositoryTestCase {
private static final String LINK_ID1 = "DEADBEEFDEADBEEFBABEDEADBEEFDEADBEEFBABE";
private static final String LINK_ID2 = "DEADDEADDEADDEADDEADDEADDEADDEADDEADDEAD";
private static final String LINK_ID3 = "BEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEF";

private static final String SUBMODULE_PATH = "submodule.link";

@Test
public void testGitLinkMerging_AddNew() throws Exception {
assertGitLinkValue(
testGitLink(null, null, LINK_ID3, newResolveMerger(), true),
LINK_ID3);
}

@Test
public void testGitLinkMerging_Delete() throws Exception {
assertGitLinkDoesntExist(testGitLink(LINK_ID1, LINK_ID1, null,
newResolveMerger(), true));
}

@Test
public void testGitLinkMerging_UpdateDelete() throws Exception {
testGitLink(LINK_ID1, LINK_ID2, null, newResolveMerger(), false);
}

@Test
public void testGitLinkMerging_DeleteUpdate() throws Exception {
testGitLink(LINK_ID1, null, LINK_ID3, newResolveMerger(), false);
}

@Test
public void testGitLinkMerging_UpdateUpdate() throws Exception {
testGitLink(LINK_ID1, LINK_ID2, LINK_ID3, newResolveMerger(), false);
}

@Test
public void testGitLinkMerging_bothAddedSameLink() throws Exception {
assertGitLinkValue(
testGitLink(null, LINK_ID2, LINK_ID2, newResolveMerger(), true),
LINK_ID2);
}

@Test
public void testGitLinkMerging_bothAddedDifferentLink() throws Exception {
testGitLink(null, LINK_ID2, LINK_ID3, newResolveMerger(), false);
}

@Test
public void testGitLinkMerging_AddNew_ignoreConflicts() throws Exception {
assertGitLinkValue(
testGitLink(null, null, LINK_ID3, newIgnoreConflictMerger(),
true),
LINK_ID3);
}

@Test
public void testGitLinkMerging_Delete_ignoreConflicts() throws Exception {
assertGitLinkDoesntExist(testGitLink(LINK_ID1, LINK_ID1, null,
newIgnoreConflictMerger(), true));
}

@Test
public void testGitLinkMerging_UpdateDelete_ignoreConflicts()
throws Exception {
assertGitLinkValue(testGitLink(LINK_ID1, LINK_ID2, null,
newIgnoreConflictMerger(), true), LINK_ID2);
}

@Test
public void testGitLinkMerging_DeleteUpdate_ignoreConflicts()
throws Exception {
assertGitLinkDoesntExist(testGitLink(LINK_ID1, null, LINK_ID3,
newIgnoreConflictMerger(), true));
}

@Test
public void testGitLinkMerging_UpdateUpdate_ignoreConflicts()
throws Exception {
assertGitLinkValue(testGitLink(LINK_ID1, LINK_ID2, LINK_ID3,
newIgnoreConflictMerger(), true), LINK_ID2);
}

@Test
public void testGitLinkMerging_bothAddedSameLink_ignoreConflicts()
throws Exception {
assertGitLinkValue(testGitLink(null, LINK_ID2, LINK_ID2,
newIgnoreConflictMerger(), true), LINK_ID2);
}

@Test
public void testGitLinkMerging_bothAddedDifferentLink_ignoreConflicts()
throws Exception {
assertGitLinkValue(testGitLink(null, LINK_ID2, LINK_ID3,
newIgnoreConflictMerger(), true), LINK_ID2);
}

protected Merger testGitLink(@Nullable String baseLink,
@Nullable String oursLink, @Nullable String theirsLink,
Merger merger, boolean shouldMerge)
throws Exception {
DirCache treeB = db.readDirCache();
DirCache treeO = db.readDirCache();
DirCache treeT = db.readDirCache();

DirCacheBuilder bTreeBuilder = treeB.builder();
DirCacheBuilder oTreeBuilder = treeO.builder();
DirCacheBuilder tTreeBuilder = treeT.builder();

maybeAddLink(bTreeBuilder, baseLink);
maybeAddLink(oTreeBuilder, oursLink);
maybeAddLink(tTreeBuilder, theirsLink);

bTreeBuilder.finish();
oTreeBuilder.finish();
tTreeBuilder.finish();

ObjectInserter ow = db.newObjectInserter();
ObjectId b = commit(ow, treeB, new ObjectId[] {});
ObjectId o = commit(ow, treeO, new ObjectId[] { b });
ObjectId t = commit(ow, treeT, new ObjectId[] { b });

boolean merge = merger.merge(new ObjectId[] { o, t });
assertEquals(Boolean.valueOf(shouldMerge), Boolean.valueOf(merge));

return merger;
}

private Merger newResolveMerger() {
return MergeStrategy.RESOLVE.newMerger(db, true);
}

private Merger newIgnoreConflictMerger() {
return new ResolveMerger(db, true) {
@Override
protected boolean mergeImpl() throws IOException {
// emulate call with ignore conflicts.
return mergeTrees(mergeBase(), sourceTrees[0], sourceTrees[1],
true);
}
};
}

@Test
public void testGitLinkMerging_blobWithLink() throws Exception {
DirCache treeB = db.readDirCache();
DirCache treeO = db.readDirCache();
DirCache treeT = db.readDirCache();

DirCacheBuilder bTreeBuilder = treeB.builder();
DirCacheBuilder oTreeBuilder = treeO.builder();
DirCacheBuilder tTreeBuilder = treeT.builder();

bTreeBuilder.add(
createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob"));
oTreeBuilder.add(
createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 2"));

maybeAddLink(tTreeBuilder, LINK_ID3);

bTreeBuilder.finish();
oTreeBuilder.finish();
tTreeBuilder.finish();

ObjectInserter ow = db.newObjectInserter();
ObjectId b = commit(ow, treeB, new ObjectId[] {});
ObjectId o = commit(ow, treeO, new ObjectId[] { b });
ObjectId t = commit(ow, treeT, new ObjectId[] { b });

Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
assertFalse(merge);
}

@Test
public void testGitLinkMerging_linkWithBlob() throws Exception {
DirCache treeB = db.readDirCache();
DirCache treeO = db.readDirCache();
DirCache treeT = db.readDirCache();

DirCacheBuilder bTreeBuilder = treeB.builder();
DirCacheBuilder oTreeBuilder = treeO.builder();
DirCacheBuilder tTreeBuilder = treeT.builder();

maybeAddLink(bTreeBuilder, LINK_ID1);
maybeAddLink(oTreeBuilder, LINK_ID2);
tTreeBuilder.add(
createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 3"));

bTreeBuilder.finish();
oTreeBuilder.finish();
tTreeBuilder.finish();

ObjectInserter ow = db.newObjectInserter();
ObjectId b = commit(ow, treeB, new ObjectId[] {});
ObjectId o = commit(ow, treeO, new ObjectId[] { b });
ObjectId t = commit(ow, treeT, new ObjectId[] { b });

Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
assertFalse(merge);
}

@Test
public void testGitLinkMerging_linkWithLink() throws Exception {
DirCache treeB = db.readDirCache();
DirCache treeO = db.readDirCache();
DirCache treeT = db.readDirCache();

DirCacheBuilder bTreeBuilder = treeB.builder();
DirCacheBuilder oTreeBuilder = treeO.builder();
DirCacheBuilder tTreeBuilder = treeT.builder();

bTreeBuilder.add(
createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob"));
maybeAddLink(oTreeBuilder, LINK_ID2);
maybeAddLink(tTreeBuilder, LINK_ID3);

bTreeBuilder.finish();
oTreeBuilder.finish();
tTreeBuilder.finish();

ObjectInserter ow = db.newObjectInserter();
ObjectId b = commit(ow, treeB, new ObjectId[] {});
ObjectId o = commit(ow, treeO, new ObjectId[] { b });
ObjectId t = commit(ow, treeT, new ObjectId[] { b });

Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
assertFalse(merge);
}

@Test
public void testGitLinkMerging_blobWithBlobFromLink() throws Exception {
DirCache treeB = db.readDirCache();
DirCache treeO = db.readDirCache();
DirCache treeT = db.readDirCache();

DirCacheBuilder bTreeBuilder = treeB.builder();
DirCacheBuilder oTreeBuilder = treeO.builder();
DirCacheBuilder tTreeBuilder = treeT.builder();

maybeAddLink(bTreeBuilder, LINK_ID1);
oTreeBuilder.add(
createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 2"));
tTreeBuilder.add(
createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 3"));

bTreeBuilder.finish();
oTreeBuilder.finish();
tTreeBuilder.finish();

ObjectInserter ow = db.newObjectInserter();
ObjectId b = commit(ow, treeB, new ObjectId[] {});
ObjectId o = commit(ow, treeO, new ObjectId[] { b });
ObjectId t = commit(ow, treeT, new ObjectId[] { b });

Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
assertFalse(merge);
}

@Test
public void testGitLinkMerging_linkBlobDeleted() throws Exception {
// We changed a link to a blob, others has deleted this link.
DirCache treeB = db.readDirCache();
DirCache treeO = db.readDirCache();
DirCache treeT = db.readDirCache();

DirCacheBuilder bTreeBuilder = treeB.builder();
DirCacheBuilder oTreeBuilder = treeO.builder();
DirCacheBuilder tTreeBuilder = treeT.builder();

maybeAddLink(bTreeBuilder, LINK_ID1);
oTreeBuilder.add(
createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 2"));

bTreeBuilder.finish();
oTreeBuilder.finish();
tTreeBuilder.finish();

ObjectInserter ow = db.newObjectInserter();
ObjectId b = commit(ow, treeB, new ObjectId[] {});
ObjectId o = commit(ow, treeO, new ObjectId[] { b });
ObjectId t = commit(ow, treeT, new ObjectId[] { b });

Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
assertFalse(merge);
}

private void maybeAddLink(DirCacheBuilder builder,
@Nullable String linkId) {
if (linkId == null) {
return;
}
DirCacheEntry newLink = createGitLink(SUBMODULE_PATH,
ObjectId.fromString(linkId));
builder.add(newLink);
}

private void assertGitLinkValue(Merger resolveMerger, String expectedValue)
throws Exception {
try (TreeWalk tw = new TreeWalk(db)) {
tw.setRecursive(true);
tw.reset(resolveMerger.getResultTreeId());

assertTrue(tw.next());
assertEquals(SUBMODULE_PATH, tw.getPathString());
assertEquals(ObjectId.fromString(expectedValue), tw.getObjectId(0));

assertFalse(tw.next());
}
}

private void assertGitLinkDoesntExist(Merger resolveMerger)
throws Exception {
try (TreeWalk tw = new TreeWalk(db)) {
tw.setRecursive(true);
tw.reset(resolveMerger.getResultTreeId());

assertFalse(tw.next());
}
}

private static ObjectId commit(ObjectInserter odi, DirCache treeB,
ObjectId[] parentIds) throws Exception {
CommitBuilder c = new CommitBuilder();
c.setTreeId(treeB.writeTree(odi));
c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0));
c.setCommitter(c.getAuthor());
c.setParentIds(parentIds);
c.setMessage("Tree " + c.getTreeId().name());
ObjectId id = odi.insert(c);
odi.flush();
return id;
}
}

+ 43
- 1
org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012, Robin Stocker <robin@nibor.org> and others
* Copyright (C) 2012, 2020 Robin Stocker <robin@nibor.org> 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
@@ -366,6 +366,48 @@ public class MergerTest extends RepositoryTestCase {
mergeResult.getMergeStatus());
}

@Theory
public void mergeConflictWithCrLfTextAuto(MergeStrategy strategy)
throws IOException, GitAPIException {
Git git = Git.wrap(db);
writeTrashFile("crlf.txt", "a crlf file\r\n");
git.add().addFilepattern("crlf.txt").call();
git.commit().setMessage("base").call();
assertEquals("[crlf.txt, mode:100644, content:a crlf file\r\n]",
indexState(CONTENT));
writeTrashFile(".gitattributes", "crlf.txt text=auto");
git.add().addFilepattern(".gitattributes").call();
git.commit().setMessage("attributes").call();

git.branchCreate().setName("brancha").call();

writeTrashFile("crlf.txt", "a crlf file\r\na second line\r\n");
git.add().addFilepattern("crlf.txt").call();
git.commit().setMessage("on master").call();
assertEquals(
"[.gitattributes, mode:100644, content:crlf.txt text=auto]"
+ "[crlf.txt, mode:100644, content:a crlf file\r\na second line\r\n]",
indexState(CONTENT));

git.checkout().setName("brancha").call();
File testFile = writeTrashFile("crlf.txt",
"a crlf file\r\nanother line\r\n");
git.add().addFilepattern("crlf.txt").call();
git.commit().setMessage("on brancha").call();

MergeResult mergeResult = git.merge().setStrategy(strategy)
.include(db.resolve("master")).call();
assertEquals(MergeResult.MergeStatus.CONFLICTING,
mergeResult.getMergeStatus());
checkFile(testFile,
"a crlf file\r\n" //
+ "<<<<<<< HEAD\n" //
+ "another line\r\n" //
+ "=======\n" //
+ "a second line\r\n" //
+ ">>>>>>> 8e9e704742f1bc8a41eac88aac4aeefd338b7384\n");
}

@Theory
public void mergeWithCrlfAutoCrlfTrue(MergeStrategy strategy)
throws IOException, GitAPIException {

+ 1
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java View File

@@ -455,6 +455,7 @@ public class SubmoduleWalkTest extends RepositoryTestCase {
final CanonicalTreeParser p = new CanonicalTreeParser();
p.reset(testDb.getRevWalk().getObjectReader(), commit.getTree());
try (SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub")) {
assertEquals(arbitraryName, gen.getModuleName());
assertEquals(path, gen.getPath());
assertEquals(subId, gen.getObjectId());
assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());

+ 233
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BasePackConnectionTest.java View File

@@ -0,0 +1,233 @@
/*
* Copyright (C) 2020, Lee Worrall 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.transport;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.SymbolicRef;
import org.junit.Test;

public class BasePackConnectionTest {

@Test
public void testExtractSymRefsFromCapabilities() {
final Map<String, String> symRefs = BasePackConnection
.extractSymRefsFromCapabilities(
Arrays.asList("symref=HEAD:refs/heads/main",
"symref=refs/heads/sym:refs/heads/other"));

assertEquals(2, symRefs.size());
assertEquals("refs/heads/main", symRefs.get("HEAD"));
assertEquals("refs/heads/other", symRefs.get("refs/heads/sym"));
}

@Test
public void testUpdateWithSymRefsAdds() {
final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
"refs/heads/main", ObjectId.fromString(
"0000000000000000000000000000000000000001"));

final Map<String, Ref> refMap = new HashMap<>();
refMap.put(mainRef.getName(), mainRef);
refMap.put("refs/heads/other",
new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
ObjectId.fromString(
"0000000000000000000000000000000000000002")));

final Map<String, String> symRefs = new HashMap<>();
symRefs.put("HEAD", "refs/heads/main");

BasePackConnection.updateWithSymRefs(refMap, symRefs);

assertThat(refMap, hasKey("HEAD"));
final Ref headRef = refMap.get("HEAD");
assertThat(headRef, instanceOf(SymbolicRef.class));
final SymbolicRef headSymRef = (SymbolicRef) headRef;
assertEquals("HEAD", headSymRef.getName());
assertSame(mainRef, headSymRef.getTarget());
}

@Test
public void testUpdateWithSymRefsReplaces() {
final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
"refs/heads/main", ObjectId.fromString(
"0000000000000000000000000000000000000001"));

final Map<String, Ref> refMap = new HashMap<>();
refMap.put(mainRef.getName(), mainRef);
refMap.put("HEAD", new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "HEAD",
mainRef.getObjectId()));
refMap.put("refs/heads/other",
new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
ObjectId.fromString(
"0000000000000000000000000000000000000002")));

final Map<String, String> symRefs = new HashMap<>();
symRefs.put("HEAD", "refs/heads/main");

BasePackConnection.updateWithSymRefs(refMap, symRefs);

assertThat(refMap, hasKey("HEAD"));
final Ref headRef = refMap.get("HEAD");
assertThat(headRef, instanceOf(SymbolicRef.class));
final SymbolicRef headSymRef = (SymbolicRef) headRef;
assertEquals("HEAD", headSymRef.getName());
assertSame(mainRef, headSymRef.getTarget());
}

@Test
public void testUpdateWithSymRefsWithIndirectsAdds() {
final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
"refs/heads/main", ObjectId.fromString(
"0000000000000000000000000000000000000001"));

final Map<String, Ref> refMap = new HashMap<>();
refMap.put(mainRef.getName(), mainRef);
refMap.put("refs/heads/other",
new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
ObjectId.fromString(
"0000000000000000000000000000000000000002")));

final Map<String, String> symRefs = new LinkedHashMap<>(); // Ordered
symRefs.put("refs/heads/sym3", "refs/heads/sym2"); // Forward reference
symRefs.put("refs/heads/sym1", "refs/heads/main");
symRefs.put("refs/heads/sym2", "refs/heads/sym1"); // Backward reference

BasePackConnection.updateWithSymRefs(refMap, symRefs);

assertThat(refMap, hasKey("refs/heads/sym1"));
final Ref sym1Ref = refMap.get("refs/heads/sym1");
assertThat(sym1Ref, instanceOf(SymbolicRef.class));
final SymbolicRef sym1SymRef = (SymbolicRef) sym1Ref;
assertEquals("refs/heads/sym1", sym1SymRef.getName());
assertSame(mainRef, sym1SymRef.getTarget());

assertThat(refMap, hasKey("refs/heads/sym2"));
final Ref sym2Ref = refMap.get("refs/heads/sym2");
assertThat(sym2Ref, instanceOf(SymbolicRef.class));
final SymbolicRef sym2SymRef = (SymbolicRef) sym2Ref;
assertEquals("refs/heads/sym2", sym2SymRef.getName());
assertSame(sym1SymRef, sym2SymRef.getTarget());

assertThat(refMap, hasKey("refs/heads/sym3"));
final Ref sym3Ref = refMap.get("refs/heads/sym3");
assertThat(sym3Ref, instanceOf(SymbolicRef.class));
final SymbolicRef sym3SymRef = (SymbolicRef) sym3Ref;
assertEquals("refs/heads/sym3", sym3SymRef.getName());
assertSame(sym2SymRef, sym3SymRef.getTarget());
}

@Test
public void testUpdateWithSymRefsWithIndirectsReplaces() {
final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
"refs/heads/main", ObjectId.fromString(
"0000000000000000000000000000000000000001"));

final Map<String, Ref> refMap = new HashMap<>();
refMap.put(mainRef.getName(), mainRef);
refMap.put("refs/heads/sym1", new ObjectIdRef.Unpeeled(
Ref.Storage.LOOSE, "refs/heads/sym1", mainRef.getObjectId()));
refMap.put("refs/heads/sym2", new ObjectIdRef.Unpeeled(
Ref.Storage.LOOSE, "refs/heads/sym2", mainRef.getObjectId()));
refMap.put("refs/heads/sym3", new ObjectIdRef.Unpeeled(
Ref.Storage.LOOSE, "refs/heads/sym3", mainRef.getObjectId()));
refMap.put("refs/heads/other",
new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
ObjectId.fromString(
"0000000000000000000000000000000000000002")));

final Map<String, String> symRefs = new LinkedHashMap<>(); // Ordered
symRefs.put("refs/heads/sym3", "refs/heads/sym2"); // Forward reference
symRefs.put("refs/heads/sym1", "refs/heads/main");
symRefs.put("refs/heads/sym2", "refs/heads/sym1"); // Backward reference

BasePackConnection.updateWithSymRefs(refMap, symRefs);

assertThat(refMap, hasKey("refs/heads/sym1"));
final Ref sym1Ref = refMap.get("refs/heads/sym1");
assertThat(sym1Ref, instanceOf(SymbolicRef.class));
final SymbolicRef sym1SymRef = (SymbolicRef) sym1Ref;
assertEquals("refs/heads/sym1", sym1SymRef.getName());
assertSame(mainRef, sym1SymRef.getTarget());

assertThat(refMap, hasKey("refs/heads/sym2"));
final Ref sym2Ref = refMap.get("refs/heads/sym2");
assertThat(sym2Ref, instanceOf(SymbolicRef.class));
final SymbolicRef sym2SymRef = (SymbolicRef) sym2Ref;
assertEquals("refs/heads/sym2", sym2SymRef.getName());
assertSame(sym1SymRef, sym2SymRef.getTarget());

assertThat(refMap, hasKey("refs/heads/sym3"));
final Ref sym3Ref = refMap.get("refs/heads/sym3");
assertThat(sym3Ref, instanceOf(SymbolicRef.class));
final SymbolicRef sym3SymRef = (SymbolicRef) sym3Ref;
assertEquals("refs/heads/sym3", sym3SymRef.getName());
assertSame(sym2SymRef, sym3SymRef.getTarget());
}

@Test
public void testUpdateWithSymRefsIgnoresSelfReference() {
final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
"refs/heads/main", ObjectId.fromString(
"0000000000000000000000000000000000000001"));

final Map<String, Ref> refMap = new HashMap<>();
refMap.put(mainRef.getName(), mainRef);
refMap.put("refs/heads/other",
new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
ObjectId.fromString(
"0000000000000000000000000000000000000002")));

final Map<String, String> symRefs = new LinkedHashMap<>();
symRefs.put("refs/heads/sym1", "refs/heads/sym1");

BasePackConnection.updateWithSymRefs(refMap, symRefs);

assertEquals(2, refMap.size());
assertThat(refMap, not(hasKey("refs/heads/sym1")));
}

@Test
public void testUpdateWithSymRefsIgnoreCircularReference() {
final Ref mainRef = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE,
"refs/heads/main", ObjectId.fromString(
"0000000000000000000000000000000000000001"));

final Map<String, Ref> refMap = new HashMap<>();
refMap.put(mainRef.getName(), mainRef);
refMap.put("refs/heads/other",
new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/other",
ObjectId.fromString(
"0000000000000000000000000000000000000002")));

final Map<String, String> symRefs = new LinkedHashMap<>();
symRefs.put("refs/heads/sym2", "refs/heads/sym1");
symRefs.put("refs/heads/sym1", "refs/heads/sym2");

BasePackConnection.updateWithSymRefs(refMap, symRefs);

assertEquals(2, refMap.size());
assertThat(refMap, not(hasKey("refs/heads/sym1")));
assertThat(refMap, not(hasKey("refs/heads/sym2")));
}
}

+ 0
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpConfigTest.java View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save