Bug 553083 - Git fetch implementation for git protocol v2
Summary: Git fetch implementation for git protocol v2
Status: RESOLVED FIXED
Alias: None
Product: JGit
Classification: Technology
Component: JGit (show other bugs)
Version: unspecified   Edit
Hardware: PC All
: P3 enhancement (vote)
Target Milestone: 5.11   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 563145
  Show dependency tree
 
Reported: 2019-11-14 18:43 EST by David Ostrovsky CLA
Modified: 2021-01-14 07:00 EST (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Ostrovsky CLA 2019-11-14 18:43:09 EST
Some products are using JGit as a client, e.g. Jenkins or Gerrit Code Review
for testing framework, and could benefit from git client protocol v2 implementation.
Comment 1 Thomas Wolf CLA 2019-11-15 08:48:55 EST
(In reply to David Ostrovsky from comment #0)
> Some products are using JGit as a client

Indeed. Even at least one Eclipse "product" called EGit. :-)

Fetch and LsRemote.
Comment 2 Eclipse Genie CLA 2020-08-03 14:51:22 EDT
New Gerrit change created: https://git.eclipse.org/r/c/jgit/jgit/+/167204
Comment 4 Andrey Loskutov CLA 2020-11-03 04:49:50 EST
(In reply to Eclipse Genie from comment #3)
> Gerrit change https://git.eclipse.org/r/c/jgit/jgit/+/167204 was merged to
> [master].
> Commit:
> http://git.eclipse.org/c/jgit/jgit.git/commit/
> ?id=f802f06e7fd5a98f256b7b7727598491f563bf2f

I see errors on random eclipse.org repositories since this change with egit.

Doing git pull with native git the pull works and *after that* pull in egit works too.


I saw this now with those repos:
https://git.eclipse.org/r/platform/eclipse.platform.releng.aggregator
https://git.eclipse.org/r/platform/eclipse.platform.ua

But I guess this is due some specific change(s) offered by remote. I typically update every day, so I guess delta was not so big.

Errors I get in egit are all exact same:

org.eclipse.jgit.api.errors.TransportException: Expected ACK/NAK, got: acknowledgments
	at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:222)
	at org.eclipse.jgit.api.PullCommand.call(PullCommand.java:263)
	at org.eclipse.egit.core.op.PullOperation$PullJob.run(PullOperation.java:256)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.eclipse.jgit.errors.TransportException: Expected ACK/NAK, got: acknowledgments
	at org.eclipse.jgit.transport.BasePackFetchConnection.doFetch(BasePackFetchConnection.java:418)
	at org.eclipse.jgit.transport.TransportHttp$SmartHttpFetchConnection.doFetch(TransportHttp.java:1403)
	at org.eclipse.jgit.transport.BasePackFetchConnection.fetch(BasePackFetchConnection.java:300)
	at org.eclipse.jgit.transport.BasePackFetchConnection.fetch(BasePackFetchConnection.java:291)
	at org.eclipse.jgit.transport.FetchProcess.fetchObjects(FetchProcess.java:246)
	at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:143)
	at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:91)
	at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1266)
	at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:211)
	... 3 more
Caused by: org.eclipse.jgit.errors.PackProtocolException: Expected ACK/NAK, got: acknowledgments
	at org.eclipse.jgit.transport.PacketLineIn.readACKorEOF(PacketLineIn.java:147)
	at org.eclipse.jgit.transport.BasePackFetchConnection.negotiate(BasePackFetchConnection.java:689)
	at org.eclipse.jgit.transport.BasePackFetchConnection.doFetch(BasePackFetchConnection.java:385)
	... 11 more
Comment 5 Matthias Sohn CLA 2020-11-03 05:01:44 EST
Did you enable protocol version 2 on the client side ?
Comment 6 Thomas Wolf CLA 2020-11-03 05:11:55 EST
(In reply to Matthias Sohn from comment #5)
> Did you enable protocol version 2 on the client side ?

It's the default, as mentioned in the commit message.

Thanks for testing, Andrew. I'm also using it and so far I'm not seeing this. But I'll try the projects you mentioned, and will track it down.

As a temporary work-around add protocol.version=0 in your git config. That should force EGit to not request protocol V2.
Comment 7 Thomas Wolf CLA 2020-11-03 05:13:07 EST
(In reply to Thomas Wolf from comment #6)
> Thanks for testing, Andrew.

s/Andrew/Andrey/ . Sorry about that.
Comment 8 Andrey Loskutov CLA 2020-11-03 05:36:08 EST
(In reply to Thomas Wolf from comment #6)
> (In reply to Matthias Sohn from comment #5)
> > Did you enable protocol version 2 on the client side ?
> 
> It's the default, as mentioned in the commit message.
> 
> Thanks for testing, Andrew. I'm also using it and so far I'm not seeing
> this. 

I typically download SDK nightly every day and install egit into it, so I always see latest greatest changes & bugs :-)

> But I'll try the projects you mentioned, and will track it down.

I guess if you can clone and hard reset all branches to a week before, you may see something. Here is what native git pulled after egit failed to pull:

socbm599:/data/4x_platform_workspace/eclipse.platform.ua$ git pull
remote: Counting objects: 6565, done
remote: Finding sources: 100% (16/16)
remote: Total 16 (delta 0), reused 8 (delta 0)
Unpacking objects: 100% (16/16), done.
From https://git.eclipse.org/r/platform/eclipse.platform.ua
   eb7afe092..88656b142  R4_11_maintenance -> origin/R4_11_maintenance
   b462d3482..7a0cd2644  R4_15_maintenance -> origin/R4_15_maintenance
   5b815ebf4..1fdd17921  refs/notes/review -> refs/notes/review
 * [new tag]             I20201102-1910    -> I20201102-1910
 * [new tag]             I20201103-0030    -> I20201103-0030
 * [new tag]             Y20201102-1200    -> Y20201102-1200
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Already up to date.

socbm599:/data/4x_platform_workspace/eclipse.platform.releng.aggregator$ git pull
remote: Counting objects: 6587, done
remote: Finding sources: 100% (35/35)
remote: Total 35 (delta 3), reused 23 (delta 3)
Unpacking objects: 100% (35/35), done.
From https://git.eclipse.org/r/platform/eclipse.platform.releng.aggregator
   cec1f439..5b613b10  master            -> origin/master
   078f8138..2ea9e30e  R4_11_maintenance -> origin/R4_11_maintenance
   a74a6698..d6e0fd72  R4_15_maintenance -> origin/R4_15_maintenance
   136dd941..d7a64060  refs/notes/review -> refs/notes/review
 * [new tag]           I20201102-1910    -> I20201102-1910
 * [new tag]           I20201103-0030    -> I20201103-0030
 * [new tag]           Y20201102-1200    -> Y20201102-1200
Updating cec1f439..5b613b10
Fast-forward
 cje-production/mbscripts/mb500_createRepoReports.sh | 4 ++--
 eclipse-platform-parent/pom.xml                     | 2 +-
 eclipse.jdt.core                                    | 2 +-
 eclipse.jdt.ui                                      | 2 +-
 eclipse.platform.swt                                | 2 +-
 eclipse.platform.swt.binaries                       | 2 +-
 eclipse.platform.ui                                 | 2 +-
 rt.equinox.bundles                                  | 2 +-
 8 files changed, 9 insertions(+), 9 deletions(-)


> As a temporary work-around add protocol.version=0 in your git config. That
> should force EGit to not request protocol V2.

Easier for me is to use native git, I will also see if anything else will be broken in egit :-)
Comment 9 Thomas Wolf CLA 2020-11-03 07:44:39 EST
Looks like I have misunderstood how negotiation in that protocol V2 works.

If there are multiple rounds, C git sends

fetch> command=fetch
fetch> 0001
fetch> thin-pack
fetch> include-tag
fetch> ofs-delta
wants & haves

Server relies with some ACKs, followed by END (0000).

For the next round, client sends again

fetch> command=fetch
fetch> 0001
fetch> thin-pack
fetch> include-tag
fetch> ofs-delta
wants & haves

Server replies with some ACKs. If followed by END, another round starts, if followed by "ready", we're good to go and can expect a packfile.

The current implementation is not like that; it sends the command=fetch only the first time. Might take a moment to come up with a fix. Might also need quite some time to set up a unit test for that. Would need an upstream that's quite a bit ahead of the local clone, possibly with many tags. And the test should use HTTP; that stateless RPC is more difficult than SSH.

As a temporary measure, it's probably best to set the default for protocol.version to 0 instead of 2 all the same.
Comment 10 Eclipse Genie CLA 2020-11-03 17:45:30 EST
New Gerrit change created: https://git.eclipse.org/r/c/jgit/jgit/+/171724
Comment 12 Thomas Wolf CLA 2020-11-04 03:34:54 EST
(In reply to Eclipse Genie from comment #11)
> Gerrit change https://git.eclipse.org/r/c/jgit/jgit/+/171724 was merged to
> [master].
> Commit:
> http://git.eclipse.org/c/jgit/jgit.git/commit/
> ?id=d69fb4d4ac7bcf7d0d84109bba56cf944646fb24

I've reverted the feature. BasePackFetchConnection needs a substantial rewrite, and an HTTP test where fetching requires several (two or ideally even more) negotiation rounds is required.

I don't have the time to do this now or in the near future. If nobody gets to it before I do I'll revisit this as soon as I have the time, but it probably will not be in the 5.10 time frame.

The commit message of the revert gives some hints. The basic mistake I made was not to have looked at the C git implementation (in fetch-pack.c). :-( I should have done so.

My attempt implemented the fetch as a single command, followed by a slightly modified V0 negotiation, followed by getting the pack. Correct is negotiation setup, followed by a round of complete fetch commands (each sending the full wants & haves again), until one gets a "ready" (or determines the client is up to date, or the client sends a "done"), and then possibly getting the pack.
Comment 13 Eclipse Genie CLA 2020-11-20 15:21:25 EST
New Gerrit change created: https://git.eclipse.org/r/c/jgit/jgit/+/172595
Comment 16 Thomas Wolf CLA 2021-01-14 07:00:56 EST
Closing this a fixed. The implementation is rolled out in EGit nightly and is being used. So far not a single problem surfaced.

If there are any issues, report them as new bugs.