Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EGit / JGit » Problem checking out HEAD after fetch
Problem checking out HEAD after fetch [message #1822361] Wed, 04 March 2020 21:53 Go to next message
Henning Blohm is currently offline Henning BlohmFriend
Messages: 6
Registered: July 2013
Junior Member
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

repo.getAllRefs()


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 #1822378 is a reply to message #1822361] Thu, 05 March 2020 09:43 Go to previous messageGo to next message
Christian Halstrick is currently offline Christian HalstrickFriend
Messages: 272
Registered: July 2009
Senior Member
On which platform do you run on?

On the repo where the checkout fails could you do a "ls -l .git/HEAD; cat .git/HEAD; git config -l; git show-ref". Please make sure the config output does not contain data you don't want to expose.

Additionally you could download jgit.sh from https://repo.eclipse.org/content/groups/releases//org/eclipse/jgit/org.eclipse.jgit.pgm/5.6.1.202002131546-r/org.eclipse.jgit.pgm-5.6.1.202002131546-r.sh
Then run a "jgit.sh config -l --local --global --system; jgit.sh show-ref"

Can you show with which jgit commands you do the clone?

The following does work for me
> jgit.sh clone https://chalstrick@github.com/chalstrick/jgit.git
Cloning into 'jgit'...
2020-03-05 10:40:21 WARN  NetscapeCookieFile:266 - Configured http.cookieFile '/Users/d032780/.gitcookies' is missing
remote: Enumerating objects: 74721
Receiving objects:      100% (74721/74721)
Resolving deltas:       100% (43608/43608)
Checking out files:     100% (1875/1875)

> jgit.sh show-ref  | grep HEAD
6cd6ccb65a9952e8f6c802fa8b93026645df01dd        HEAD
> jgit.sh checkout HEAD
>


Ciao
Chris
Re: Problem checking out HEAD after fetch [message #1822441 is a reply to message #1822378] Fri, 06 March 2020 10:58 Go to previous message
Henning Blohm is currently offline Henning BlohmFriend
Messages: 6
Registered: July 2013
Junior Member
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();		
	}


}
Previous Topic:Configure upstream for push and pull
Next Topic:Please explain why these settings are needed in the IDE if they are not used by plugins?
Goto Forum:
  


Current Time: Fri Jun 25 11:28:30 GMT 2021

Powered by FUDForum. Page generated in 0.01882 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top