Search code examples
github-api

How to create submodule in GitHub using GitHub Rest Api


I found that GitHub has Create Tree and Create File API, but I am still not sure how to create the submodule item, for Create Tree Api, how to specify the Sha, for Create File Api, it seems we can't set item type. BTW, do I need to first create the .gitmodules file?


Solution

  • I was trying to do this earlier today.

    Here's my workflow:

    1. Create a tree
    2. Create a commit
    3. Update the reference

    Let me give a little example to make it more clear.

    Say the latest commit on the master branch of the repo you want to add a submodule is $BASE_SHA.


    1. Create a tree

    Assuming you don't have any submodules on your repo yet, you'll need to create a file named .gitmodules first. And then you can create a reference to it.

    POST /repos/:owner/:repo/git/trees
    {
        "base_tree": $BASE_SHA,
        "tree": [
            // create submodule config
            {
                "path": ".gitmodules",
                "mode": "100644",
                "type": "blob",
                "content": "[submodule \"rails\"]\n\tpath = rails\n\turl = https://github.com/rails/rails"
            },
            // link to submodule
            {
                "path": "rails",
                "mode": "160000", 
                "type": "commit",
                "sha": "39e087cbf5628ecc351fc86a3a1e320be193bf29"
            }
        ]
    }
    

    The API server will then send a response to you

    {
      "sha": $TREE_SHA,
      "url": "...",
      "tree": [...]
    }
    



    2. Create a commit

    We then use the sha of the newly created tree to create a commit (with $BASE_SHA as its parent).

    POST /repos/:owner/:repo/git/commits
    {
        "message": "commit message",
        "tree": $TREE_SHA,
        "parents": [$BASE_SHA]
    }
    

    And the server will return

    {
        "sha": $COMMIT_SHA,
        "url": "...",
        // other content omitted here ..
    }
    

    3. Update the reference

    We then need to update the master.

    PATCH /repos/:owner/:repo/git/refs/heads/master
    {
        "sha": $COMMIT_SHA,
        "force": true
    }
    

    And we're all set if no error is returned.

    Refresh your GitHub repo page and you'll find the submodule is added.