11

I'm using the v3 API and managed to list repos/trees/branches, access file contents, and create blobs/trees/commits. I'm now trying to create a new repo, and managed to do it with "POST user/repos"

But when I try to create blobs/trees/commits/references in this new repo I get the same error message. (409) "Git Repository is empty.". Obviously I can go and init the repository myself through the git command line, but would rather like if my application did it for me.

Is there a way to do that? What's the first thing I need to do through the API after I create an empty repository?

Thanks

Konamiman
  • 49,681
  • 17
  • 108
  • 138
Rui Viana
  • 246
  • 3
  • 6
  • 2
    Looks like they don't support it yet, http://stackoverflow.com/questions/9670604/github-v3-api-how-to-create-initial-commit-for-my-shiny-new-repository – aclark May 29 '12 at 02:25

4 Answers4

3

Since 2012, it is now possible to auto initialize a repository after creation, according to this blog post published on the GitHub blog:

Today we’ve made it easier to add commits to a repository via the GitHub API. Until now, you could create a repository, but you would need to initialize it locally via your Git client before adding any commits via the API.

Now you can optionally init a repository when it’s created by sending true for the auto_init parameter:

curl -i -u pengwynn \
     -d '{"name": "create-repo-test", "auto_init": true}' \
     https://api.github.com/user/repos 

The resulting repository will have a README stub and an initial commit.

gsnedders
  • 5,532
  • 2
  • 30
  • 41
Jai Pandya
  • 2,129
  • 18
  • 29
2

If you want to create an empty initial commit (i.e. one without any file) you can do the following:

  1. Create the repository using the auto_init option as in Jai Pandya's answer; or, if the repository already exists, use the create file endpoint to create a dummy file - this will create the branch:
PUT https://api.github.com/repos/USER/REPO/contents/dummy

{
  "branch": "master",
  "message": "Create a dummy file for the sake of creating a branch",
  "content": "ZHVtbXk="
}

This will give you a bunch of data including a commit SHA, but you can discard all of it since we are about to obliterate that commit.

  1. Use the create commit endpoint to create a commit that points to the empty tree:
POST https://api.github.com/repos/USER/REPO/git/commits

{
  "message": "Initial commit",
  "tree": "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
}

This time you need to take note of the returned commit SHA.

  1. Use the update reference endpoint to make the branch point to the commit you just created (notice the Use Of The ForceTM):
PATCH https://api.github.com/repos/USER/REPO/git/refs/heads/master

{
    "sha": "<the SHA of the commit>",
    "force": true
}
  1. Done! Your repository has now one branch, one commit and zero files.
Konamiman
  • 49,681
  • 17
  • 108
  • 138
  • 1
    Interesting. +1. I documented the empty tree in https://stackoverflow.com/a/9766506/6309 – VonC Nov 26 '18 at 09:27
1

Update May 2013: Note that the repository content API now authorize adding files.

See "File CRUD and repository statistics now available in the API".


Original answer (May 2012)

Since it doesn't seems to be supported yet ("GitHub v3 API: How to create initial commit for my shiny new repository?", as aclark comments), you can start by pushing an initial empty commit

git commit --allow-empty -m 'Initial commit'
git push origin master

That can be a good practice to initialize one's repository anyway.
And it is illustrated in "git's semi-secret empty tree".

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1

2023 January: The 2. step of Konamiman's solution did not work for me, unless I deleted the dummy file with the contents api:

DELETE https://api.github.com/repos/USER/REPO/contents/dummy

{
  "branch": "master",
  "message": "Delete dummy file",
  "sha": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
}

(This sha is for the empty content "".)

After deleting the dummy file somehow 4b825dc642cb6eb9a060e54bf8d69288fbee4904 becomes assignable to a new commit.

It looks like over time this changed. It feels bad to rely on undocumented API behavior. :(

kabalage
  • 11
  • 2