Pushing Tags with GitWorkTree

In order to make our apps Bitbucket 8.0 compatible, we are migrating existing code to the GitWorkTree API.

Our app cloned and pushed a git repo with all it’s branches and tags. I’m wondering how I can do that.

The branches seems possible by using the GitWorkTree.publish.
Looks like it has to be invoked for each branch, or is the a way to push multiple branches at once?

    gitWorkTree.publish(
      new PublishGitWorkTreeParameters.Builder(invoker)
        .author(author)
        .branch(mainBranch.name, expectedCommitHash)
        .build())

What I’m not sure is how to push branches. I didn’t find a obvious way on how to push tags?
Maybe use the .branch(“refs/tags/tag-name”, ???) on the publish paramters?

Another API which seems possible, but doesn’t work is to directly use the push command. Like this:

    val cmd = gitWorkTree.builder()
      .push()
      .repository(gitWorkTree.getRepository)
      .refspecs(s"master:master")
      .build(new LoggingCommandOutputHandler)

However, this fails with the missing pre-receive hook setup.

[INFO] com.atlassian.bitbucket.scm.CommandFailedException: '/usr/bin/git push /home/roman/dev/repository-templates/target/bitbucket/home/shared/data/repositories/19 refs/heads/master:refs/heads/master' exited with code 1 saying: remote: hooks/pre-receive: line 9: /home/roman/dev/repository-templates/target/bitbucket/home/shared/data/repositories/19/hooks/pre-receive.d: Is a directory        
[INFO] remote: hooks/pre-receive: line 9: exec: /home/roman/dev/repository-templates/target/bitbucket/home/shared/data/repositories/19/hooks/pre-receive.d: cannot execute: Is a directory        

Is there something I’m missing. Or is the push API not supported? There is no hint that the ‘.push()’ command won’t work.

Anyway, and input on how to push tags with the GitWorkTree api would be helpful.

1 Like

We also get the same error using the git push Java API.
We found https://jira.atlassian.com/browse/BSERV-2936 existed for this error (bug?).

@RomanStoffel,

I’ll need to look into the push behavior a bit further. In the interim, one approach that would definitely work is to publish your work tree changes to a branch and then create a tag using RefService.createTag. If your goal is to create tags that reference commits that aren’t present on any branch, with the current work tree API I suspect that may not be possible. RefService.createTag will allow you to tag any commit, so from that perspective it’s fine. The issue is with getting your commit(s) out of the work tree into the real repository without updating a branch. If you’re trying to update a branch and tag it, though, then what’s already available should be enough.

As for hooks the error, from 8.0 it should no longer be possible to get the hooks/pre-receive error you’re showing because we no longer process hooks/pre-receive.d scripts. My own testing does not produce that error, in the current 8.0.0-rc2 codebase. (It still doesn’t allow the push, to be clear; it just doesn’t fail that specific way.) As I said, that part bears further investigation.

Best regards,
Bryan Turner
Atlassian Bitbucket

@BIF01,

If you’re trying to build something that only works on 7.x, you may be able to use HookService.doWithHookRequest “around” your builder code. You’d pass in the ID of the repository you’re trying to push to, not where you’re pushing from. Inside the callback, you’d apply the various ENV_* constants on HookRequestHandle to your builder using withEnvironment. Each environment variable matches up with an accessor on HookRequestHandle. (For example, ENV_HOOK_REQUEST_ID is HookRequestHandle.getRequestId().)

This will not work using the WorkTree API, however–not to mention the HookService is no longer in the API in 8.0. For a solution that works in 8.0, stay tuned.

Best regards,
Bryan Turner
Atlassian Bitbucket

Thanks for the hint about the RefService.create tag =). That might be a possible solution.

I’m currently pausing the Git tag investigation, as its a low priority issue for us =).
But it’s good to know that there might be a feasible solution to create tags.

Hi,

Here is the solution which worked for us. We skipped the GitWorkTree API and instead use the GitCommandBuilderFactory with the ‘fetch’ command. In the ‘fetch’ case the tags can be copied:

    GitCommandBuilderFactory gitOperations = ....
    val commandFactory = gitOperations.builder(newRepo)
    val fetch = commandFactory.fetch()
      .repository(sourceRepo)
      .refspecs("+refs/heads/*:refs/heads/*", "+refs/tags/*:refs/tags/*")
      .build(loggingCommandHandler())

Thanks for the help in this and the Bitbucket EAP thread.

1 Like