'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 :(
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 :
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/^* //')
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow