172

I am building a (somewhat limited) Git client. To set up a repository, you enter the URL to the remote repo. I want to check whether the user has read+write access to that repository. If not, I present an authentication dialog.

I check 'read' access with git ls-remote <url>.

Is there an analogous way to check 'write' access, without cloning the repo first? (I know I could git clone <url> and then git push --dry-run)

4
  • 2
    Well, technically to push a commit into a repo you don't need to clone it first. But remember that pushing a chain of commits and update remote references are two different operations and you may have a permission for the former, but no permission for the latter. Also certain references could be unmodifiable. Commented Apr 2, 2014 at 12:17
  • 'git push --dry-run' is mentioned in this post as a way to check write access, when you have cloned. however for some of my remotes, this opens a password prompt & hangs indefinitely. there doesn't seem to be a non-interactive way to check if you have write access, even if you do have a clone of the repo. how can i check write access to a git repository, if i do have a clone of it? Commented Jan 30, 2020 at 23:10
  • 13
    A very easy way to check is whether you see an edit 'pencil' icon in the top right of the README.MD on the main Code page of the repo (scroll down to it if there's a long list of top level files/folders). Do this when you are logged in to Github, obviously. Commented Nov 13, 2020 at 16:04
  • Regarding trying to use --dry-run... Unfortunately, --dry-run does not check write access to the actual repo (which was the original question). It may check that ssh access to the host works (assuming your repo url uses ssh). But it does not check if (once you have successfully ssh'd) you can then write (push) to the actual repo. I don't know of a way to use git to check for write access. You COULD maybe use test(1) (test -w) on the remote side (assuming unix and test(1) is available to you - like a usable posix shell environment available to you on the remote). Commented May 5, 2025 at 18:32

8 Answers 8

166

If the git repo is in github, open any file in the repo, then click 'edit', github will show something like this:

You’re editing a file in a project you don’t have write access to. We’ve created a fork of this project for you to commit your proposed changes to. Submitting a change to this file will write it to a new branch in your fork, so you can send a pull request.enter code here

Sign up to request clarification or add additional context in comments.

5 Comments

You're not wrong -- Github does indeed show this behaviour. However, the OP asked for something analogous to git ls-remote that their new tool could use, so the Github web UI probably wouldn't suit them.
There are more git repositories than just github repositories ;)
Regarding the GUI, the tooltip can also indicate whether you can "Edit" or "Fork then edit" if no access. This is true with both Github proper and GH Enterprise.
Forking a repo copies the entire repo, right? The repo could be very large. That seems like a pretty hefty operation just to check what your access level is...
@KyleDelaney You don't need to click on the edit button, just hover over it. It will show "Edit this file" or "Edit the file in your fork of this project" depending on whether you have write access or not.
27

Literally just push (with no changes). Git needs credentials even just to attempt a push and report that it's unnecessary.

With correct credentials set up:

$ git push
Everything up-to-date

after messing up my ssh config:

$ git push
ERROR: Permission to [some repo] denied to [my user name].
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

2 Comments

This is easily the best answer! It works for any Git repo (not just GitHub) and doesn't create any dummy commits/branches. Just make sure your local branch is level with the remote before you push otherwise you might push an unwanted extra commit.
Yeah just tried it and though my error message looks a bit different this seems to be the only real answer to the original question with no side effects or github specific dependency
20

With the latest GitHub API you can check the permissions on a particular repo for a USERNAME (yours or another user) with the following command (you'll need to authenticate using your_username and your_personal_access_token) e.g.:

curl -u your_username:your_personal_access_token \
 -H "Accept: application/vnd.github.v3+json" \
 https://api.github.com/repos/octocat/hello-world/collaborators/USERNAME/permission

The response will show what permissions the USERNAME has for that repo.

Otherwise it can report:

{
"message": "Not Found"
}

Or if you don't have push access to the repo in question or it will fail with:

{
  "message": "Must have push access to view collaborator permission.",
  "documentation_url": "https://docs.github.com/rest/reference/repos#get-repository-permissions-for-a-user"
}

1 Comment

If you have the Github CLI, it's even easier: gh api repos/octocat/hello-world/collaborators/USERNAME/permission
5
GIT_TERMINAL_PROMPT=0 git push --dry-run &>/dev/null
  • GIT_TERMINAL_PROMPT=0: fail if you are required to enter credentials manually.

  • git push: try to push changes to origin.

  • --dry-run: simulate the operation, but don't perform it.

  • &>/dev/null: silence any output.

4 Comments

Zero side effects -- very nice! Exactly what I was hoping to find.
--dry-run does not try to write on the remote, so it not only has 0 side effects, it has 0 effects in general.
That's the idea: simulating.
@AlbertoSalviaNovella, Unfortunately, --dry-run does not check write access to the actual repo (which was the original question). It may check that ssh access to the host works. But it does not check if (once you have successfully ssh'd) you can then write (push) to the actual repo. The OP did not ask for simulation: "Is there an analogous way to check 'write' access...".
4

You can use gh (GitHub CLI)'s api subcommand to check your access to a repo (you need to use gh auth login to login to your GitHub account first).

The command is

gh api /repos{/owner}{/repo}/collaborators/USERNAME/permission

This will give you the lots of info.

If you want a command to output either just read or write, run this:

gh api /repos{/owner}{/repo}/collaborators/USERNAME/permission | jq '.permission' -r

1 Comment

Note that "The authenticated user must have push access to the repository to use this endpoint." So this is still a check, but it will return a 404 both for a non-existing repo and one you don't have push access to.
3

Push a harmless branch to the server:

git clone (...)
git branch -a
# Make sure no branch named "test" exists. If it does, use another name.

git branch test
git push -u origin test
# If the above push worked, you have write access

# Cleaning up
git branch -d test
git push -d origin test # only run this if you do have write access

Comments

1

Go the branch that you want to edit and hover over the edit button and it might say "Fork this repository and edit this file", if you have no access to the repository. But suppose you have some access to the repository, then the hover message will show "Edit this file", but you might not have access to commit to the branch. To check access to a particular branch, you can click on the edit button and on the submit changes form,you will see "Commit changes", if you have access. Or if you don't have access, you will see "Propose Changes" as it will create a new branch.

Comments

0

You may perform git push git+ssh://host.org/path/to/repo some_ref without cloning.

But remember that pushing a chain of commits and update remote references are two different operations and you may have a permission for the former, but no permission for the latter. Also certain references could be unmodifiable.

5 Comments

This method would work from a working directory with a ref. Is there a way to do this without setting up a dummy repo and creating a commit first?
Yeah, who wants all these random dummy commits? Isn't there a cleaner way?
Haven't tried this myself, but perhaps the --dry-run parameter could be used to test for push access without pushing a real commit? git-scm.com/docs/git-push#Documentation/git-push.txt---dry-run
--dry-run can't be used for this purpose. Check this answer for explanation: stackoverflow.com/questions/25403573/…
Unfortunately, --dry-run does not check write access to the actual repo (which was the original question). It may check that ssh access to the host works. But it does not check if (once you have successfully ssh'd) you can then write (push) to the actual repo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.