Commit Graph

933 Commits

Author SHA1 Message Date
Luca Milanesio f5f4bf0ad9 Do not exclude objects in locked packs from bitmap processing
Packfiles having an equivalent .keep file are associated with in-flight
pushes that haven't been completed, with potentially a set of git
objects not yet referenced by a ref.

If the Git client is not up-to-date, it may result in pushing a
packfile, generating a <packfile>.keep on the server, which
may also contain existing commits due to the lack of Git protocol
negotiation in the git-receive-pack.

The Git protocol negotiation is the phase where the client and the
server exchange the list of refs they have for trying to find a common
base and minimise the amount of objects to be transferred.

The repack phase in GC was previously skipping all objects that were
contained in all packfiles having a <packfile>.keep file associated
(aka "locked packfiles"), which did not take into consideration the
fact that excluding the existing commits would have resulted in the
generation of an invalid bitmap file.

The code for excluding the objects in the locked packfiles was written
well before the bitmap was introduced, hence could not consider a use
case that did not exist at that time.

However, when the bitmap was introduced, the exclusion of locked
packfiles was not changed, hence creating a potential problem.
The issue went unnoticed for many years because the bitmap generation
was disabled when JGit noticed any locked packfiles; however, the
bitmaps are enabled again since  Id722e68d9f , and the the issue is now
visible and is impacting the GC repack phase.

Introduce the '--pack-kept-objects' option in GC for including the
objects contained in the locked packfiles during the repack phase,
which is not an issue because of the following:

- If there are any existing commits duplicated in the packfiles
  they will be just considered once anyway because the repack doesn't
  generate duplicates in the output packfile.

- If there are any new commits that do not have any ref pointing to
  them, they will be automatically excluded from the output repacked
  packfile.

The same identical solution is adopted in the C implementation of git
in repack.c.

Because the locked packfile is not pruned, any new commits not pointed
by any refs will remain in the repository and there will not be any
accidental pruning or object loss as it is today before this change.

As a side-effect of this change, it is now potentially possible to still
have duplicate BLOBs after GC when the keep packfile contained existing
objects. However, it is way better to keep the duplication until the
next GC phase rather than omitting existing objects from repacking and,
therefore generating an invalid bitmap and incorrect packfile.

Bug: 582292
Bug: 582455
Change-Id: Ide3445e652fcf256a7912f881cb898897c99b8f8
2023-10-12 22:46:08 +02:00
Matthias Sohn dd92c1aa98 Prepare 5.13.3-SNAPSHOT builds
Change-Id: I02b9388c8bc1c266bb29b4502504d137dd42142f
2023-06-22 02:15:21 +02:00
Matthias Sohn 5aa8a7e276 JGit v5.13.2.202306221912-r
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Change-Id: Id0ee779fba85a6d5557f6319969adb2c74feebcf
2023-06-22 01:12:05 +02:00
Matthias Sohn 9424052f27 Add pack options to preserve and prune old pack files
Add the options
- pack.preserveOldPacks
- pack.prunePreserved

This allows to configure in git config if old packs should be preserved
during gc and pruned during the next gc.

The original implementation in 91132bb0 only allows to set these options
using the API.

Change-Id: I5b23ab4f317d12f5ccd234401419913e8263cc9a
2023-02-11 01:19:28 +01:00
Matthias Sohn db074a1352 Prepare 5.13.2-SNAPSHOT builds
Change-Id: I4862e5d80a7d95a1a119d06306e3f6927445d1d3
2022-06-14 00:41:18 +02:00
Matthias Sohn b34961a493 JGit v5.13.1.202206130422-r
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Change-Id: Ife74d64e8171c68dbf08271492c0ac852a6dc51c
2022-06-13 10:22:43 +02:00
Matthias Sohn 486afbc08d Use slf4j-simple instead of log4j for logging
JGit uses slf4j-api as logging API.

The libraries
- org.eclipse.jgit.http.test
- org.eclipse.jgit.pgm
- org.eclipse.jgit.ssh.apache.test
- org.eclipse.jgit.test
used the outdated log4j 1.2.15 which is EOL since years.

Since both jgit command line and also the tests don't need sophisticated
logging features replace log4j with the much simpler slf4j-simple log
implementation. The org.slf4j.binding.simple 1.7.30 archive has only
25kB instead of 429kB for log4j 1.2.15

Applications using jgit are free to choose any other log implementation
supporting slf4j API.

Change-Id: I89e85cd3c76e954c3434622510975ce65dc227d4
2021-12-31 01:09:52 +01:00
Matthias Sohn 81cd70d5d0 Prepare 5.13.1-SNAPSHOT builds
Change-Id: Ib2f689d8d13eab022da5b5e83d6d6bebc1bb81d3
2021-09-08 20:24:36 +02:00
Matthias Sohn b3d51a399e JGit v5.13.0.202109080827-r
Change-Id: If3b2d4256712cc7e577c23e75c0d4ad940870e72
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-09-08 14:27:06 +02:00
Matthias Sohn efdc03e164 Prepare 5.13.0-SNAPSHOT builds
Change-Id: I2a1d7ab24d5ca718348f4ce3cda351553e48cd1f
2021-09-01 20:00:56 +02:00
Matthias Sohn 4949a295df JGit v5.13.0.202109011149-rc1
Change-Id: Id8d0970102f18e61a2fc7cf941267c9089d71c1a
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-09-01 16:49:12 +02:00
Matthias Sohn 6817b7e3b4 Ignore IllegalStateException if JVM is already shutting down
Trying to register/unregister a shutdown hook when the JVM is already in
shutdown throws an IllegalStateException. Ignore this exception since we
can't do anything about it.

Bug: 575367
Change-Id: Ic967c16c7f566c84778795315ab369e76668b364
2021-08-29 05:02:59 -04:00
Matthias Sohn 0b9193e69f [pgm] Fix default meta variable defined in StopOptionHandler
Change-Id: I703718e2476d40d34b11083414ac0ed5e34bf90a
2021-06-28 01:10:41 +02:00
Matthias Sohn d947e84980 Fix typo in javadoc of PathTreeFilterHandler
Change-Id: Icf0dc814baf0dc44addd102d9c03b821b4022a84
2021-06-28 01:08:48 +02:00
Matthias Sohn 1cbfea9ece Prepare 5.13.0-SNAPSHOT builds
Change-Id: Ie9cfc1eeb0eda7b2bbe744a22a7e4cfe6d59bc37
2021-06-14 01:49:05 +02:00
Matthias Sohn a397727e4a Prepare 5.12.1-SNAPSHOT builds
Change-Id: Idf266c34aa9a04cf9c5e0e09bcb415c13d773d4c
2021-06-13 23:59:14 +02:00
Matthias Sohn 1f062c64be JGit v5.12.0.202106070339-r
Change-Id: I0fbfea2c83f1ce83f75130cc97591547032f1104
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-06-07 09:38:29 +02:00
Matthias Sohn 044c5f215c Prepare 5.12.0-SNAPSHOT builds
Change-Id: Ifc72d3f3ac84b9c4055b95ec0093d877ffb09ab0
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-06-03 20:04:28 +02:00
Matthias Sohn 45a4c131ae JGit v5.12.0.202106021050-rc1
Change-Id: I622ee049f14f37504ff4a062f03d6fc25465d0ec
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-06-02 16:49:17 +02:00
Matthias Sohn 1f733663bf Prepare 5.12.0-SNAPSHOT builds
Change-Id: I25e4efc9b40ae4e7168b37385445c73992c5beb0
2021-06-02 08:47:28 +02:00
Matthias Sohn 94aa245023 JGit v5.12.0.202106011439-rc1
Change-Id: Ieac1d02879defe0f4791062448d4efc328a2f652
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-06-01 20:38:31 +02:00
Matthias Sohn 677d7794cc Prepare 5.12.0-SNAPSHOT builds
Change-Id: If563be77aab768ac1f31ae2211fb0892d0205a2a
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-06-01 16:13:41 +02:00
Matthias Sohn ff4c10bf90 JGit v5.12.0.202105261145-m3
Change-Id: I3b1af2032227900e6e0c6189f47bace1df67f0ab
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-05-26 17:43:55 +02:00
kylezhao 46a702ef41 pgm: rewrite parents when --parents flag is passed
According to [1], we should rewrite parents in RevWalkTextBuiltin
when variable parents is true.
[1]
https://git-scm.com/docs/git-rev-list#Documentation/git-rev-list.txt---parents

Change-Id: If5dca3b280366969d0488fa895bc37253a797394
Signed-off-by: kylezhao <kylezhao@tencent.com>
2021-05-26 10:14:22 +02:00
Thomas Wolf 8210f29fe4 Implement ours/theirs content conflict resolution
Git has different conflict resolution strategies:

* There is a tree merge strategy "ours" which just ignores any changes
  from theirs ("-s ours"). JGit also has the mirror strategy "theirs"
  ignoring any changes from "ours". (This doesn't exist in C git.)
  Adapt StashApplyCommand and CherrypickCommand to be able to use those
  tree merge strategies.
* For the resolve/recursive tree merge strategies, there are content
  conflict resolution strategies "ours" and "theirs", which resolve
  any conflict hunks by taking the "ours" or "theirs" hunk. In C git
  those correspond to "-Xours" or -Xtheirs". Implement that in
  MergeAlgorithm, and add API to set and pass through such a strategy
  for resolving content conflicts.
* The "ours/theirs" content conflict resolution strategies also apply
  for binary files. Handle these cases in ResolveMerger.

Note that the content conflict resolution strategies ("-X ours/theirs")
do _not_ apply to modify/delete or delete/modify conflicts. Such
conflicts are always reported as conflicts by C git. They do apply,
however, if one side completely clears a file's content.

Bug: 501111
Change-Id: I2c9c170c61c440a2ab9c387991e7a0c3ab960e07
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-04-19 01:52:19 +02:00
Matthias Sohn 232876421d Prepare 5.12.0-SNAPSHOT builds
Change-Id: I736de7c3deb11da75777d459f47332df0b486443
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-03-10 16:34:28 +01:00
Matthias Sohn 1f368f8867 Prepare 5.11.1-SNAPSHOT builds
Change-Id: I94628ccbb5099a65aa4345cfd28a141ff5555b68
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-03-09 23:42:31 +01:00
Matthias Sohn 30b6887d44 JGit v5.11.0.202103091610-r
Change-Id: I8e6855eaf7228459f492036feb4e34ca085698a7
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-03-09 22:10:22 +01:00
Matthias Sohn 1172c0b283 Prepare 5.11.0-SNAPSHOT builds
Change-Id: I89ed49a6acc53dd75d16f40c99e1140e0c18f646
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-03-04 16:27:51 +01:00
Matthias Sohn d60dd72310 JGit v5.11.0.202103031150-rc1
Change-Id: I0a86fa59645888f9f36ea6938c9121e095f02fc6
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-03-03 17:48:00 +01:00
Matthias Sohn 83d4f19a30 Prepare 5.11.0-SNAPSHOT builds
Change-Id: If3dbe084ee37ae4b993d3a10ec48b14e8709ff6d
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-02-24 21:21:34 +01:00
Matthias Sohn 9eacae28df JGit v5.11.0.202102240950-m3
Change-Id: Iea6b3515fa63db497989194b6bf50fe7324086d0
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-02-24 15:50:41 +01:00
Matthias Sohn 927deed5a5 init: add config option to set default for the initial branch name
We introduced the option --initial-branch=<branch-name> to allow
initializing a new repository with a different initial branch.

To allow users to override the initial branch name more permanently
(i.e. without having to specify the name manually for each 'git init'),
introduce the 'init.defaultBranch' option.

This option was added to git in 2.28.0.

See https://git-scm.com/docs/git-config#Documentation/git-config.txt-initdefaultBranch

Bug: 564794
Change-Id: I679b14057a54cd3d19e44460c4a5bd3a368ec848
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-02-22 23:11:45 +01:00
Matthias Sohn cb8924a80d init: allow specifying the initial branch name for the new repository
Add option --initial-branch/-b to InitCommand and the CLI init command.
This is the first step to implement support for the new option
init.defaultBranch. Both were added to git in release 2.28.

See https://git-scm.com/docs/git-init#Documentation/git-init.txt--bltbranch-namegt

Bug: 564794
Change-Id: Ia383b3f90b5549db80f99b2310450a7faf6bce4c
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-02-22 23:11:45 +01:00
Matthias Sohn 64cb7148ac Fail clone if initial branch doesn't exist in remote repository
jgit clone --branch foo <url>

did not fail if the remote branch "foo" didn't exist in the remote
repository being cloned.

Bug: 546580
Change-Id: I55648ad3a39da4a5711dfa8e6d6682bb8190a6d6
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-02-22 23:11:44 +01:00
Thomas Wolf 3774fcc848 GPG signature verification via BouncyCastle
Add a GpgSignatureVerifier interface, plus a factory to create
instances thereof that is provided via the ServiceLoader mechanism.

Implement the new interface for BouncyCastle. A verifier maintains
an internal LRU cache of previously found public keys to speed up
verifying multiple objects (tag or commits). Mergetags are not handled.

Provide a new VerifySignatureCommand in org.eclipse.jgit.api together
with a factory method Git.verifySignature(). The command can verify
signatures on tags or commits, and can be limited to accept only tags
or commits. Provide a new public WrongObjectTypeException thrown when
the command is limited to either tags or commits and a name resolves
to some other object kind.

In jgit.pgm, implement "git tag -v", "git log --show-signature", and
"git show --show-signature". The output is similar to command-line
gpg invoked via git, but not identical. In particular, lines are not
prefixed by "gpg:" but by "bc:".

Trust levels for public keys are read from the keys' trust packets,
not from GPG's internal trust database. A trust packet may or may
not be set. Command-line GPG produces more warning lines depending
on the trust level, warning about keys with a trust level below
"full".

There are no unit tests because JGit still doesn't have any setup to
do signing unit tests; this would require at least a faked .gpg
directory with pre-created key rings and keys, and a way to make the
BouncyCastle classes use that directory instead of the default. See
bug 547538 and also bug 544847.

Tested manually with a small test repository containing signed and
unsigned commits and tags, with signatures made with different keys
and made by command-line git using GPG 2.2.25 and by JGit using
BouncyCastle 1.65.

Bug: 547751
Change-Id: If7e34aeed6ca6636a92bf774d893d98f6d459181
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
2021-02-16 00:37:00 +01:00
Matthias Sohn 9109cb9d2b [pgm] add option --timeout to clone command
Change-Id: I2ee74755045a8d9971ea0d9426db405829c7c679
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-01-29 16:23:29 +01:00
Jonathan Tan c29ec3447d Merge changes I36d9b63e,I8c5db581,I2c02e89c
* changes:
  Compare getting all refs except specific refs with seek and with filter
  Add getsRefsByPrefixWithSkips (excluding prefixes) to ReftableDatabase
  Add seekPastPrefix method to RefCursor
2021-01-27 13:36:43 -05:00
Gal Paikin 31e3cb4375 Compare getting all refs except specific refs with seek and with filter
There are currently two ways to get all refs except a specific ref, we
add two methods that perform both and compare the two different approaches.

This change adds two methods that compares the two different approaches
of such query:
1. Get all the refs, and then filter by refs that don't start with the
prefix (current approach).
2. Get all refs until encountering a ref that is part of the prefix we
should exclude, skip using seekPastPrefix, and continue (new approach).
This works since the refs are sorted.

Specifically in Gerrit, we often have thousands of refs that are not
refs/changes, and millions of refs/changes, hence the second approach
should be much faster. In Jgit in general it's still expected to provide
a better result even if we're skipping a smaller chunk of the refs
since the complexity here is O(logn) with a binary search, rather than
O(number of skipped refs).

We ran this benchmark on a big chunk of chromium/src's reftable. To run
it, we first create the reftable:

  git ls-remote https://chromium.googlesource.com/chromium/src > lsr

  bazel build org.eclipse.jgit.pgm:jgit && rm -rf /tmp/reftable* && \
    ./bazel-bin/org.eclipse.jgit.pgm/jgit debug-benchmark-reftable \
    --test write_stack lsr /tmp/reftable

Then, we actually test the created reftable. Note that we can't test all
of them at once since there are multiple ones, but below is a good
example.

bazel build org.eclipse.jgit.pgm:jgit  && \
./bazel-bin/org.eclipse.jgit.pgm/jgit debug-benchmark-reftable \
--test get_refs_excluding_ref --ref refs/changes \
lsr /tmp/reftable/000000000001-0000001e0371.ref

Result:
total time the action took using seek:      36925 usec
total time the action took using filter:     874382 usec
number of refs that start with prefix: 4266.
number of refs that don't start with prefix: 1962695.

Similarly for Android's biggest repository, platform/frameworks/base
(still only partial result):
total time the action took using seek:       9020 usec
total time the action took using filter:     143166 usec
number of refs that start with prefix: 296.
number of refs that don't start with prefix: 60400.

In conclusion, it's easy to see an improvement of a factor of 15-20x for
large Gerrit repositories!

Signed-off-by: Gal Paikin <paiking@google.com>
Change-Id: I36d9b63eb259804c774864429cf2c761cd099cc3
2021-01-27 02:22:51 -05:00
Matthias Sohn d4fca2e81c pgm: add missing dependency to org.apache.commons.logging
Without this dependency I get class loading exceptions when trying to
run org.eclipse.jgit.pgm.Clone in Eclipse.

Change-Id: Ia9ecb385d3baccbcd041114287af5076fefd3d71
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2021-01-17 18:04:38 -05:00
Thomas Wolf 3ef9f2c764 [pgm] Use Apache sshd by default
Change-Id: I2a00059415fc2674469bc921827362801583af83
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
2021-01-15 18:42:45 -05:00
Thomas Wolf dd3846513b Tag message must not include the signature
Signatures on tags are just tacked onto the end of the message.
Getting the message must not return the signature. Compare [1]
and [2] in C git, which both drop a signature at the end of an
object body.

[1] https://github.com/git/git/blob/21bf933/builtin/tag.c#L173
[2] https://github.com/git/git/blob/21bf933/ref-filter.c#L1276

Change-Id: Ic8a1062b8bc77f2d7c138c3fe8a7fd13b1253f38
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
2021-01-10 10:19:40 -05:00
Han-Wen Nienhuys 7386f73bb0 Remove reftree and ketch
This was experimental code and never used in production.

Change-Id: Ia3da7f2b82d9e365cec2ccf9397cbc47439cd150
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2020-12-15 02:00:35 +01:00
Matthias Sohn 8548cb4e51 LsRemote: suppress warning for non-externalized string
Change-Id: Ic1d8f2eef4a8de0a75d5b523b584b1ac275a8811
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2020-12-15 02:00:35 +01:00
Thomas Wolf 41b9159795 TagCommand: support signing annotated tags
Add the two config constants from C git that can switch on signing
of annotated tags. Add them to the GpgConfig, and implement actually
signing a tag in TagCommand.

The interactions between command line options for "git tag" and config
options is a bit murky in C git. There are two config settings for it:

* tag.gpgSign is the main option, if set to true, it kicks in if
  neither -s nor -u are given on the command line.
* tag.forceSignAnnotated signs only tags created via "git tag -m",
  but only if command-line option "-a" is not present. It applies
  even if tag.gpgSign is set explicitly to false.

Giving -s or -u on the command line also forces an annotated tag
since lightweight tags cannot be signed.

Bug: 386908
Change-Id: Ic8a1a44b5f12f47d5cdf3aae2456c1f6ca9ef057
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
2020-12-07 09:33:57 +01:00
Matthias Sohn 9034c7d423 Prepare 5.11.0-SNAPSHOT builds
Change-Id: I91e5532526775191fbd34f81e2ef777cba605e3b
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2020-12-02 15:57:16 +01:00
Lee Worrall 9ebbfe93bb Add support for reading symrefs from pack capabilities
A SymbolicRef is added to the advertised refs for any symref in
capabilities whose target is an advertised ref; this may replace an
existing entry, such as HEAD.

When cloning, if any advertised HEAD is symbolic then use the target
rather than looking for an advertised ref with a matching objectId.

Add --symref option to LsRemote command.

Bug: 514052
Change-Id: Idfb48e6f6e8dcfe57a6896883fe6d84d533aa9d0
Signed-off-by: Lee Worrall <worrall.la@gmail.com>
2020-11-26 21:14:08 +01:00
Jason Yeo 276fcb2a11 Implement git describe --all
This enables jgit to use any refs in the refs/ namespace when describing
commits.

Signed-off-by: Jason Yeo <jasonyeo88@gmail.com>
Change-Id: I1fa22d1c39c0e2f5e4c2938c9751d8556494ac26
2020-10-13 18:06:39 +08:00
Matthias Sohn 6ae1a30004 Prepare 5.10.0-SNAPSHOT builds
Change-Id: I9a2b39e9e85f27179ceb3b1709d75c466089a3bc
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2020-08-27 16:14:36 +02:00
Matthias Sohn 855842af19 Prepare 5.9.0-SNAPSHOT builds
Change-Id: Ia998e2772df1285a4c674b07201f15d53156eb78
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
2020-06-09 12:51:12 +02:00