<commit_before>= Gerrit Code Review - /projects/ REST API

This page describes the project related REST endpoints.
Please also take note of the general information on the
link:rest-api.html[REST API].

[[project-endpoints]]
== Project Endpoints

[[list-projects]]
=== List Projects
--
'GET /projects/'
--

Lists the projects accessible by the caller. This is the same as
using the link:cmd-ls-projects.html[ls-projects] command over SSH,
and accepts the same options as query parameters.

As result a map is returned that maps the project names to
link:#project-info[ProjectInfo] entries. The entries in the map are sorted
by project name.

.Request
----
  GET /projects/?d HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "external/bison": {
      "id": "external%2Fbison",
      "description": "GNU parser generator"
    },
    "external/gcc": {
      "id": "external%2Fgcc"
    },
    "external/openssl": {
      "id": "external%2Fopenssl",
      "description": "encryption\ncrypto routines"
    },
    "test": {
      "id": "test",
      "description": "\u003chtml\u003e is escaped"
    }
  }
----

[[project-options]]
==== Project Options

Branch(b)::
Limit the results to the projects having the specified branch and
include the sha1 of the branch in the results.
+
Get projects that have a 'master' branch:
+
.Request
----
GET /projects/?b=master HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-project": {
      "id": "some-project",
      "branches": {
        "master": "c5ed9dfcbf002ca0e432d788dab6ca2387829ca7"
      }
    },
    "some-other-project": {
      "id": "some-other-project",
      "branches": {
        "master": "ef1c270142f9581ecf768f4193fc8f8a81102ec2"
      }
    },
  }
----

Description(d)::
Include project description in the results.
+
Get all the projects with their description:
+
.Request
----
GET /projects/?d HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-project": {
      "id": "some-project",
      "description": "Description of some project."
    },
    "some-other-project": {
      "id": "some-other-project",
       "description": "Description of some other project."
      }
    },
  }
----

Limit(n)::
Limit the number of projects to be included in the results.
+
Query the first project in the project list:
+
.Request
----
  GET /projects/?n=1 HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-project": {
      "id": "some-project"
    }
  }
----


[[suggest-projects]]
Prefix(p)::
Limit the results to those projects that start with the specified
prefix.
+
The match is case sensitive. May not be used together with `m` or `r`.
+
List all projects that start with `platform/`:
+
.Request
----
  GET /projects/?p=platform%2F HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "platform/drivers": {
      "id": "platform%2Fdrivers"
    },
    "platform/tools": {
      "id": "platform%2Ftools"
    }
  }
----
+
E.g. this feature can be used by suggestion client UI's to limit results.

Regex(r)::
Limit the results to those projects that match the specified regex.
+
Boundary matchers '^' and '$' are implicit. For example: the regex 'test.*' will
match any projects that start with 'test' and regex '.*test' will match any
project that end with 'test'.
+
The match is case sensitive. May not be used together with `m` or `p`.
+
List all projects that match regex `test.*project`:
+
.Request
----
  GET /projects/?r=test.*project HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "test/some-project": {
      "id": "test%2Fsome-project"
    },
    "test/some-other-project": {
      "id": "test%2Fsome-other-project"
    }
  }

----

Skip(S)::
Skip the given number of projects from the beginning of the list.
+
Query the second project in the project list:
+
.Request
----
  GET /projects/?n=1&S=1 HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-other-project": {
      "id": "some-other-project"
    }
  }
----

Substring(m)::
Limit the results to those projects that match the specified substring.
+
The match is case insensitive. May not be used together with `r` or `p`.
+
List all projects that match substring `test/`:
+
.Request
----
  GET /projects/?m=test%2F HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "test/some-project": {
      "id": "test%2Fsome-project"
    },
    "some-path/test/some-other-project": {
      "id": "some-path%2Ftest%2Fsome-other-project"
    }
  }
----

Tree(t)::
Get projects inheritance in a tree-like format. This option does
not work together with the branch option.
+
Get all the projects with tree option:
+
.Request
----
GET /projects/?t HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "All-Projects" {
      "id": "All-Projects"
    },
    "child-project": {
      "id": "child-project",
      "parent":"parent-project"
    },
    "parent-project": {
      "id": "parent-project",
      "parent":"All-Projects"
    }
  }
----

Type(type)::
Get projects with specified type: ALL, CODE, PERMISSIONS.
+
Get all the projects of type 'PERMISSIONS':
+
.Request
----
GET /projects/?type=PERMISSIONS HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "All-Projects" {
      "id": "All-Projects"
    },
    "some-parent-project": {
      "id": "some-parent-project"
    }
  }
----

All::
Get all projects, including those whose state is "HIDDEN". May not be used
together with the `state` option.
+
.Request
----
GET /projects/?all HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "All-Projects" {
      "id": "All-Projects",
      "state": "ACTIVE"
    },
    "some-other-project": {
      "id": "some-other-project",
      "state": "HIDDEN"
    }
  }
----

State(s)::
Get all projects with the given state. May not be used together with the
`all` option.
+
.Request
----
GET /projects/?state=HIDDEN HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-other-project": {
      "id": "some-other-project",
      "state": "HIDDEN"
    }
  }
----

[[query-projects]]
=== Query Projects
--
'GET /projects/?query=<query>'
--

Queries projects visible to the caller. The
link:user-search-projects.html#_search_operators[query string] must be
provided by the `query` parameter. The `start` and `limit` parameters
can be used to skip/limit results.

As result a list of link:#project-info[ProjectInfo] entities is returned.

.Request
----
  GET /projects/?query=name:test HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "test": {
      "id": "test",
      "description": "\u003chtml\u003e is escaped"
    }
  }
----

[[project-query-limit]]
==== Project Limit
The `/projects/?query=<query>` URL also accepts a limit integer in the
`limit` parameter. This limits the results to `limit` projects.

Query the first 25 projects in project list.
----
  GET /projects/?query=<query>&limit=25 HTTP/1.0
----

The `/projects/` URL also accepts a start integer in the `start`
parameter. The results will skip `start` groups from project list.

Query 25 projects starting from index 50.
----
  GET /groups/?query=<query>&limit=25&start=50 HTTP/1.0
----

[[project-query-options]]
==== Project Options
Additional fields can be obtained by adding `o` parameters. Each option
requires more lookups and slows down the query response time to the
client so they are generally disabled by default. The supported fields
are described in the context of the link:#project-options[List Projects]
REST endpoint.

[[get-project]]
=== Get Project
--
'GET /projects/link:#project-name[\{project-name\}]'
--

Retrieves a project.

.Request
----
  GET /projects/plugins%2Freplication HTTP/1.0
----

As response a link:#project-info[ProjectInfo] entity is returned that
describes the project.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "id": "plugins%2Freplication",
    "name": "plugins/replication",
    "parent": "Public-Plugins",
    "description": "Copies to other servers using the Git protocol",
    "state": "ACTIVE",
    "labels": {
      "Code-Review": {
        "values": {
          " 0": "No score",
          "+1": "Approved"
        },
        "default_value": 0
      }
    }
  }
----

[[create-project]]
=== Create Project
--
'PUT /projects/link:#project-name[\{project-name\}]'
--

Creates a new project.

In the request body additional data for the project can be provided as
link:#project-input[ProjectInput].

.Request
----
  PUT /projects/MyProject HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "description": "This is a demo project.",
    "submit_type": "INHERIT",
    "owners": [
      "MyProject-Owners"
    ]
  }
----

As response the link:#project-info[ProjectInfo] entity is returned that
describes the created project.

.Response
----
  HTTP/1.1 201 Created
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "id": "MyProject",
    "name": "MyProject",
    "parent": "All-Projects",
    "description": "This is a demo project.",
    "labels": {
      "Code-Review": {
        "values": {
          " 0": "No score",
          "+1": "Approved"
        },
        "default_value": 0
      }
    }
  }
----

[[get-project-description]]
=== Get Project Description
--
'GET /projects/link:#project-name[\{project-name\}]/description'
--

Retrieves the description of a project.

.Request
----
  GET /projects/plugins%2Freplication/description HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "Copies to other servers using the Git protocol"
----

If the project does not have a description an empty string is returned.

[[set-project-description]]
=== Set Project Description
--
'PUT /projects/link:#project-name[\{project-name\}]/description'
--

Sets the description of a project.

The new project description must be provided in the request body inside
a link:#project-description-input[ProjectDescriptionInput] entity.

.Request
----
  PUT /projects/plugins%2Freplication/description HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "description": "Plugin for Gerrit that handles the replication.",
    "commit_message": "Update the project description"
  }
----

As response the new project description is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "Plugin for Gerrit that handles the replication."
----

If the description was deleted the response is "`204 No Content`".

[[delete-project-description]]
=== Delete Project Description
--
'DELETE /projects/link:#project-name[\{project-name\}]/description'
--

Deletes the description of a project.

The request body does not need to include a
link:#project-description-input[ProjectDescriptionInput] entity if no
commit message is specified.

Please note that some proxies prohibit request bodies for DELETE
requests. In this case, if you want to specify a commit message, use
link:#set-project-description[PUT] to delete the description.

.Request
----
  DELETE /projects/plugins%2Freplication/description HTTP/1.0
----

.Response
----
  HTTP/1.1 204 No Content
----

[[get-project-parent]]
=== Get Project Parent
--
'GET /projects/link:#project-name[\{project-name\}]/parent'
--

Retrieves the name of a project's parent project. For the
`All-Projects` root project an empty string is returned.

.Request
----
  GET /projects/plugins%2Freplication/parent HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "All-Projects"
----

[[set-project-parent]]
=== Set Project Parent
--
'PUT /projects/link:#project-name[\{project-name\}]/parent'
--

Sets the parent project for a project.

The new name of the parent project must be provided in the request body
inside a link:#project-parent-input[ProjectParentInput] entity.

.Request
----
  PUT /projects/plugins%2Freplication/parent HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "parent": "Public-Plugins",
    "commit_message": "Update the project parent"
  }
----

As response the new parent project name is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "Public-Plugins"
----

[[get-head]]
=== Get HEAD
--
'GET /projects/link:#project-name[\{project-name\}]/HEAD'
--

Retrieves for a project the name of the branch to which `HEAD` points.

.Request
----
  GET /projects/plugins%2Freplication/HEAD HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "refs/heads/master"
----

[[set-head]]
=== Set HEAD
--
'PUT /projects/link:#project-name[\{project-name\}]/HEAD'
--

Sets `HEAD` for a project.

The new ref to which `HEAD` should point must be provided in the
request body inside a link:#head-input[HeadInput] entity.

.Request
----
  PUT /projects/plugins%2Freplication/HEAD HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "ref": "refs/heads/stable"
  }
----

As response the new ref to which `HEAD` points is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "refs/heads/stable"
----

[[get-repository-statistics]]
=== Get Repository Statistics
--
'GET /projects/link:#project-name[\{project-name\}]/statistics.git'
--

Return statistics for the repository of a project.

.Request
----
  GET /projects/plugins%2Freplication/statistics.git HTTP/1.0
----

The repository statistics are returned as a
link:#repository-statistics-info[RepositoryStatisticsInfo] entity.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "number_of_loose_objects": 127,
    "number_of_loose_refs": 15,
    "number_of_pack_files": 15,
    "number_of_packed_objects": 67,
    "number_of_packed_refs": 0,
    "size_of_loose_objects": 29466,
    "size_of_packed_objects": 9646
  }
----

[[get-config]]
=== Get Config
--
'GET /projects/link:#project-name[\{project-name\}]/config'
--

Gets some configuration information about a project. Note that this
config info is not simply the contents of `project.config`; it generally
contains fields that may have been inherited from parent projects.

.Request
----
  GET /projects/myproject/config
----

A link:#config-info[ConfigInfo] entity is returned that describes the
project configuration. Some fields are only visible to users that have
read access to `refs/meta/config`.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "description": "demo project",
    "use_contributor_agreements": {
      "value": true,
      "configured_value": "TRUE",
      "inherited_value": false
    },
    "use_content_merge": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": true
    },
    "use_signed_off_by": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "create_new_change_for_all_not_in_target": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "require_change_id": {
      "value": false,
      "configured_value": "FALSE",
      "inherited_value": true
    },
    "max_object_size_limit": {
      "value": "15m",
      "configured_value": "15m",
      "inherited_value": "20m"
    },
    "submit_type": "INHERIT",
    "default_submit_type": {
      "value": "MERGE_IF_NECESSARY",
      "configured_value": "INHERIT",
      "inherited_value": "MERGE_IF_NECESSARY"
    },
    "state": "ACTIVE",
    "commentlinks": {},
    "plugin_config": {
      "helloworld": {
        "language": {
          "display_name": "Preferred Language",
          "type": "STRING",
          "value": "en"
        }
      }
    },
    "actions": {
      "cookbook~hello-project": {
        "method": "POST",
        "label": "Say hello",
        "title": "Say hello in different languages",
        "enabled": true
      }
    }
  }
----

[[set-config]]
=== Set Config
--
'PUT /projects/link:#project-name[\{project-name\}]/config'
--

Sets the configuration of a project.

The new configuration must be provided in the request body as a
link:#config-input[ConfigInput] entity.

.Request
----
  PUT /projects/myproject/config HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "description": "demo project",
    "use_contributor_agreements": "FALSE",
    "use_content_merge": "INHERIT",
    "use_signed_off_by": "INHERIT",
    "create_new_change_for_all_not_in_target": "INHERIT",
    "enable_signed_push": "INHERIT",
    "require_signed_push": "INHERIT",
    "reject_implicit_merges": "INHERIT",
    "require_change_id": "TRUE",
    "max_object_size_limit": "10m",
    "submit_type": "REBASE_IF_NECESSARY",
    "state": "ACTIVE"
  }
----

As response the new configuration is returned as a link:#config-info[
ConfigInfo] entity.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "use_contributor_agreements": {
      "value": false,
      "configured_value": "FALSE",
      "inherited_value": false
    },
    "use_content_merge": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": true
    },
    "use_signed_off_by": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "create_new_change_for_all_not_in_target": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "require_change_id": {
      "value": true,
      "configured_value": "TRUE",
      "inherited_value": true
    },
    "enable_signed_push": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "require_signed_push": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "reject_implicit_merges": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "max_object_size_limit": {
      "value": "10m",
      "configured_value": "10m",
      "inherited_value": "20m"
    },
    "submit_type": "REBASE_IF_NECESSARY",
    "default_submit_type": {
      "value": "REBASE_IF_NECESSARY",
      "configured_value": "INHERIT",
      "inherited_value": "REBASE_IF_NECESSARY"
    },
    "state": "ACTIVE",
    "commentlinks": {}
  }
----

[[run-gc]]
=== Run GC
--
'POST /projects/link:#project-name[\{project-name\}]/gc'
--

Run the Git garbage collection for the repository of a project.

Options for the Git garbage collection can be specified in the
request body as a link:#gc-input[GCInput] entity.

.Request
----
  POST /projects/plugins%2Freplication/gc HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "show_progress": true
  }
----

The response is the streamed output of the garbage collection.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: text/plain; charset=UTF-8

  collecting garbage for "plugins/replication":
  Pack refs:              100% (21/21)
  Counting objects:       20
  Finding sources:        100% (20/20)
  Getting sizes:          100% (13/13)
  Compressing objects:     83% (5/6)
  Writing objects:        100% (20/20)
  Selecting commits:      100% (7/7)
  Building bitmaps:       100% (7/7)
  Finding sources:        100% (41/41)
  Getting sizes:          100% (25/25)
  Compressing objects:     52% (12/23)
  Writing objects:        100% (41/41)
  Prune loose objects also found in pack files: 100% (36/36)
  Prune loose, unreferenced objects: 100% (36/36)
  done.
----

==== Asynchronous Execution

The option `async` allows to schedule a background task that asynchronously
executes a Git garbage collection.

The `Location` header of the response refers to the link:rest-api-config.html#get-task[background task]
which allows to inspect the progress of its execution. In case of asynchronous
execution the `show_progress` option is ignored.

.Request
----
  POST /projects/plugins%2Freplication/gc HTTP/1.0
  Content-Type: application/json;charset=UTF-8

  {
    "async": true
  }
----

The response is empty.

.Response
----
  HTTP/1.1 202 Accepted
  Content-Disposition: attachment
  Location: https:<host>/a/config/server/tasks/383a0602
----

[[ban-commit]]
=== Ban Commit
--
'PUT /projects/link:#project-name[\{project-name\}]/ban'
--

Marks commits as banned for the project. If a commit is banned Gerrit
rejects every push that includes this commit with
link:error-contains-banned-commit.html[contains banned commit ...].

[NOTE]
This REST endpoint only marks the commits as banned, but it does not
remove the commits from the history of any central branch. This needs
to be done manually.

The commits to be banned must be specified in the request body as a
link:#ban-input[BanInput] entity.

The caller must be project owner.

.Request
----
  PUT /projects/plugins%2Freplication/ban HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "commits": [
      "a8a477efffbbf3b44169bb9a1d3a334cbbd9aa96",
      "cf5b56541f84b8b57e16810b18daca9c3adc377b"
    ],
    "reason": "Violates IP"
  }
----

As response a link:#ban-result-info[BanResultInfo] entity is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "newly_banned": [
      "a8a477efffbbf3b44169bb9a1d3a334cbbd9aa96",
      "cf5b56541f84b8b57e16810b18daca9c3adc377b"
    ]
  }
----

[[get-access]]
=== List Access Rights for Project
--
'GET /projects/link:rest-api-projects.html#project-name[\{project-name\}]/access'
--

Lists the access rights for a single project.

As result a
link:rest-api-access.html#project-access-info[ProjectAccessInfo]
entity is returned.

.Request
----
  GET /projects/MyProject/access HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "revision": "61157ed63e14d261b6dca40650472a9b0bd88474",
    "inherits_from": {
      "id": "All-Projects",
      "name": "All-Projects",
      "description": "Access inherited by all other projects."
    },
    "local": {
        "refs/*": {
          "permissions": {
            "read": {
              "rules": {
                "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
                  "action": "ALLOW",
                  "force": false
                },
                "global:Anonymous-Users": {
                  "action": "ALLOW",
                  "force": false
                }
              }
            }
          }
        }
    },
    "is_owner": true,
    "owner_of": [
      "refs/*"
    ],
    "can_upload": true,
    "can_add": true,
    "config_visible": true,
    "groups": {
      "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
        "url": "#/admin/groups/uuid-c2ce4749a32ceb82cd6adcce65b8216e12afb41c",
        "options": {},
        "description": "Users who perform batch actions on Gerrit",
        "group_id": 2,
        "owner": "Administrators",
        "owner_id": "d5b7124af4de52924ed397913e2c3b37bf186948",
        "created_on": "2009-06-08 23:31:00.000000000",
        "name": "Non-Interactive Users"
      },
      "global:Anonymous-Users": {
        "options": {},
        "name": "Anonymous Users"
      }
    }
  }
----

[[set-access]]
=== Add, Update and Delete Access Rights for Project
--
'POST /projects/link:rest-api-projects.html#project-name[\{project-name\}]/access'
--

Sets access rights for the project using the diff schema provided by
link:#project-access-input[ProjectAccessInput]. Deductions are used to
remove access sections, permissions or permission rules. The backend will remove
the entity with the finest granularity in the request, meaning that if an
access section without permissions is posted, the access section will be
removed; if an access section with a permission but no permission rules is
posted, the permission will be removed; if an access section with a permission
and a permission rule is posted, the permission rule will be removed.

Additionally, access sections and permissions will be cleaned up after applying
the deductions by removing items that have no child elements.

After removals have been applied, additions will be applied.

As result a
link:rest-api-access.html#project-access-info[ProjectAccessInfo]
entity is returned.

.Request
----
  POST /projects/MyProject/access HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "remove": [
      {
        "refs/*": {
          "permissions": {
            "read": {
              "rules": {
                "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
                  "action": "ALLOW"
                }
              }
            }
          }
        }
      }
    ]
  }
----

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "revision": "61157ed63e14d261b6dca40650472a9b0bd88474",
    "inherits_from": {
      "id": "All-Projects",
      "name": "All-Projects",
      "description": "Access inherited by all other projects."
    },
    "local": {
        "refs/*": {
          "permissions": {
            "read": {
              "rules": {
                "global:Anonymous-Users": {
                  "action": "ALLOW",
                  "force": false
                }
              }
            }
          }
        }
    },
    "is_owner": true,
    "owner_of": [
      "refs/*"
    ],
    "can_upload": true,
    "can_add": true,
    "config_visible": true,
    "groups": {
      "global:Anonymous-Users": {
        "options": {},
        "name": "Anonymous Users"
      }
    }
  }
----

[[create-access-change]]
=== Create Access Rights Change for review.
--
'PUT /projects/link:rest-api-projects.html#project-name[\{project-name\}]/access:review
--

Sets access rights for the project using the diff schema provided by
link:#project-access-input[ProjectAccessInput]

This takes the same input as link:#set-access[Update Access Rights], but creates a pending
change for review. Like link:#create-change[Create Change], it returns
a link:#change-info[ChangeInfo] entity describing the resulting change.

.Request
----
  PUT /projects/MyProject/access:review HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "add":{
      "refs/heads/*":{
        "permissions":{
          "read":{
            "rules":{
              "global:Anonymous-Users": {
                "action":"DENY",
                "force":false
              }
            }
          }
        }
      }
    }
  }
----

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "id": "testproj~refs%2Fmeta%2Fconfig~Ieaf185bf90a1fc3b58461e399385e158a20b31a2",
    "project": "testproj",
    "branch": "refs/meta/config",
    "hashtags": [],
    "change_id": "Ieaf185bf90a1fc3b58461e399385e158a20b31a2",
    "subject": "Review access change",
    "status": "NEW",
    "created": "2017-09-07 14:31:11.852000000",
    "updated": "2017-09-07 14:31:11.852000000",
    "submit_type": "CHERRY_PICK",
    "mergeable": true,
    "insertions": 2,
    "deletions": 0,
    "unresolved_comment_count": 0,
    "has_review_started": true,
    "_number": 7,
    "owner": {
      "_account_id": 1000000
    }
  }
----

[[check-access]]
=== Check Access
--
'POST /projects/MyProject/check.access'
--

Runs access checks for other users. This requires the
link:access-control.html#capability_administrateServer[Administrate Server]
global capability.

Input for the access checks that should be run must be provided in
the request body inside a
link:#access-check-input[AccessCheckInput] entity.

.Request
----
  POST /projects/MyProject/check.access HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "account": "<EMAIL>",
    "ref": "refs/heads/secret/bla"
  }
----

The result is a link:#access-check-info[AccessCheckInfo] entity
detailing the read access of the given user for the given project (or
project-ref combination).

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "message": "user <NAME> \u003c<EMAIL>\u003e (1000098) cannot see ref refs/heads/secret/bla in project MyProject",
    "status": 403
  }
----

[[index]]
=== Index all changes in a project

Adds or updates all the changes belonging to a project in the secondary index.
The indexing task is executed asynchronously in background, so this command
returns immediately.

.Request
----
  POST /projects/MyProject/index HTTP/1.0
----

.Response
----
HTTP/1.1 202 Accepted
Content-Disposition: attachment
----

[[branch-endpoints]]
== Branch Endpoints

[[list-branches]]
=== List Branches
--
'GET /projects/link:#project-name[\{project-name\}]/branches/'
--

List the branches of a project.

As result a list of link:#branch-info[BranchInfo] entries is
returned.

.Request
----
  GET /projects/work%2Fmy-project/branches/ HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK<commit_msg>Fix indentation in project REST API documentation<commit_after>= Gerrit Code Review - /projects/ REST API

This page describes the project related REST endpoints.
Please also take note of the general information on the
link:rest-api.html[REST API].

[[project-endpoints]]
== Project Endpoints

[[list-projects]]
=== List Projects
--
'GET /projects/'
--

Lists the projects accessible by the caller. This is the same as
using the link:cmd-ls-projects.html[ls-projects] command over SSH,
and accepts the same options as query parameters.

As result a map is returned that maps the project names to
link:#project-info[ProjectInfo] entries. The entries in the map are sorted
by project name.

.Request
----
  GET /projects/?d HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "external/bison": {
      "id": "external%2Fbison",
      "description": "GNU parser generator"
    },
    "external/gcc": {
      "id": "external%2Fgcc"
    },
    "external/openssl": {
      "id": "external%2Fopenssl",
      "description": "encryption\ncrypto routines"
    },
    "test": {
      "id": "test",
      "description": "\u003chtml\u003e is escaped"
    }
  }
----

[[project-options]]
==== Project Options

Branch(b)::
Limit the results to the projects having the specified branch and
include the sha1 of the branch in the results.
+
Get projects that have a 'master' branch:
+
.Request
----
GET /projects/?b=master HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-project": {
      "id": "some-project",
      "branches": {
        "master": "c5ed9dfcbf002ca0e432d788dab6ca2387829ca7"
      }
    },
    "some-other-project": {
      "id": "some-other-project",
      "branches": {
        "master": "ef1c270142f9581ecf768f4193fc8f8a81102ec2"
      }
    },
  }
----

Description(d)::
Include project description in the results.
+
Get all the projects with their description:
+
.Request
----
GET /projects/?d HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-project": {
      "id": "some-project",
      "description": "Description of some project."
    },
    "some-other-project": {
      "id": "some-other-project",
       "description": "Description of some other project."
      }
    },
  }
----

Limit(n)::
Limit the number of projects to be included in the results.
+
Query the first project in the project list:
+
.Request
----
  GET /projects/?n=1 HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-project": {
      "id": "some-project"
    }
  }
----


[[suggest-projects]]
Prefix(p)::
Limit the results to those projects that start with the specified
prefix.
+
The match is case sensitive. May not be used together with `m` or `r`.
+
List all projects that start with `platform/`:
+
.Request
----
  GET /projects/?p=platform%2F HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "platform/drivers": {
      "id": "platform%2Fdrivers"
    },
    "platform/tools": {
      "id": "platform%2Ftools"
    }
  }
----
+
E.g. this feature can be used by suggestion client UI's to limit results.

Regex(r)::
Limit the results to those projects that match the specified regex.
+
Boundary matchers '^' and '$' are implicit. For example: the regex 'test.*' will
match any projects that start with 'test' and regex '.*test' will match any
project that end with 'test'.
+
The match is case sensitive. May not be used together with `m` or `p`.
+
List all projects that match regex `test.*project`:
+
.Request
----
  GET /projects/?r=test.*project HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "test/some-project": {
      "id": "test%2Fsome-project"
    },
    "test/some-other-project": {
      "id": "test%2Fsome-other-project"
    }
  }

----

Skip(S)::
Skip the given number of projects from the beginning of the list.
+
Query the second project in the project list:
+
.Request
----
  GET /projects/?n=1&S=1 HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-other-project": {
      "id": "some-other-project"
    }
  }
----

Substring(m)::
Limit the results to those projects that match the specified substring.
+
The match is case insensitive. May not be used together with `r` or `p`.
+
List all projects that match substring `test/`:
+
.Request
----
  GET /projects/?m=test%2F HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "test/some-project": {
      "id": "test%2Fsome-project"
    },
    "some-path/test/some-other-project": {
      "id": "some-path%2Ftest%2Fsome-other-project"
    }
  }
----

Tree(t)::
Get projects inheritance in a tree-like format. This option does
not work together with the branch option.
+
Get all the projects with tree option:
+
.Request
----
GET /projects/?t HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "All-Projects" {
      "id": "All-Projects"
    },
    "child-project": {
      "id": "child-project",
      "parent":"parent-project"
    },
    "parent-project": {
      "id": "parent-project",
      "parent":"All-Projects"
    }
  }
----

Type(type)::
Get projects with specified type: ALL, CODE, PERMISSIONS.
+
Get all the projects of type 'PERMISSIONS':
+
.Request
----
GET /projects/?type=PERMISSIONS HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "All-Projects" {
      "id": "All-Projects"
    },
    "some-parent-project": {
      "id": "some-parent-project"
    }
  }
----

All::
Get all projects, including those whose state is "HIDDEN". May not be used
together with the `state` option.
+
.Request
----
GET /projects/?all HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "All-Projects" {
      "id": "All-Projects",
      "state": "ACTIVE"
    },
    "some-other-project": {
      "id": "some-other-project",
      "state": "HIDDEN"
    }
  }
----

State(s)::
Get all projects with the given state. May not be used together with the
`all` option.
+
.Request
----
GET /projects/?state=HIDDEN HTTP/1.0
----
+
.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "some-other-project": {
      "id": "some-other-project",
      "state": "HIDDEN"
    }
  }
----

[[query-projects]]
=== Query Projects
--
'GET /projects/?query=<query>'
--

Queries projects visible to the caller. The
link:user-search-projects.html#_search_operators[query string] must be
provided by the `query` parameter. The `start` and `limit` parameters
can be used to skip/limit results.

As result a list of link:#project-info[ProjectInfo] entities is returned.

.Request
----
  GET /projects/?query=name:test HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "test": {
      "id": "test",
      "description": "\u003chtml\u003e is escaped"
    }
  }
----

[[project-query-limit]]
==== Project Limit
The `/projects/?query=<query>` URL also accepts a limit integer in the
`limit` parameter. This limits the results to `limit` projects.

Query the first 25 projects in project list.
----
  GET /projects/?query=<query>&limit=25 HTTP/1.0
----

The `/projects/` URL also accepts a start integer in the `start`
parameter. The results will skip `start` groups from project list.

Query 25 projects starting from index 50.
----
  GET /groups/?query=<query>&limit=25&start=50 HTTP/1.0
----

[[project-query-options]]
==== Project Options
Additional fields can be obtained by adding `o` parameters. Each option
requires more lookups and slows down the query response time to the
client so they are generally disabled by default. The supported fields
are described in the context of the link:#project-options[List Projects]
REST endpoint.

[[get-project]]
=== Get Project
--
'GET /projects/link:#project-name[\{project-name\}]'
--

Retrieves a project.

.Request
----
  GET /projects/plugins%2Freplication HTTP/1.0
----

As response a link:#project-info[ProjectInfo] entity is returned that
describes the project.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "id": "plugins%2Freplication",
    "name": "plugins/replication",
    "parent": "Public-Plugins",
    "description": "Copies to other servers using the Git protocol",
    "state": "ACTIVE",
    "labels": {
      "Code-Review": {
        "values": {
          " 0": "No score",
          "+1": "Approved"
        },
        "default_value": 0
      }
    }
  }
----

[[create-project]]
=== Create Project
--
'PUT /projects/link:#project-name[\{project-name\}]'
--

Creates a new project.

In the request body additional data for the project can be provided as
link:#project-input[ProjectInput].

.Request
----
  PUT /projects/MyProject HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "description": "This is a demo project.",
    "submit_type": "INHERIT",
    "owners": [
      "MyProject-Owners"
    ]
  }
----

As response the link:#project-info[ProjectInfo] entity is returned that
describes the created project.

.Response
----
  HTTP/1.1 201 Created
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "id": "MyProject",
    "name": "MyProject",
    "parent": "All-Projects",
    "description": "This is a demo project.",
    "labels": {
      "Code-Review": {
        "values": {
          " 0": "No score",
          "+1": "Approved"
        },
        "default_value": 0
      }
    }
  }
----

[[get-project-description]]
=== Get Project Description
--
'GET /projects/link:#project-name[\{project-name\}]/description'
--

Retrieves the description of a project.

.Request
----
  GET /projects/plugins%2Freplication/description HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "Copies to other servers using the Git protocol"
----

If the project does not have a description an empty string is returned.

[[set-project-description]]
=== Set Project Description
--
'PUT /projects/link:#project-name[\{project-name\}]/description'
--

Sets the description of a project.

The new project description must be provided in the request body inside
a link:#project-description-input[ProjectDescriptionInput] entity.

.Request
----
  PUT /projects/plugins%2Freplication/description HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "description": "Plugin for Gerrit that handles the replication.",
    "commit_message": "Update the project description"
  }
----

As response the new project description is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "Plugin for Gerrit that handles the replication."
----

If the description was deleted the response is "`204 No Content`".

[[delete-project-description]]
=== Delete Project Description
--
'DELETE /projects/link:#project-name[\{project-name\}]/description'
--

Deletes the description of a project.

The request body does not need to include a
link:#project-description-input[ProjectDescriptionInput] entity if no
commit message is specified.

Please note that some proxies prohibit request bodies for DELETE
requests. In this case, if you want to specify a commit message, use
link:#set-project-description[PUT] to delete the description.

.Request
----
  DELETE /projects/plugins%2Freplication/description HTTP/1.0
----

.Response
----
  HTTP/1.1 204 No Content
----

[[get-project-parent]]
=== Get Project Parent
--
'GET /projects/link:#project-name[\{project-name\}]/parent'
--

Retrieves the name of a project's parent project. For the
`All-Projects` root project an empty string is returned.

.Request
----
  GET /projects/plugins%2Freplication/parent HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "All-Projects"
----

[[set-project-parent]]
=== Set Project Parent
--
'PUT /projects/link:#project-name[\{project-name\}]/parent'
--

Sets the parent project for a project.

The new name of the parent project must be provided in the request body
inside a link:#project-parent-input[ProjectParentInput] entity.

.Request
----
  PUT /projects/plugins%2Freplication/parent HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "parent": "Public-Plugins",
    "commit_message": "Update the project parent"
  }
----

As response the new parent project name is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "Public-Plugins"
----

[[get-head]]
=== Get HEAD
--
'GET /projects/link:#project-name[\{project-name\}]/HEAD'
--

Retrieves for a project the name of the branch to which `HEAD` points.

.Request
----
  GET /projects/plugins%2Freplication/HEAD HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "refs/heads/master"
----

[[set-head]]
=== Set HEAD
--
'PUT /projects/link:#project-name[\{project-name\}]/HEAD'
--

Sets `HEAD` for a project.

The new ref to which `HEAD` should point must be provided in the
request body inside a link:#head-input[HeadInput] entity.

.Request
----
  PUT /projects/plugins%2Freplication/HEAD HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "ref": "refs/heads/stable"
  }
----

As response the new ref to which `HEAD` points is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  "refs/heads/stable"
----

[[get-repository-statistics]]
=== Get Repository Statistics
--
'GET /projects/link:#project-name[\{project-name\}]/statistics.git'
--

Return statistics for the repository of a project.

.Request
----
  GET /projects/plugins%2Freplication/statistics.git HTTP/1.0
----

The repository statistics are returned as a
link:#repository-statistics-info[RepositoryStatisticsInfo] entity.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "number_of_loose_objects": 127,
    "number_of_loose_refs": 15,
    "number_of_pack_files": 15,
    "number_of_packed_objects": 67,
    "number_of_packed_refs": 0,
    "size_of_loose_objects": 29466,
    "size_of_packed_objects": 9646
  }
----

[[get-config]]
=== Get Config
--
'GET /projects/link:#project-name[\{project-name\}]/config'
--

Gets some configuration information about a project. Note that this
config info is not simply the contents of `project.config`; it generally
contains fields that may have been inherited from parent projects.

.Request
----
  GET /projects/myproject/config
----

A link:#config-info[ConfigInfo] entity is returned that describes the
project configuration. Some fields are only visible to users that have
read access to `refs/meta/config`.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "description": "demo project",
    "use_contributor_agreements": {
      "value": true,
      "configured_value": "TRUE",
      "inherited_value": false
    },
    "use_content_merge": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": true
    },
    "use_signed_off_by": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "create_new_change_for_all_not_in_target": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "require_change_id": {
      "value": false,
      "configured_value": "FALSE",
      "inherited_value": true
    },
    "max_object_size_limit": {
      "value": "15m",
      "configured_value": "15m",
      "inherited_value": "20m"
    },
    "submit_type": "INHERIT",
    "default_submit_type": {
      "value": "MERGE_IF_NECESSARY",
      "configured_value": "INHERIT",
      "inherited_value": "MERGE_IF_NECESSARY"
    },
    "state": "ACTIVE",
    "commentlinks": {},
    "plugin_config": {
      "helloworld": {
        "language": {
          "display_name": "Preferred Language",
          "type": "STRING",
          "value": "en"
        }
      }
    },
    "actions": {
      "cookbook~hello-project": {
        "method": "POST",
        "label": "Say hello",
        "title": "Say hello in different languages",
        "enabled": true
      }
    }
  }
----

[[set-config]]
=== Set Config
--
'PUT /projects/link:#project-name[\{project-name\}]/config'
--

Sets the configuration of a project.

The new configuration must be provided in the request body as a
link:#config-input[ConfigInput] entity.

.Request
----
  PUT /projects/myproject/config HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "description": "demo project",
    "use_contributor_agreements": "FALSE",
    "use_content_merge": "INHERIT",
    "use_signed_off_by": "INHERIT",
    "create_new_change_for_all_not_in_target": "INHERIT",
    "enable_signed_push": "INHERIT",
    "require_signed_push": "INHERIT",
    "reject_implicit_merges": "INHERIT",
    "require_change_id": "TRUE",
    "max_object_size_limit": "10m",
    "submit_type": "REBASE_IF_NECESSARY",
    "state": "ACTIVE"
  }
----

As response the new configuration is returned as a link:#config-info[
ConfigInfo] entity.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "use_contributor_agreements": {
      "value": false,
      "configured_value": "FALSE",
      "inherited_value": false
    },
    "use_content_merge": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": true
    },
    "use_signed_off_by": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "create_new_change_for_all_not_in_target": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "require_change_id": {
      "value": true,
      "configured_value": "TRUE",
      "inherited_value": true
    },
    "enable_signed_push": {
      "value": true,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "require_signed_push": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "reject_implicit_merges": {
      "value": false,
      "configured_value": "INHERIT",
      "inherited_value": false
    },
    "max_object_size_limit": {
      "value": "10m",
      "configured_value": "10m",
      "inherited_value": "20m"
    },
    "submit_type": "REBASE_IF_NECESSARY",
    "default_submit_type": {
      "value": "REBASE_IF_NECESSARY",
      "configured_value": "INHERIT",
      "inherited_value": "REBASE_IF_NECESSARY"
    },
    "state": "ACTIVE",
    "commentlinks": {}
  }
----

[[run-gc]]
=== Run GC
--
'POST /projects/link:#project-name[\{project-name\}]/gc'
--

Run the Git garbage collection for the repository of a project.

Options for the Git garbage collection can be specified in the
request body as a link:#gc-input[GCInput] entity.

.Request
----
  POST /projects/plugins%2Freplication/gc HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "show_progress": true
  }
----

The response is the streamed output of the garbage collection.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: text/plain; charset=UTF-8

  collecting garbage for "plugins/replication":
  Pack refs:              100% (21/21)
  Counting objects:       20
  Finding sources:        100% (20/20)
  Getting sizes:          100% (13/13)
  Compressing objects:     83% (5/6)
  Writing objects:        100% (20/20)
  Selecting commits:      100% (7/7)
  Building bitmaps:       100% (7/7)
  Finding sources:        100% (41/41)
  Getting sizes:          100% (25/25)
  Compressing objects:     52% (12/23)
  Writing objects:        100% (41/41)
  Prune loose objects also found in pack files: 100% (36/36)
  Prune loose, unreferenced objects: 100% (36/36)
  done.
----

==== Asynchronous Execution

The option `async` allows to schedule a background task that asynchronously
executes a Git garbage collection.

The `Location` header of the response refers to the link:rest-api-config.html#get-task[background task]
which allows to inspect the progress of its execution. In case of asynchronous
execution the `show_progress` option is ignored.

.Request
----
  POST /projects/plugins%2Freplication/gc HTTP/1.0
  Content-Type: application/json;charset=UTF-8

  {
    "async": true
  }
----

The response is empty.

.Response
----
  HTTP/1.1 202 Accepted
  Content-Disposition: attachment
  Location: https:<host>/a/config/server/tasks/383a0602
----

[[ban-commit]]
=== Ban Commit
--
'PUT /projects/link:#project-name[\{project-name\}]/ban'
--

Marks commits as banned for the project. If a commit is banned Gerrit
rejects every push that includes this commit with
link:error-contains-banned-commit.html[contains banned commit ...].

[NOTE]
This REST endpoint only marks the commits as banned, but it does not
remove the commits from the history of any central branch. This needs
to be done manually.

The commits to be banned must be specified in the request body as a
link:#ban-input[BanInput] entity.

The caller must be project owner.

.Request
----
  PUT /projects/plugins%2Freplication/ban HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "commits": [
      "a8a477efffbbf3b44169bb9a1d3a334cbbd9aa96",
      "cf5b56541f84b8b57e16810b18daca9c3adc377b"
    ],
    "reason": "Violates IP"
  }
----

As response a link:#ban-result-info[BanResultInfo] entity is returned.

.Response
----
  HTTP/1.1 200 OK
  Content-Disposition: attachment
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "newly_banned": [
      "a8a477efffbbf3b44169bb9a1d3a334cbbd9aa96",
      "cf5b56541f84b8b57e16810b18daca9c3adc377b"
    ]
  }
----

[[get-access]]
=== List Access Rights for Project
--
'GET /projects/link:rest-api-projects.html#project-name[\{project-name\}]/access'
--

Lists the access rights for a single project.

As result a
link:rest-api-access.html#project-access-info[ProjectAccessInfo]
entity is returned.

.Request
----
  GET /projects/MyProject/access HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "revision": "61157ed63e14d261b6dca40650472a9b0bd88474",
    "inherits_from": {
      "id": "All-Projects",
      "name": "All-Projects",
      "description": "Access inherited by all other projects."
    },
    "local": {
        "refs/*": {
          "permissions": {
            "read": {
              "rules": {
                "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
                  "action": "ALLOW",
                  "force": false
                },
                "global:Anonymous-Users": {
                  "action": "ALLOW",
                  "force": false
                }
              }
            }
          }
        }
    },
    "is_owner": true,
    "owner_of": [
      "refs/*"
    ],
    "can_upload": true,
    "can_add": true,
    "config_visible": true,
    "groups": {
      "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
        "url": "#/admin/groups/uuid-c2ce4749a32ceb82cd6adcce65b8216e12afb41c",
        "options": {},
        "description": "Users who perform batch actions on Gerrit",
        "group_id": 2,
        "owner": "Administrators",
        "owner_id": "d5b7124af4de52924ed397913e2c3b37bf186948",
        "created_on": "2009-06-08 23:31:00.000000000",
        "name": "Non-Interactive Users"
      },
      "global:Anonymous-Users": {
        "options": {},
        "name": "Anonymous Users"
      }
    }
  }
----

[[set-access]]
=== Add, Update and Delete Access Rights for Project
--
'POST /projects/link:rest-api-projects.html#project-name[\{project-name\}]/access'
--

Sets access rights for the project using the diff schema provided by
link:#project-access-input[ProjectAccessInput]. Deductions are used to
remove access sections, permissions or permission rules. The backend will remove
the entity with the finest granularity in the request, meaning that if an
access section without permissions is posted, the access section will be
removed; if an access section with a permission but no permission rules is
posted, the permission will be removed; if an access section with a permission
and a permission rule is posted, the permission rule will be removed.

Additionally, access sections and permissions will be cleaned up after applying
the deductions by removing items that have no child elements.

After removals have been applied, additions will be applied.

As result a
link:rest-api-access.html#project-access-info[ProjectAccessInfo]
entity is returned.

.Request
----
  POST /projects/MyProject/access HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "remove": [
      {
        "refs/*": {
          "permissions": {
            "read": {
              "rules": {
                "c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
                  "action": "ALLOW"
                }
              }
            }
          }
        }
      }
    ]
  }
----

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "revision": "<PASSWORD>",
    "inherits_from": {
      "id": "All-Projects",
      "name": "All-Projects",
      "description": "Access inherited by all other projects."
    },
    "local": {
        "refs/*": {
          "permissions": {
            "read": {
              "rules": {
                "global:Anonymous-Users": {
                  "action": "ALLOW",
                  "force": false
                }
              }
            }
          }
        }
    },
    "is_owner": true,
    "owner_of": [
      "refs/*"
    ],
    "can_upload": true,
    "can_add": true,
    "config_visible": true,
    "groups": {
      "global:Anonymous-Users": {
        "options": {},
        "name": "Anonymous Users"
      }
    }
  }
----

[[create-access-change]]
=== Create Access Rights Change for review.
--
'PUT /projects/link:rest-api-projects.html#project-name[\{project-name\}]/access:review
--

Sets access rights for the project using the diff schema provided by
link:#project-access-input[ProjectAccessInput]

This takes the same input as link:#set-access[Update Access Rights], but creates a pending
change for review. Like link:#create-change[Create Change], it returns
a link:#change-info[ChangeInfo] entity describing the resulting change.

.Request
----
  PUT /projects/MyProject/access:review HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "add":{
      "refs/heads/*":{
        "permissions":{
          "read":{
            "rules":{
              "global:Anonymous-Users": {
                "action":"DENY",
                "force":false
              }
            }
          }
        }
      }
    }
  }
----

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "id": "testproj~refs%2Fmeta%2Fconfig~Ieaf185bf90a1fc3b58461e399385e158a20b31a2",
    "project": "testproj",
    "branch": "refs/meta/config",
    "hashtags": [],
    "change_id": "Ieaf185bf90a1fc3b58461e399385e158a20b31a2",
    "subject": "Review access change",
    "status": "NEW",
    "created": "2017-09-07 14:31:11.852000000",
    "updated": "2017-09-07 14:31:11.852000000",
    "submit_type": "CHERRY_PICK",
    "mergeable": true,
    "insertions": 2,
    "deletions": 0,
    "unresolved_comment_count": 0,
    "has_review_started": true,
    "_number": 7,
    "owner": {
      "_account_id": 1000000
    }
  }
----

[[check-access]]
=== Check Access
--
'POST /projects/MyProject/check.access'
--

Runs access checks for other users. This requires the
link:access-control.html#capability_administrateServer[Administrate Server]
global capability.

Input for the access checks that should be run must be provided in
the request body inside a
link:#access-check-input[AccessCheckInput] entity.

.Request
----
  POST /projects/MyProject/check.access HTTP/1.0
  Content-Type: application/json; charset=UTF-8

  {
    "account": "<EMAIL>",
    "ref": "refs/heads/secret/bla"
  }
----

The result is a link:#access-check-info[AccessCheckInfo] entity
detailing the read access of the given user for the given project (or
project-ref combination).

.Response
----
  HTTP/1.1 200 OK
  Content-Type: application/json; charset=UTF-8

  )]}'
  {
    "message": "user <NAME> \u003c<EMAIL>\u003e (1000098) cannot see ref refs/heads/secret/bla in project MyProject",
    "status": 403
  }
----

[[index]]
=== Index all changes in a project

Adds or updates all the changes belonging to a project in the secondary index.
The indexing task is executed asynchronously in background, so this command
returns immediately.

.Request
----
  POST /projects/MyProject/index HTTP/1.0
----

.Response
----
  HTTP/1.1 202 Accepted
  Content-Disposition: attachment
----

[[branch-endpoints]]
== Branch Endpoints

[[list-branches]]
=== List Branches
--
'GET /projects/link:#project-name[\{project-name\}]/branches/'
--

List the branches of a project.

As result a list of link:#branch-info[BranchInfo] entries is
returned.

.Request
----
  GET /projects/work%2Fmy-project/branches/ HTTP/1.0
----

.Response
----
  HTTP/1.1 200 OK
{'fraction_non_alphanumeric': 0.14469051301457764, 'fraction_numerical': 0.029615979466254237, 'mean_word_length': 2.805585123035502, 'pattern_counts': {'":': 592, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2345565', 'n_tokens_mistral': 21158, 'n_tokens_neox': 19645, 'n_words': 5211}