Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in DevOps and Agile by (19.4k points)

I have an application that does not fully support git. The requirement is that remote repository is always the single source of truth so

  1. Commits are always pushed right away
  2. Fetch is done before any interaction to update local repository state

This is how I am fetching given branch on request

private void fetchBranch(String branch) throws GitAPIException {

        RefSpec ref = new RefSpec().setSourceDestination(Constants.R_HEADS + branch, Constants.R_REMOTES + Constants.DEFAULT_REMOTE_NAME + "/" + branch)

                .setForceUpdate(true);

        RefSpec ref2 = new RefSpec().setSourceDestination(Constants.R_HEADS + branch, Constants.R_HEADS + branch)

                .setForceUpdate(true);

        git.fetch()

                .setRemote(Constants.DEFAULT_REMOTE_NAME)

                .setRefSpecs(ref2,ref)

                .setCredentialsProvider(credentials.orElse(null))

                .setProgressMonitor(new FetchProgressMonitor(log, configuration))

                .setForceUpdate(true)

                .call();

//        git.branchCreate()

//                .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM)

//                .setName(branch)

//                .setStartPoint(Constants.DEFAULT_REMOTE_NAME + "/" + branch)

//                .setForce(true)

//                .call();

}

My intention here is clearly to update (locally) remote head and local head to the state that is on remote repository.

However, only first ref in setRefSpecs gets updated

My intention is clear here, update 2 references (remotes/origin/branchName, and heads/branchName) with one value (remotes/origin/branchName) with value. I have checked JGit code and I see that there is some sort of check that skips references based on source ref (that is why the first argument is processed and second is not).

How to do it properly using fetch command? Do I really have to do branchChreate with setForce(true) to update the heads/branchName?

It would be convenient to have multiple destination RefSpec, but that does not exist.

1 Answer

0 votes
by (12.4k points)

Here the "FetchCommand" will never change your local branches, rather it will just update remote-tracking branches like for eg. "refs/remotes/origin/foo"

 Usually to fetch changes to a remote-tracking branch then do merge or rebase or even rest the local branch & the remote-tracking branch.

You can the below command to freset the branch to its remote tracking branch:

git.reset().setRef("refs/remotes/origin/foo").setMode(ResetType.HARD).call();

Or if you don't want to reset the branch, use the below command to update:

ObjectId remoteCommitId = repository.resolve("refs/remotes/origin/foo");

repository.updateRef("refs/heads/foo").setNewObjectId(remoteCommitId).forceUpdate();

For more information on Git, you can join git training

Browse Categories

...