0

I created local branch 12345 from origin/master that relevant to gerrit

How I can find the remote name refs/for/master for the local branch 12345

The input is the branch name refs/heads/12345 or part of the string

I calculated it branch Name in :

   public String getCurrentBranch() throws GitException {
        try {
            Ref headRef;
            headRef = repository.getRef(Constants.HEAD);
            return Repository.shortenRefName(headRef.getLeaf().getName());
        } catch (IOException e) {
            throw new GitException(e.getMessage(), e);
        }
    }

How I Can find the result of the remote refs/for/master to res/heads/12345 ?

Do I need to do it from the config ?

user1365697
  • 5,819
  • 15
  • 60
  • 96

2 Answers2

1

You've cross-tagged this as both and (and then also , which seems completely inappropriate here, but I'll leave that to others) and I can only give a pure- answer, which may be unhelpful.

In Git, a branch—by which I mean the branch name, not the structure—can have at most one upstream set. When a branch has an upstream set, the branch is said to track the upstream. This upstream is normally a remote-tracking branch name, e.g., master may track origin/master. The name origin/master is a remote-tracking branch, so we say that "branch master tracks remote-tracking branch origin/master": this has far too many occurrences of the words "branch" and "tracks", each with a different meaning, but we're kind of stuck with it.

A branch that tracks another branch need not track (i.e., have as an upstream) a remote-tracking branch at all. For instance, local branch feature/zorg might track local branch develop. The only things that having an upstream does for you are to automate more of fetch, merge, and rebase (and hence pull which is just fetch followed by one of the other two), and give you more information when running git branch -v (or -vv, etc) and git status. Of course, these are fairly significant, and hence are a reason to set an upstream.

The upstream—the name of the other branch that the given branch is tracking—is set in two parts: a remote, which is the name of a remote if the upstream is a remote-tracking branch, and a branch (name). If the remote is set to ., the branch is tracking another local branch.

These two parts may be obtained individually with git config or git config --get (both do the same thing):

$ git config --get branch.master.remote
origin
$ git config --get branch.master.merge
refs/heads/master

Note that the second part has not undergone the mapping(s) specified by the fetch rule for the given remote:

$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*

Since this mapping says that refs/heads/* becomes refs/remotes/origin/*, we can determine that our name for the remote-tracking branch that corresponds to refs/heads/master on remote origin is in fact refs/remotes/origin/master. (Of course, this mapping is pretty standard and some software might just assume it, but it's better practice to actually do the mapping using the setting(s) for remotes.origin.fetch. There may be more than one, hence the --get-all here.)

Again, if the remote part is set to ., the upstream is actually a local branch, and no mapping should be applied to the merge part.

In shell script, then, you could do something like:

branch="${1:-master}"
has_upstream=true
remote="$(git config --get branch.$branch.remote)" || has_upstream=false
merge="$(git config --get branch.$branch.merge)" || has_upstream=false
if ! $has_upstream; then
    echo "branch $branch has no upstream"
else
    case "$remote" in
        .) echo "branch $branch tracks local branch $merge";;
        *) echo "branch $branch tracks $merge on $remote";;
    esac
fi

This does not help with the mapping, if you'd like to check the remote-tracking branch (you may of course need to run git fetch to update it), but you can get that using git rev-parse:

$ git rev-parse --symbolic-full-name master@{u}
refs/remotes/origin/master

Note that you need to strip refs/remotes/ from the result when it is a remote-tracking branch, if you want to use the short form. Of course if the upstream is a local branch, the full name will begin with refs/heads/ rather than refs/remotes/. If you want the current branch's upstream, a simple @{u} suffices; the name@{u} syntax allows you to find other branches' upstream names.

The @{u} suffix makes rev-parse fail if there is no configured upstream:

$ git rev-parse --symbolic-full-name target@{u}
fatal: no upstream configured for branch 'target'

which offers another way to tell if an upstream is configured.

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775
0

Sorry to be late, but here you go:

private static Ref findCurrentBranch(Git git) throws IOException, GitAPIException {
    String currentBranch = git.getRepository().getFullBranch();

    return git.branchList()
            .setListMode(ListBranchCommand.ListMode.ALL)
            .call()
            .stream()
            .filter(e -> e.getName().equals(currentBranch))
            .findFirst()
            .get();
}

private static Optional<Ref> findRemoteBranch(Git git, Ref branch) throws GitAPIException {
    Optional<Ref> remoteBranch = git.branchList()
            .setListMode(ListBranchCommand.ListMode.REMOTE)
            .call()
            .stream()
            .filter(e -> e.getObjectId().getName().equals(branch.getObjectId().getName()))
            .findFirst();

    return remoteBranch;
}
Jacques Koorts
  • 1,819
  • 1
  • 17
  • 10