6 Git support

The PKM has a built-in support for the Git distributed version control system, which provides user with a way to synchronize PKM with one or more Git repositories on remote Git servers over HTTP/HTTPS/SSH with as much freedom as possible. It can run a list of any Git commands. Each user has a kind of “wallet” in property git_user_credentials of PKM user (see Chapter 4), which stores the Git user’s credentials either completely or partially (e.g. without the password). Each projects have an on-disk storage on the server, which hosts the PKM, for storing every Git working trees (the workspaces) and Git directories (the .git directories). The PKM synchronizes the PKM Files (see Section 7.1) in the database with those in the Git working trees on the server and vice versa.

6.1 Operations

The PKM provides the following operations for supporting Git:

Run a Git command sequence with bidirectional synchronization between PKM and Git working trees (REST API 🔐, see GitApi.postGitRun in SDK):

POST /git/run/{dbName}?asynchronous=…
{
    "git_commands": [
        [ "clone", "https://gitlab.ow2.org/decoder/pkm-api.git" ],
        [ "cd", "pkm-api" ],
        [ "branch", "mynewbranch" ]
    ],
    "options": {
        "dont_delete_pkm_files": false,
        "dont_delete_git_working_tree_files": false
    }
}

This runs the git command sequence passed in request body in the project with the given name {dbName}. Commands cd or chdir in the command sequence allow changing the working directory to execute subsequent commands within a Git working tree. The operation returns in the response body a Git job which client can poll when in asynchronous mode (i.e. asynchronous=true) using the property id of the job as a job identifier. When in asynchronous mode, the job is enqueued in a job queue. The default behavior is to run jobs synchronously. Section 6.2 describes the role of the dont_delete_pkm_files and dont_delete_git_working_tree_files properties in the request body which are optional.

Poll a Git job (REST API 🔐, see GitApi.getGitJob in SDK):

GET /git/job/{jobId}

When a Git job is running asynchronously, this operation allows polling the Git job with the given identifier {jobId} until job completion. The job is dequeued when client polls a completed job (either finished or failed).

Update Git config file (aka. .git/config) content of a Git working tree (REST API 🔐, see GitApi.putGitConfig in SDK):

PUT /git/config/{dbName}/{gitWorkingTree}
{
    "git_config": "[core]\n…\n[remote \"origin\"]\n…"
}

This updates the Git config file of the given Git working tree {gitWorkingTree} of the project with the given name {dbName} with the content given in the request body.

Insert files in a Git working tree (REST API 🔐, see GitApi.postGitFiles in SDK):

POST /git/files/{dbName}/{gitWorkingTree}
[
    {
        "rel_path": "relative/path/to/file",
        "content": "…",
        "format": "binary"
    }
]

This inserts the given files in the request body into the given Git working tree {gitWorkingTree} of the project with the given name {dbName}.

Insert or update files in a Git working tree (REST API 🔐, see GitApi.putGitFiles in SDK):

PUT /git/files/{dbName}/{gitWorkingTree}
[
    {
        "rel_path": "relative/path/to/file",
        "content": "…",
        "format": "binary"
    }
]

This inserts the given files in the request body into the given Git working tree {gitWorkingTree} of the project with the given name {dbName}, or updates existing files into the given Git working tree {gitWorkingTree} of the project with the given name {dbName} with the ones given in the request body.

Delete all files in a Git working tree (REST API 🔐, see GitApi.deleteGitFiles in SDK):

DELETE /git/files/{dbName}/{gitWorkingTree}

This operation deletes all files of the given Git working tree {gitWorkingTree} of the project with the given name {dbName}.

Delete a file in a Git working tree (REST API 🔐, see GitApi.deleteGitFile in SDK):

DELETE /git/files/{dbName}/{gitWorkingTree}/{filename}

This operation deletes the file with the given name {filename} of the given Git working tree {gitWorkingTree} and the project with the given name {dbName}.

Delete all Git working trees (REST API 🔐, see GitApi.deleteGitWorkingTrees in SDK):

DELETE /git/working_trees/{dbName}?dontDeletePkmFiles=…

This operation deletes all Git working trees of the project with the given name {dbName}. Section 6.2 describes the role of the dontDeletePkmFiles query parameter which is optional.

Delete a Git working tree (REST API 🔐, see GitApi.deleteGitWorkingTree in SDK):

DELETE /git/working_trees/{dbName}/{gitWorkingTree}?dontDeletePkmFiles=…

This operation deletes the given Git working tree {gitWorkingTree} of the project with the given name {dbName}. Section 6.2 describes the role of the dontDeletePkmFiles query parameter which is optional.

Get Git config file (aka. .git/config) of a Git working tree (REST API 🔐, see GitApi.getGitConfig in SDK):

GET /git/config/{dbName}/{gitWorkingTree}

This operation returns in the response body the content of the Git config file of the given Git working tree {gitWorkingTree} of the project with the given name {dbName}.

Get files from a Git working tree (REST API 🔐, see GitApi.getGitFiles in SDK):

GET /git/files/{dbName}/{gitWorkingTree}?abbrev=…

This operation returns in the response body the files of the given Git working tree {gitWorkingTree} and the project with the given name {dbName}. When the abbrev query parameter is set to true, this operation returns only file metadata and suppresses the file content from the response.

Get a file from a Git working tree (REST API 🔐, see GitApi.getGitFile in SDK):

GET /git/files/{dbName}/{gitWorkingTree}/{filename}?abbrev=…

This operation returns in the response body the file with the given name {filename} of the given Git working tree {gitWorkingTree} and the project with the given name {dbName}. When the abbrev query parameter is set to true, this operation returns only file metadata and suppresses the file content from the response.

Get metadata about Git working trees (REST API 🔐, see GitApi.getGitWorkingTrees in SDK):

GET /git/working_trees/{dbName}

This operation returns in the response body the metadata of all Git working trees in the project with the given name {dbName}. The schema for the Git working trees is available on the pkm-api gitlab repository.

Get metadata about a Git working tree (REST API 🔐, see GitApi.getGitWorkingTree in SDK):

GET /git/working_trees/{dbName}/{gitWorkingTree}

This operation returns in the response body the metadata of the given Git working tree {gitWorkingTree} and the project with the given name {dbName}. The schema for the Git working trees is available on the pkm-api gitlab repository.

6.2 Lazy synchronization

Sometimes it is not desirable that the PKM Files get deleted because the file has been removed in the Git working tree by the last Git commands or a by calling one of the DELETE /git/working_trees operations. Similarly, sometimes it is not desirable to delete some files in the Git working tree (because the PKM Files were deleted) because subsequent accidental commit –a and push commands may delete these files on the remote Git server too. The lazy synchronization is a mechanism to overcome these issues by finely tuning the behavior of the former operations.

Some operations have some extra parameters to allow lazy synchronization:

Note that the default behavior of the PKM is to fully synchronize the PKM Files and the Git working trees before and after running a Git command sequence, and after when deleting some files in a Git working tree.