Here is the proof. The following script [1] sets up a server and tries to fetch from it. When uploadpack.allowreachablesha1inwant is not set on server side the
the fetch of a sha1 fails. If it is set on server-side the the fetch with native git succeeds but the fetch with JGit still fails. And setting it on client side doesn’t help JGit. It’s all about the FetchProcess.expandSingle() method where client side JGit
doesn’t like to fetch something from the server what the server has not advertised.
+ rm -fr 'writingClient*/' 'readingClient*/' server/
+ mkdir server
+ git init --bare server/repo.git
Initialized empty Git repository in /private/tmp/x2/server/repo.git/
+ git clone git://127.0.0.1/repo.git writingClient
+ git daemon --base-path=server --export-all --enable=receive-pack
Cloning into 'writingClient'...
warning: You appear to have cloned an empty repository.
+ cd writingClient
+ touch a
+ git add a
+ git commit -m add_a
[master (root-commit) 0014c4f] add_a
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
+ git push origin HEAD:master
Counting objects: 3, done.
Writing objects: 100% (3/3), 206 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git://127.0.0.1/repo.git
* [new branch] HEAD -> master
+ cd ..
+ git clone git://127.0.0.1/repo.git readingClientNative
Cloning into 'readingClientNative'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
+ git clone git://127.0.0.1/repo.git readingClientJGit
Cloning into 'readingClientJGit'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
+ cd writingClient
+ touch b
+ git add b
+ git commit -m add_b
[master e82c7a8] add_b
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 b
++ git rev-parse HEAD
+ COMMITID=e82c7a814fb7e1254ea82b701c2471b8d3bff7d9
+ echo 2
+ git commit -a -m mod_b
[master e528936] mod_b
1 file changed, 1 insertion(+)
+ git push origin HEAD:master
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 465 bytes | 0 bytes/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To git://127.0.0.1/repo.git
0014c4f..e528936 HEAD -> master
+ cd ../readingClientNative
+ git fetch origin e82c7a814fb7e1254ea82b701c2471b8d3bff7d9:new
+ git -C ../server/repo.git config uploadpack.allowreachablesha1inwant true
+ git fetch origin e82c7a814fb7e1254ea82b701c2471b8d3bff7d9:new
remote: Counting objects: 2, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
From git://127.0.0.1/repo
* [new ref] e82c7a814fb7e1254ea82b701c2471b8d3bff7d9 -> new
+ cd ../readingClientJGit
+ jgit fetch origin e82c7a814fb7e1254ea82b701c2471b8d3bff7d9:new
org.eclipse.jgit.api.errors.TransportException: Remote does not have e82c7a814fb7e1254ea82b701c2471b8d3bff7d9 available for fetch.
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:135)
at org.eclipse.jgit.pgm.Fetch.run(Fetch.java:128)
at org.eclipse.jgit.pgm.TextBuiltin.execute(TextBuiltin.java:199)
at org.eclipse.jgit.pgm.Main.execute(Main.java:250)
at org.eclipse.jgit.pgm.Main.run(Main.java:142)
at org.eclipse.jgit.pgm.Main.main(Main.java:114)
Caused by: org.eclipse.jgit.errors.TransportException: Remote does not have e82c7a814fb7e1254ea82b701c2471b8d3bff7d9 available for fetch.
at org.eclipse.jgit.transport.FetchProcess.expandSingle(FetchProcess.java:365)
at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:149)
at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:122)
at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1201)
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:128)
... 5 more
+ git config uploadpack.allowreachablesha1inwant true
+ jgit fetch origin e82c7a814fb7e1254ea82b701c2471b8d3bff7d9:new
org.eclipse.jgit.api.errors.TransportException: Remote does not have e82c7a814fb7e1254ea82b701c2471b8d3bff7d9 available for fetch.
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:135)
at org.eclipse.jgit.pgm.Fetch.run(Fetch.java:128)
at org.eclipse.jgit.pgm.TextBuiltin.execute(TextBuiltin.java:199)
at org.eclipse.jgit.pgm.Main.execute(Main.java:250)
at org.eclipse.jgit.pgm.Main.run(Main.java:142)
at org.eclipse.jgit.pgm.Main.main(Main.java:114)
Caused by: org.eclipse.jgit.errors.TransportException: Remote does not have e82c7a814fb7e1254ea82b701c2471b8d3bff7d9 available for fetch.
at org.eclipse.jgit.transport.FetchProcess.expandSingle(FetchProcess.java:365)
at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:149)
at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:122)
at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1201)
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:128)
... 5 more
+ cd ..
+ kill %1
[1] https://gist.github.com/chalstrick/942a1ebc0be01d4e350cdc9c1ba9e45c
From:
"Halstrick, Christian" <christian.halstrick@xxxxxxx>
Date: Monday, 13 February 2017 at 17:41
To: Alaa Nassef <alan.125@xxxxxxxxx>, "matthias.sohn@xxxxxxxxx" <matthias.sohn@xxxxxxxxx>
Cc: "jgit-dev@xxxxxxxxxxx" <jgit-dev@xxxxxxxxxxx>
Subject: Re: [jgit-dev] How to fetch a specific commit with JGit
I think that “allowreachablesha1inwant” is a server side configuration parameter. And I think Alaa has only control over the client side, right? The parameter
configures a JGit based server to answer correctly when a git client triggers a “git fetch origin <sha1>:…” command. This parameter doesn’t help on the client side.
We have to teach JGit client side to be not so strict when matching what the client wants to what the server advertises. During a fetch the Git server will send
back it’s advertised refs (tags and branches) and JGits client side FetchProcess explicitly checks that the objects the clients wants are among the objects pointed to by the servers advertised refs.
From:
Alaa Nassef <alan.125@xxxxxxxxx>
Date: Monday, 13 February 2017 at 17:14
To: "matthias.sohn@xxxxxxxxx" <matthias.sohn@xxxxxxxxx>
Cc: "Halstrick, Christian" <christian.halstrick@xxxxxxx>, "jgit-dev@xxxxxxxxxxx" <jgit-dev@xxxxxxxxxxx>
Subject: Re: [jgit-dev] How to fetch a specific commit with JGit
Unfortunately, that didn't work. Tried to set config as both boolean and String, and tried
allowreachablesha1inwant as well as allowReachableSHA1InWant but got no difference. Thanks a lot
for your time anyway
On Mon, Feb 13, 2017 at 5:44 PM, Matthias Sohn <matthias.sohn@xxxxxxxxx> wrote:
let me know if this works for you
On Mon, Feb 13, 2017 at 4:39 PM, Alaa Nassef <alan.125@xxxxxxxxx> wrote:
On Mon, Feb 13, 2017 at 4:52 PM, Matthias Sohn <matthias.sohn@xxxxxxxxx> wrote:
Hello Matthias,
Can you please tell me how can I make use of that, since it's not supported in porcelain
FetchCommand. I'm using latest JGit 4.6. Thanks in advance
try to set the config parameter uploadpack.allowreachablesha1inwant:
StoredConfig config = repository.getConfig();
config.setString("uploadpack", null, "allowreachablesha1inwant", true);
config.save();
and then run FetchCommand.
As Chris already explained the server also needs to allow this. If the server is based on JGit set the same config option on the server.
On Mon, Feb 13, 2017 at 3:46 PM, Matthias Sohn <matthias.sohn@xxxxxxxxx> wrote:
On Mon, Feb 13, 2017 at 10:29 AM, Halstrick, Christian <christian.halstrick@xxxxxxx> wrote:
Server side: I once asked the question whether it is allowed to fetch SHA1’s here:
http://git.661346.n2.nabble.com/Can-I-fetch-an-arbitrary-commit-by-sha1-td7619396.html . The answer was at that time that the server side decides whether this is allowed or not. I think native git server side has learned more options regarding this. See
https://git-scm.com/docs/git-config#git-config-uploadpackallowReachableSHA1InWant .
When I work e.g. with github I still see that I am not allowed to fetch any SHA1 which is known to the service side repo. See
the log from my native git command line experiment and see how native git refuses the fetch
Client side: But since there are servers which do allow a fetch of SHA1 we should allow to talk to this servers from jgit. In
the example you see below native git allows a “git fetch origin a29d652966d835393dfc98e7d266d1e4c8d184f7:newBranch” if the commit is already present in the local repo. It will create newBranch and let it point to that commit. But JGit behaves differently and
disallows the fetch. We should fix JGit to behave like native git.
JGit supports uploadpack.allowreachablesha1inwant since 4.1, see
======================================================
> git --version
git version 2.10.2
> git clone
https://github.com/chalstrick/dondalfi.git
Cloning into 'dondalfi'...
...
> git clone
https://github.com/chalstrick/dondalfi.git dondalfi2
Cloning into 'dondalfi2'...
...
> cd dondalfi
> touch b
> git add b
> git commit -m add_b
[master a29d652] add_b
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 b
> echo 2 >b
> git commit –a -m mod_b
[master 17b07fd] mod_b
1 file changed, 1 insertion(+)
> git log -2
commit 17b07fdb4c177d40a9b09b9cf012581b07d3f53d
Author: Christian Halstrick <christian.halstrick@xxxxxxx>
Date: Mon Feb 13 10:08:41 2017 +0100
mod_b
commit a29d652966d835393dfc98e7d266d1e4c8d184f7
Author: Christian Halstrick <christian.halstrick@xxxxxxx>
Date: Mon Feb 13 10:08:13 2017 +0100
add_b
> git push origin HEAD:testFetch
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 504 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 2 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local objects.
To
https://github.com/chalstrick/dondalfi.git
* [new branch] HEAD -> testFetch
> cd ../dondalfi2/
> git fetch origin a29d652966d835393dfc98e7d266d1e4c8d184f7:newBranch
error: no such remote ref a29d652966d835393dfc98e7d266d1e4c8d184f7
> git fetch origin
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), done.
From
https://github.com/chalstrick/dondalfi
* [new branch] testFetch -> origin/testFetch
> git fetch origin a29d652966d835393dfc98e7d266d1e4c8d184f7:newBranch
From
https://github.com/chalstrick/dondalfi
* [new ref] a29d652966d835393dfc98e7d266d1e4c8d184f7 -> newBranch
I already asked this question on
StackOverflow, but I need to confirm if there's a way to do that. In Git, it's possible to fetch specific commit (along with its ancestors of course) using the commit's SHA, so calling git
fetch origin 57eab609d9efda3b8ee370582c3762c0e721033d:HEAD is perfectly normal. However, trying to do so with JGit fails, since FetchProcess tries to match
the source of the passed RefSpec with the advertisedRefs, which
are only the branches and tags.
Is there any way I can fetch a specific commit from a remote repository?
_______________________________________________
jgit-dev mailing list
jgit-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jgit-dev