'How to check if remote branch exists on a given remote repository?

I need to do a subtree merge for a specific branch, if it exists on a given remote repository. The problem is that the remote repository is not checked out locally, so I can't use git branch -r. All I have is a remote address, something like this https://github.com/project-name/project-name.git. Is there a way to list remote branches just by a remote address? I couldn't find anything usefull :(

git


Solution 1:[1]

$ git ls-remote --heads [email protected]:user/repo.git branch-name

In case branch-name is found you will get the following output:

b523c9000c4df1afbd8371324083fef218669108        refs/heads/branch-name

Otherwise no output will be sent.

So piping it to wc will give you 1 or 0:

$ git ls-remote --heads [email protected]:user/repo.git branch-name | wc -l

Alternatively you can set --exit-code flag on git ls-remote which will return exit code 2 in case no matching refs are found. The result can be checked directly in a shell test or by checking the status variable $?.

$ git ls-remote --exit-code --heads [email protected]:user/repo.git branch-name

Solution 2:[2]

git ls-remote --heads https://github.com/rails/rails.git
5b3f7563ae1b4a7160fda7fe34240d40c5777dcd    refs/heads/1-2-stable
81d828a14c82b882e31612431a56f830bdc1076f    refs/heads/2-0-stable
b5d759fd2848146f7ee7a4c1b1a4be39e2f1a2bc    refs/heads/2-1-stable
c6cb5a5ab00ac9e857e5b2757d2bce6a5ad14b32    refs/heads/2-2-stable
e0774e47302a907319ed974ccf59b8b54d32bbde    refs/heads/2-3-stable
13ad87971cc16ebc5c286b484821e2cb0fc3e3b1    refs/heads/3-0-stable
3df6c73f9edb3a99f0d51d827ef13a439f31743a    refs/heads/3-1-stable
f4db3d72ea564c77d5a689b850751ce510500585    refs/heads/compressor
c5a809e29e9213102351def7e791c3a8a67d7371    refs/heads/deps_refactor
821e15e5f2d9ef2aa43918a16cbd00f40c221e95    refs/heads/encoding
8f57bf207ff4f28fa8da4544ebc573007b65439d    refs/heads/master
c796d695909c8632b4074b7af69a1ef46c68289a    refs/heads/sass-cleanup
afd7140b66e7cb32e1be58d9e44489e6bcbde0dc    refs/heads/serializers

Solution 3:[3]

You can also use this:

git show-branch remotes/origin/<<remote-branch-name>>

returns latest commit and value of $? is 0 otherwise returns "fatal: bad sha1 reference remotes/origin/<>" and value of $? is 128

Solution 4:[4]

All of the answers here are Linux shell-specific, which doesn't help very much if you're in an environment that doesn't support those sort of operations - for example, Windows' command prompt.

Fortunately git ls-remote accepts an --exit-code argument that returns 0 or 2 depending on whether the branch exists or not, respectively. So:

git ls-remote --exit-code --heads origin <branch-that-exists-in-origin>

will return 0, and

git ls-remote --exit-code --heads origin <branch-that-only-exists-locally>

will return 2.

For PowerShell, you can simply use the built-in truthiness handling semantics:

if (git ls-remote --heads origin <branch-that-exists-in-origin>) { $true } else { $false }

yields $true, while:

if (git ls-remote --heads origin <branch-that-only-exists-locally>) { $true } else { $false }

yields $false.

Solution 5:[5]

Then no need to manually pass the repository name everytime.

git ls-remote origin <branch>

Instead of

git ls-remote <full repo url> <branch>

Example :

git ls-remote [email protected]:landmarkgroupme/in-store-application.git  uat_21dec

OR

git ls-remote origin uat_21dec

Both will give same output :

enter image description here

More on Origin : Git has the concept of "remotes", which are simply URLs to other copies of your repository. When you clone another repository, Git automatically creates a remote named "origin" and points to it. You can see more information about the remote by typing git remote show origin .

Solution 6:[6]

Another way you can use in the current folder if it is a git repo to run

git branch -a | egrep 'remotes/origin/${YOUR_BRANCH_NAME}$'

Solution 7:[7]

You can do something like this in the Bash terminal. Just replace the echos with the commands you want to execute.

if git ls-remote https://username:[email protected]/project-name/project-name.git | grep -sw "remote_branch_name" 2>&1>/dev/null; then echo "IT EXISTS..START MERGE" ; else echo "NOT FOUND" ; fi

Hope it helps.

Solution 8:[8]

$ git ls-remote --heads origin <branch> | wc -l

works most of the time.

But will not work if branch matches partially as below,

$ git branch -a
creative/dev
qa/dev

$ git ls-remote --heads origin dev | wc -l
2

Use

git ls-remote --heads origin <branch> | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^<branch>$ | wc -l

if you want a reliable way.

If you want to use in script and do not want to assume origin as default remote then

git ls-remote --heads $(git remote | head -1) "$branch" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^"$branch"$ | wc -l

should work.

Note that git branch -a | grep ... is not reliable as it may be a while since the last fetch was run.

Solution 9:[9]

Will return all branches (remote or local) that contain the query in the name.

git branch --all | grep <query>

Solution 10:[10]

You can add the repository you have as a remote using git remote add something https://github.com/project-name/project-name.git and then do a git remote show something to get all information about the remote. This requires a network connection and is useful for human use.

Alternatively, do a git fetch something. This will fetch all branches on the remote called something and keep them in your local repository. You can then merge them into your local branch as you please. I recommend this path since if you finally decide that you have to merge, this is what you need to do.

OT: Your use of "checked out locally" indicates that you're approaching this from a centralised version control system standpoint. That's usually a dead end when you're dealing with git. It uses words like "checkout" etc. differently from how older systems did.

Solution 11:[11]

You can try

git diff --quiet @{u} @{0}

Here @{u} refers to remote/upstream, and @{0} refers to current local HEAD (with newer version of git, @{0} can be shortened as @). If remote does not exist, it errors out.

With git 2.16.2 (I am not sure which version is the first to have this functionality, for example, git 1.7.1 doesn't have it), you can do

git checkout

If a remote branch exists, there will be some output, like

Your branch is up to date with 'origin/master'

Otherwise there is no output.

Solution 12:[12]

I'm combining some of the answers above in a script:

BRANCHES=(develop master 7.0 7.0-master)
ORIGIN=bitbucket
REMOTE=github

for BRANCH in "${BRANCHES[@]}"; do
  BRANCH=$(git ls-remote --heads "${ORIGIN}" "${BRANCH}" \
      | cut --delimiter=$'\t' --fields=2 \
      | sed 's,refs/heads/,,' \
      | grep --line-regexp "${BRANCH}")
  if [ -n "${BRANCH}" ]
  then
    git branch --force "${BRANCH}" "${ORIGIN}"/"${BRANCH}"
    git checkout "${BRANCH}"
    git push "${REMOTE}" "${BRANCH}"
  fi
done

git push github --tags

This script will get 4 branches from a remote bitbucket, and push them to a remote github, and will then push all tags to github. I'm using this in a Jenkins job, that's why you don't see any git fetch or git pull, that is already done in the Jenkins job repository config.

I usually prefer long-form options in scripts. I could have combined git branch and git checkout by using git checkout -B.

Solution 13:[13]

How about just

if [ -e .git/refs/remotes/origin/mybranch ]; then
  echo remote branch still exists - locally at least
else
  echo remote branch is gone
fi

git ls-remote will interact with the remote server, which may or may not be what you want.

Solution 14:[14]

If your branch names are very specific, you might not need to use grep for simple branch name matching:

git ls-remote --heads $(git remote | head -1) "*${BRANCH_NAME}*" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    wc -l

which works for

BRANCH=master
BRANCH=mas
BRANCH=NonExistingBranch (returns 0)
BRANCH=ISSUE-123

We use unique issue id as branch names and it works fine.

Solution 15:[15]

I just tried this:

git ls-remote --heads 2>/dev/null|awk -F 'refs/heads/' '{print $2}'|grep -x "your-branch"|wc -l

This will return 1 if branch "your-branch" is found and 0 otherwise.

Solution 16:[16]

This is the simplest way for me.?(? fish shell)

if test (git ls-remote | grep your-branch-name)
  echo exist
else
  echo not_exist
end

Solution 17:[17]

I needed the further requirement to get the name of the remote branch, given input options, e.g. master or main.

~This is someone else's hack but I can't remember where I got it from, sharing here in case it helps another traveler.~ Found it! https://stackoverflow.com/a/68098145, thanks to @Eugene Yarmash

The following will return nothing if neither branch1 or branch2 is extant on the remote and one of the given branch names otherwise.

git branch -l branch1 branch2 | sed 's/^* //'

I use it to set variables for custom git functions, e.g.

branch=$(git branch -l master main | sed 's/^* //')