Create remote and local branch with jgit - java

I am trying to create a remote branch with jgit, which executes exactly the following git commands:
git clone git#gitlab.com:my-project/test.git
git checkout -b superBranch
git push --set-upstream origin superBranch
After these executions, I can change and push the files of the branch without merge request.
jGit:
Unfortunately jgit does not know the command "push -u" (Upstream). So I found some maybe solution. But all solutions does not work really.
First in StackOverflow:
// git clone done, than:
git.branchCreate()
.setName("superBranch")
.setForce(true)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.setStartPoint("origin/superBranch").call(); // <-- Ref not found
RefSpec refSpec = new RefSpec().setSourceDestination("superBranch", "superBranch");
git.push()
.setRefSpecs(refSpec)
.setCredentialsProvider(provider).call();
git.checkout().setName("superBranch").call();
Exception:
org.eclipse.jgit.api.errors.RefNotFoundException: Ref origin/superBranch cannot be resolved
Another solution I found here Eclipse Forum:
git.branchCreate().setName("superBranch").call();
git.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("superBranch" + ":" + "superBranch")) //<-- Ref not found
.setCredentialsProvider(provider).call();
git.branchCreate()
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM)
.setStartPoint("origin/" + "superBranch")
.setForce(true).call();
git.checkout().setName("superBranch").call();
Exception:
org.eclipse.jgit.api.errors.InvalidRefNameException: Branch name <null> is not allowed
Does anyone know how can I create a remote and local branch, without call an api or make a merge request like my git example on the top?

Following code works for me:
Git git = Git.cloneRepository()
.setURI("https://gitlab.com/my-project/test.git")
.setDirectory(new File("scratch/test"))
.setCloneAllBranches(true)
.setCredentialsProvider(provider).call();
git.checkout()
.setCreateBranch(true)
.setName(BRANCH).call();
git.push()
.setRemote("origin")
.setRefSpecs(new RefSpec(BRANCH + ":" + BRANCH))
.setCredentialsProvider(provider).call();
So I clone the repository, checkout the branch or create the branch if not exits, then I push the new branch to the remote repository.

Finally, I tried this, that works for me.
git.branchCreate().setName(localBranchName).call();
git.push().setRemote("origin")
.setCredentialsProvider(createCredential(name, password))
.setRefSpecs(new RefSpec(localBranchName + ":" + localBranchName)).call();
//delete is necessary
git.branchDelete().setBranchNames(localBranchName).call();
git.checkout().setCreateBranch(true).setName(localBranchName)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.setStartPoint("origin/" + localBranchName)
.call();

Related

Accessing commit details of a specific file using jgit in springboot

I have been trying to get git comit log for a specific file in git repo, but after multiple attempts I am failing to identify the source of the problem.
Here is the link to my github code.
PS: The files Folder needs to be deleted everytime the app needs to start again. Any tips on that would be also helpful.
To put it in short, I tried the below piece of code to get the commit log, but I am getting a null RevCommit.
Repository repository = git.getRepository();
//Approach 1
RevCommit commits = git.log().addPath("D:/Code_downloads/fileaccess/files/dev/Doc2.csv").call().iterator().next();
//Approach 2
RevWalk revWalk = new RevWalk( repository );
revWalk.markStart( revWalk.parseCommit( repository.resolve( Constants.HEAD ) ) );
revWalk.setTreeFilter(PathFilter.create( "D:/Code_downloads/fileaccess/files/dev/Doc2.csv" ) );
revWalk.sort( RevSort.COMMIT_TIME_DESC );
revWalk.sort( RevSort.REVERSE, true );
RevCommit commit = revWalk.next();
Referred multiple documentations and stackoverflow posts. no luck.
https://archive.eclipse.org/jgit/site/4.5.0.201609210915-r/apidocs/org/eclipse/jgit/api/LogCommand.html
Any help will be appreciated.
It should work to use addPath() and then iterate over the RevCommits.
But you should not use the "absoulte path" to the file, but rather only the relative path inside your repository.
E.g.
Iterable<RevCommit logs = git.log().addPath("README.md").call();
for (RevCommit rev : logs) {
System.out.println("Commit: " + rev + ", name: " + rev.getName() + ", id: " + rev.getId().getName());
}
There is a ready-to-run snippet in the jgit-cookbook which shows a few more ways to iterate commits.

RefNotFoundException when creating a branch in JGIT

I have a problem where i cannot create local branch.
Error: org.eclipse.jgit.api.errors.RefNotFoundException: Ref origin/sideMerge cannot be resolved
I have checked the following topics and some others in Stackoverflow but it seems something fishy going on or something i don't understand yet.
Can someone point me to a direction what i don't understand regarding the Ref ?
As far as i know the local refs starts from origin/"other_branch"
Code snippet:
Git git;
CreateBranchCommand tmpCreateBranch;
git = new Git(existingRepo);
tmpCreateBranch = git.branchCreate();
try {
tmpCreateBranch.setName(tmpBranchName).setStartPoint("origin/" + tmpBranchName).setForce(true).call();
} catch (Exception e) {
System.out.println("Error in Branch creation");
System.out.println(e);
}
According to Git manual, you can create a branch using the following syntax. It creates a new branch head named <branchname> which points to the current HEAD, or <start-point> if given:
git branch [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
Therefore, you can create a local branch "topic" by following the similar syntax in JGit (see next code-block). In this case, you didn't configure the start-point explicitly. JGit will use HEAD as start-point. So everything works fine:
git.branchCreate().setName("topic").call();
However, if you create a local branch with start-point origin/topic, JGit will try to find this reference in Git References. In this context, origin is the name of the remote, and topic is the name of the branch. If not found, it raises an exception:
git.branchCreate().setName("topic").setStartPoint("origin/topic").call();
You also need to be aware that:
setForce(true) will reset the target branch name to start-point if branch name exists already. Without -f,--force git branch refuses to change an existing branch.
Szilágyi István, I create the branch as follows:
try (Git git = new Git(repository)) {
Ref ref = git.branchCreate().setName("Name_Branch").setStartPoint("origin/develop").call();
git.checkout().setName(branch).call();
git.push().setCredentialsProvider(userService.getCredencialsProvider()).call();
logger.info("Branch created: " + ref + " - " + ref.getName() + " - " + ref.getObjectId().getName());
}

what is the difference between getPeeledObjectId() and getObjectId() of Ref Object?

I am using jgit api for my project's build, deployment functionalities (in Local Machine). I commited whole source (java project) via command prompt by following commands
git add .
git commit -a -m "Initial_Source"
Here I get the commit id as cb96c685a5a4338f852a782631df8d1cf5dca21d
git tag Initial_Source cb96c685a5a4338f852a782631df8d1cf5dca21d
[cb96c685a5a4338f852a782631df8d1cf5dca21d is commitid]
git push
git push --tags
but when i tried to get commit id via getPeeledObjectId() it is returning null
my code is
Ref tag = git.getRepository().getRef("Initial_Source");
Ref peeledRef = git.getRepository().peel(tag);
return peeledRef.getPeeledObjectId(); -- this is returning null
but instead of getPeeledObjectId() I tried using getObjectId(). It's giving the commitId. But I wanna know when to use getPeelObjectId() and getObjectId().
What are those methods?
The getPeeledObjectId() method is always null on a non-annotated (lightweight) tag:
git tag Initial_Source cb96c685a5a4338f852a782631df8d1cf5dca21d
That would work with an annotated tag
git tag -a Initial_Source cb96c685a5a4338f852a782631df8d1cf5dca21d
# or
git tag -m "Initial Source" Initial_Source cb96c685a5a4338f852a782631df8d1cf5dca21d
Since your tag is a pointer to a commit (referenced by git.getRepository().peel(tag)), getObjectId() gets its id, there is nothing to "peel" again: you already have the commit.
See "What is the difference between an annotated and unannotated tag?"
See porcelain/ListTags.java example: it takes into account the two kinds of tag:
List<Ref> call = git.tagList().call();
for (Ref ref : call) {
System.out.println("Tag: " + ref + " " + ref.getName() + " " + ref.getObjectId().getName());
// fetch all commits for this tag
LogCommand log = git.log();
Ref peeledRef = repository.peel(ref);
if(peeledRef.getPeeledObjectId() != null) {
// Annotated tag
log.add(peeledRef.getPeeledObjectId());
} else {
// Lightweight tag
log.add(ref.getObjectId());
}
}
As #VonC said i think we cannot get ObjectId of a lightweight tag(i.e
a tag without -a or -m) from getPeeledObjectId().
I tried to commit a file and tag that file without -a or -m
[ git
tag Initial_Source cb96c685a5a4338f852a782631df8d1cf5dca21d ].
Then run a java main program to get object Id from
getPeeledObjectId() which obviously returns null.
Then i commit a file and then tag it with -a and -m (any 1 is enough
to act as annotated tag)
[ git tag Appinterface 523a05f9c486e64eba29786a1b8abfc4da421260 -m "Appinterface_commit_tag" ]
Now i am getting objectId from getPeeledObjectId()

Removing remote Git branch using JGit

I am trying to remove a remote branch called test. I don't get any errors while running this code but the remote branch is not getting removed.
'ans' is the destination including the branch id.
This code worked for me when I used the full branch. but I must have changed something because it doesnt work any more.
git.branchDelete().setBranchNames(ans).setForce(true).call();
RefSpec refSpec = new RefSpec()
.setSource(null)
.setDestination("refs/remotes/origin/test");
git.push().setRefSpecs(refSpec).setRemote("origin").call();
Assuming that 'ans' is the full branch name of the local branch e.g. refs/heads/test the branchDelete() code looks ok.
But the destination of the ref spec that is pased to the push command should denote the name of the branch as it is referenced on the remote end. In this case refs/heads/test
RefSpec refSpec = new RefSpec().setSource(null).setDestination("refs/heads/test");
or in short
RefSpec refSpec = new RefSpec(":refs/heads/test");

Getting InvalidConfigurationException in JGit while pulling remote branch

I'm trying to pull the remote master branch in my currently checked out local branch. Here's the code for it
checkout.setName(branchName).call();
PullCommand pullCommand = git.pull();
System.out.println("Pulling master into " + branchName + "...");
StoredConfig config = git.getRepository().getConfig();
config.setString("branch", "master", "merge", "refs/heads/master");
pullCommand.setRemote("https://github.com/blackblood/TattooShop.git");
pullCommand.setRemoteBranchName("master");
pullResult = pullCommand.setCredentialsProvider(credentialsProvider).call();
When I run the code I get the following error on this line pullCommand.setRemote("https://github.com/blackblood/TattooShop.git");
Error :
org.eclipse.jgit.api.errors.InvalidConfigurationException:
No value for key remote.https://github.com/blackblood/TattooShop.git.url found in configurationCouldn't pull from remote. Terminating...
at org.eclipse.jgit.api.PullCommand.call(PullCommand.java:247)
at upload_gen.Launcher.updateFromRemote(Launcher.java:179)
at upload_gen.Launcher.main(Launcher.java:62)
Following are the contents of my .git/config file
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
[remote "origin"]
url = https://github.com/blackblood/TattooShop.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[remote "heroku"]
url = git#heroku.com:tattooshop.git
fetch = +refs/heads/*:refs/remotes/heroku/*
This seems to be a bug in JGit. According to the JavaDoc of setRemote(), it sets the remote (uri or name) to be used for the pull operation but apparently only the remote name works.
Given your configuration you can work around the issue by using the remote name like this:
pullCommand.setRemote( "origin" );
I recommend to open a bug report in the JGit bugzilla so that this gets fixed in future versions of JGit.

Categories

Resources