Problem checking out HEAD after fetch [message #1822361] |
Wed, 04 March 2020 16:53  |
Eclipse User |
|
|
|
Some code of ours is used to fetch a branch from another repository and check it out locally. One particular usage is to fetch HEAD and check it out. Specifically, the fetchRefSpec is
+HEAD:HEAD
On the new local repository the code then tries to checkout HEAD.
This worked nicely with jgit-4.7.0. Currently I am trying to upgrade to jgit-5.6.1 and it stopped working.
More specifically, when I run "git show-ref --head" on the new local repo I get
ef25fcaa00fc0c3da9ee6a261bf0c24f5c82eeae HEAD
Running a checkout like this
try (Git git = new Git(repo)){
git
.checkout()
.setName("HEAD")
.call();
}
however fails with "RefNotFoundException: Ref HEAD cannot be resolved"
I tried to debug a bit, and when I run this code:
RepositoryBuilder builder = new RepositoryBuilder();
File meta = new File("/home/hb/testrepos/test/.git");
Repository repo = builder
.setGitDir(meta)
.build();
ObjectId head = repo.resolve(Constants.HEAD);
System.err.println(head);
I get "null". Actually, I see that
has the correct HEAD object id. I.e. the information is there but not used as expected.
This problem does not occur, if I run the HEAD checkout on another local repo that has been cloned from the command line and has a workspace.
Any on how can I check out "HEAD" from a "+HEAD:HEAD" fetched repo?
Would checking out FETCH_HEAD be a reliable substitute that would check out whatever a fetch for any "+REF:REF" retrieved?
Thanks,
Henning
|
|
|
|
Re: Problem checking out HEAD after fetch [message #1822441 is a reply to message #1822378] |
Fri, 06 March 2020 05:58  |
Eclipse User |
|
|
|
It is running on Ubuntu 18.04, Java 8 and Java 9.
Running "ls -l .git/HEAD; cat .git/HEAD; git config -l; git show-ref" on the target repo (see the code below):
-rw-rw-r-- 1 hb hb 23 Mär 6 11:49 .git/HEAD
ref: refs/heads/master
user.name=Henning Blohm
user.email=henning.blohm@zfabrik.de
core.autocrlf=false
filesystem.Oracle Corporation|11.0.1|/dev/sdb2.timestampresolution=5000 nanoseconds
filesystem.Oracle Corporation|11.0.1|/dev/sdb2.minracythreshold=4485 microseconds
filesystem.Oracle Corporation|1.8.0_101|/dev/sdb2.timestampresolution=1002 milliseconds
filesystem.Oracle Corporation|1.8.0_101|/dev/sdb2.minracythreshold=0 nanoseconds
core.repositoryformatversion=0
core.filemode=true
core.logallrefupdates=true
remote.origin.url=/home/hb/z2-core/workspace/zzz_git_problem/source_repo
26f130cc87357f6980f500b26523730813728d51 HEAD
50b82850eb6fcad870c40cda650e6ec97aa552f8 refs/tags/tag
I think the problem may not be easily reproducible on the command line. But I haven't tried.
Instead I created an isolated code sample that shows the problem.
Interestingly, the problem does not show without creating a tag (see below) but does happen when creating the tag.
This code was extracted from test code and is of course slightly artificial. The actual usage of JGit, i.e. using fetch/checkout rather than clone is exactly how it is done by the application.
package zzz_git_problem;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.TagOpt;
import org.eclipse.jgit.transport.URIish;
public class FetchAndCheckout {
private static File source = new File("source_repo");
private static File target = new File("target_repo");
public static void main(String[] args) throws Exception {
initialize(source);
initialize(target);
// set up source repo with some commits and branches
Git.init().setDirectory(source).call();
try (Git git = new Git(repo(source))) {
// add a file
writeAndCommit(source, "first");
git.branchCreate().setName("branch").call();
checkout(source, "branch");
writeAndCommit(source, "second");
checkout(source, "master");
// THIS BREAKS it
// git.tag().setName("tag").call();
}
// set up target repo with remote to source
try (Git git = Git.init().
setBare(false).
setDirectory(target).
call()) {
Repository repo = git.getRepository();
// add origin - clone all branches
StoredConfig config = repo.getConfig();
RemoteConfig remoteCfg = null;
try {
remoteCfg = new RemoteConfig(config, "origin");
} catch (URISyntaxException e) {
throw new IOException("Failed to configure origin repository", e);
}
remoteCfg.addURI(new URIish(source.getAbsolutePath()));
remoteCfg.update(config);
config.save();
}
// fetch HEAD
try (Git git = new Git(repo(target))) {
git.
fetch().
setRemote("origin").
setRefSpecs("+HEAD:HEAD").
setTagOpt(TagOpt.FETCH_TAGS).
call();
}
// checkout
try (Git git = new Git(repo(target))) {
git
.checkout()
.setName("HEAD")
.call();
}
}
private static void initialize(File folder) throws Exception {
Files.walk(folder.toPath())
.map(Path::toFile)
.sorted(Comparator.reverseOrder())
.forEach(File::delete);
folder.mkdirs();
}
private static void writeAndCommit(File root, String content) throws Exception {
File file = new File(root,"test.txt");
try (FileOutputStream fout = new FileOutputStream(file)) { fout.write(content.getBytes()); }
try (Git git = new Git(repo(root))) {
git.add().addFilepattern(file.getName()).call();
git.commit().setMessage(content).call();
}
}
private static void checkout(File root, String ref) throws Exception {
try (Git git = new Git(repo(root))) {
git.checkout().setName(ref).call();
}
}
private static Repository repo(File root) throws Exception {
return new RepositoryBuilder().setGitDir(new File(root,".git")).build();
}
}
|
|
|
Powered by
FUDForum. Page generated in 0.03726 seconds