Get Repository object for remote address - java

I try to obtain a Repository object from a URL address, with JGit using code like this:
Repository repository = Git.lsRemoteRepository()
.setHeads(true)
.setTags(true)
.setRemote(url)
.setCredentialsProvider(credentials)
.getRepository();
However, with that code, repository is null. On the other hand, using this code
Collection<Ref> refs = Git.lsRemoteRepository()
.setHeads(true)
.setTags(true)
.setRemote(urlString)
.setCredentialsProvider(credentials)
.call();
a collection of Ref objects can be obtained, and that method seems to work for a remote URL.
Can I obtain a Repository object from a Ref object? How can I find a file from starting from Ref object?

The Repository class of JGit represents a local repository, quite often a clone of a remote repository.
The LsRemoteCommand returned by Git::lsRemoteRepository operates outside the context of a local repository and hence returns null for getRepository.
A Ref in JGit does not have a reference to the repository, either, as they may originate from a repository without a local representation. Remember, for example, there is no local repository for the refs returned by LsRemoteCommand.
To do anything useful with a repository, it needs to be cloned first. For example, with:
Git git = Git.cloneRepository().setURI(url).call();
// do something with repository, access to repository through git.getRepostory()
git.close();
The code is equivalent to git clone <url>. If the url is https://host.org/repo.git, the command would create a clone in a repo subdirectory of the current working directory.
More details on cloning repositories with JGit can be found here: https://www.codeaffine.com/2015/11/30/jgit-clone-repository/

Try this:
String repoUrl = "https://github.com/GovindParashar136/SpringBootWithRestOpenIdClientAuthentication.git";
String cloneDirectoryPath = "/path/to/directory/"; // Ex.in windows c:\\gitProjects\SpringBootWithRestOpenIdClientAuthentication\
try {
System.out.println("Cloning "+repoUrl+" into "+repoUrl);
Git.cloneRepository()
.setURI(repoUrl)
.setDirectory(Paths.get(cloneDirectoryPath).toFile())
.setCredentialsProvider(new UsernamePasswordCredentialsProvider("username", "password"))
.call();
System.out.println("Completed Cloning");
} catch (GitAPIException e) {
System.out.println("Exception occurred while cloning repo");
e.printStackTrace();
}

Related

Jgit - checkout from a specific branch

I am using jgit. I want to create and checkout a new branch. I have seen the git.checkout.createnewbranch command. Is there a way to specify the base branch for the checkout, say "test" (or) we have to checkout,pull "test" first and then checkout/create the new branch from it?
Yes, it's possible:
Git git = Git.cloneRepository()
.setURI("https://github.com/eclipse/jgit.git") // just an example uri
.setDirectory("/path/to/repo")
.setCloneAllBranches(true)
.call();
git.checkout()
.setCreateBranch(true)
.setName("new-branch")
.setStartPoint("<base branch>") // if it's a remote base then use origin/ prefix
.call();
Don't forget to call git.close() or use try-with-resources once you are done with git.

JGit Commit file to remoteRepository without Clone

I'm new with JGit and I'm trying to checkout a remote branch and commit a file to it. But I stucked here and don't know what to do next:
Collection<Ref> branchs = Git.lsRemoteRepository()
.setHeads(true)
.setTags(true)
.setRemote(REMOTE_URL)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username,password))
.call();
Optional<Ref> branch = branchs.stream().filter(r -> r.getName().equals("refs/heads/"+branchName)).findFirst();
How can I turn Ref to Repository or something to use GitCommand?
Sorry for my bad English, thank you!
Your code works with a remote repository. You need to clone it if you want to perform changes.
Git myGit = Git.cloneRepository()
.setURI(REMOTE_URL)
.setDirectory(destination)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username,password))
.call();
After you have a local copy you can add files to it.
myGit.add().addFilepattern(FILE_PATTERN).call();
Changing branches can be done with:
myGit.checkout().setName(branch).call()'
Do not forget to commit the changes and push to the remote.

JGit: Can I find out whether or not a particular tag exists in a Git repository without checking it out?

I need to write a piece of code in Java which tests whether or not a particular tag exists in a Git repository.
Most obvious way to do it it this:
git = Git.cloneRepository()
.setURI(gitUri)
.setDirectory(dir)
.call();
git.checkout().setName(String.format("refs/tags/%s", version)).call();
If tag version does not exist, an exception will be thrown.
But this way requires me to have a directory (dir) into which the repository will be checked out.
Is it possible to find out whether or not a tag exists in a remote repository without checking it out on disk? If yes, how can I do it?
The LsRemoteCommand is able to list the refs that a remote repository has.
The command can be configured to include tags like this:
LsRemoteCommand ls = Git.lsRemoteRepository();
Collection<Ref> remoteRefs = ls
.setRemote("url-to-remote-repo")
.setHeads(true) // true by default, set to false if not interested in refs/heads/*
.setTags(true) // include tags in result
.call();
If you prefer to get a map of ref-names to Ref objects, you can execute the command with callAsMap().

How To Use JGit To Do Equivalent Of "git push --mirror ..."?

I'm trying to create a simple application that executes a "git push --mirror" operation from the Java domain.
The JGit library, specifically the PushCommand class, doesn't seem to support the "--mirror" option even though it supports "--all" and "--tags".
Am I missing something? How do we use JGit to do "git push --mirror ..."?
Try it manually by using the following ref spec:
git.push().setRefSpecs(new RefSpec("+refs/*:refs/*")).call();
There is no exact equivalent to --mirror in JGit yet, but you should be able to emulate this behaviour. To force-push all local refs you can configure the PushCommand with
PushCommand pushCommand = git.push();
pushCommand.setForce(true);
pushCommand.add("refs/*:refs/*");
That would leave the refs that have been deleted locally. Therefore you can obtain a list of remote-refs to determine what has been deleted locally and publish those deletions to the remote:
Collection<Ref> remoteRefs = git.lsRemote().setRemote("origin").setHeads(true).setTags(true).call();
Collection<String> deletedRefs = new ArrayList<String>();
for (Ref remoteRef : remoteRefs) {
if (git.getRepository().getRef(remoteRef.getName()) == null) {
deletedRefs.add(remoteRef.getName());
}
}
for (String deletedRef : deletedRefs) {
pushCommand.add(":" + deletedRef);
}
The git variable references the repository that you want to push from, i.e. the one from the first block. The LsRemoteCommand returns all heads and tags from the remote repository that is configured as origin in the local repository's configuration. In the usual case, the one you cloned from.
Please note that there is a small gap to the approach how deleted local refs are propagated. The LsRemoteCommand only returns refs under heads and tags (e.g. no custom refs like pulls), hence you would not detect a local deletion of e.g. refs/foo/bar.
Does that work for you?

JGit branch checkout Issue

I am checking out a repository from github using the following code .
private String url = "https://github.com/organization/project.git";
Git repo = Git.cloneRepository().setURI(url).setDirectory(directory).setCloneAllBranches(true).call();
for (Ref b : repo.branchList().call()) {
System.out.println("(standard): cloned branch " + b.getName());
}
i am using the code
Git git = Git.open(checkout); //checkout is the folder with .git
git.pull().call(); //succeeds
If i chekout a branch
Git git = Git.open(new File(checkout)); //checkout is the folder with .git
System.out.println(git.getRepository().getFullBranch());
CheckoutCommand checkout = git.checkout();
Ref call = checkout.setName("kalees").call();
It throws org.eclipse.jgit.api.errors.RefNotFoundException: Ref kalees can not be resolved.
What is the issue here, if i specify "master" instead of "kalees", it works fine. what change should i do to checkout a specific branch?
if i use the code
git.checkout().setCreateBranch(true).setName("refs/remotes/origin/kalees");
It checkout the kalees branch. but when i do pull operation
git.pull().call();
it throws org.eclipse.jgit.api.errors.DetachedHeadException: HEAD is detached. What could be the , whether this is a checkout issue or pull issue ?
It should only happen if:
kalees isn't an existing branch (or is incorrectly written, bad case)
kalees is a remote branch you haven tracked yet a a local branch
If so you might need to create it first (a bit like in this example)
git.branchCreate().setForce(true).setName("kalees").setStartPoint("origin/kalees").call();
Following "JGit: Cannot find a tutorial or simple example", I would rather use:
git.branchCreate()
.setName("kalees")
.setUpstreamMode(SetupUpstreamMode.SET_UPSTREAM)
.setStartPoint("origin/kalees")
.setForce(true)
.call();
I met this question when I want to create a branch with an empty repository, there is no commit in this repository.
It's resolved when I commit something to the repository. Hope it's helpful for you :)
Muthu your code is working you only need to add origin/branch like this to the branch call
Ref call = checkout.setName("origin/kalees").call();

Categories