1# Git LFS File Locking API 2 3Added: v2.0 4 5The File Locking API is used to create, list, and delete locks, as well as 6verify that locks are respected in Git pushes. The locking URLs are built 7by adding a suffix to the LFS Server URL. 8 9Git remote: https://git-server.com/foo/bar<br> 10LFS server: https://git-server.com/foo/bar.git/info/lfs<br> 11Locks API: https://git-server.com/foo/bar.git/info/lfs/locks<br> 12 13See the [Server Discovery doc](./server-discovery.md) for more info on how LFS 14builds the LFS server URL. 15 16All File Locking requests require the following HTTP headers: 17 18 Accept: application/vnd.git-lfs+json 19 Content-Type: application/vnd.git-lfs+json 20 21See the [Authentication doc](./authentication.md) for more info on how LFS 22gets authorizes Batch API requests. 23 24Note: This is the first version of the File Locking API, supporting only the 25simplest use case: single branch locking. The API is designed to be extensible 26as we experiment with more advanced locking scenarios, as defined in the 27[original proposal](/docs/proposals/locking.md). 28 29The [Batch API's `ref` property docs](./batch.md#ref-property) describe how the `ref` property can be used to support auth schemes that include the server ref. Locking API implementations should also only use it for authentication, until advanced locking scenarios have been developed. 30 31## Create Lock 32 33The client sends the following to create a lock by sending a `POST` to `/locks` 34(appended to the LFS server url, as described above). Servers should ensure that 35users have push access to the repository, and that files are locked exclusively 36to one user. 37 38* `path` - String path name of the file that is locked. This should be 39relative to the root of the repository working directory. 40* `ref` - Optional object describing the server ref that the locks belong to. Note: Added in v2.4. 41 * `name` - Fully-qualified server refspec. 42 43```js 44// POST https://lfs-server.com/locks 45// Accept: application/vnd.git-lfs+json 46// Content-Type: application/vnd.git-lfs+json 47// Authorization: Basic ... 48{ 49 "path": "foo/bar.zip", 50 "ref": { 51 "name": "refs/heads/my-feature" 52 } 53} 54``` 55 56### Successful Response 57 58Successful responses return the created lock: 59 60* `id` - String ID of the Lock. Git LFS doesn't enforce what type of ID is used, 61as long as it's returned as a string. 62* `path` - String path name of the locked file. This should be relative to the 63root of the repository working directory. 64* `locked_at` - The timestamp the lock was created, as an uppercase 65RFC 3339-formatted string with second precision. 66* `owner` - Optional name of the user that created the Lock. This should be set from 67the user credentials posted when creating the lock. 68 69```js 70// HTTP/1.1 201 Created 71// Content-Type: application/vnd.git-lfs+json 72{ 73 "lock": { 74 "id": "some-uuid", 75 "path": "foo/bar.zip", 76 "locked_at": "2016-05-17T15:49:06+00:00", 77 "owner": { 78 "name": "Jane Doe" 79 } 80 } 81} 82``` 83 84### Bad Response: Lock Exists 85 86Lock services should reject lock creations if one already exists for the given 87path on the current repository. 88 89* `lock` - The existing Lock that clashes with the request. 90* `message` - String error message. 91* `request_id` - Optional String unique identifier for the request. Useful for 92debugging. 93* `documentation_url` - Optional String to give the user a place to report 94errors. 95 96```js 97// HTTP/1.1 409 Conflict 98// Content-Type: application/vnd.git-lfs+json 99{ 100 "lock": { 101 // details of existing lock 102 }, 103 "message": "already created lock", 104 "documentation_url": "https://lfs-server.com/docs/errors", 105 "request_id": "123" 106} 107``` 108 109### Unauthorized Response 110 111Lock servers should require that users have push access to the repository before 112they can create locks. 113 114* `message` - String error message. 115* `request_id` - Optional String unique identifier for the request. Useful for 116debugging. 117* `documentation_url` - Optional String to give the user a place to report 118errors. 119 120```js 121// HTTP/1.1 403 Forbidden 122// Content-Type: application/vnd.git-lfs+json 123{ 124 "message": "You must have push access to create a lock", 125 "documentation_url": "https://lfs-server.com/docs/errors", 126 "request_id": "123" 127} 128``` 129 130### Error Response 131 132* `message` - String error message. 133* `request_id` - Optional String unique identifier for the request. Useful for 134debugging. 135* `documentation_url` - Optional String to give the user a place to report 136errors. 137 138```js 139// HTTP/1.1 500 Internal server error 140// Content-Type: application/vnd.git-lfs+json 141{ 142 "message": "internal server error", 143 "documentation_url": "https://lfs-server.com/docs/errors", 144 "request_id": "123" 145} 146``` 147 148## List Locks 149 150The client can request the current active locks for a repository by sending a 151`GET` to `/locks` (appended to the LFS server url, as described above). LFS 152Servers should ensure that users have at least pull access to the repository. 153 154The properties are sent as URI query values, instead of through a JSON body: 155 156* `path` - Optional string path to match against locks on the server. 157* `id` - Optional string ID to match against a lock on the server. 158* `cursor` - The optional string value to continue listing locks. This value 159should be the `next_cursor` from a previous request. 160* `limit` - The integer limit of the number of locks to return. The server 161should have its own upper and lower bounds on the supported limits. 162* `refspec` - Optional fully qualified server refspec 163from which to search for locks. 164 165```js 166// GET https://lfs-server.com/locks?path=&id=&cursor=&limit=&refspec= 167// Accept: application/vnd.git-lfs+json 168// Authorization: Basic ... (if needed) 169``` 170 171### Successful Response 172 173A successful response will list the matching locks: 174 175* `locks` - Array of matching Lock objects. See the "Create Lock" successful 176response section to see what Lock properties are possible. 177* `next_cursor` - Optional string cursor that the server can return if there 178are more locks matching the given filters. The client will re-do the request, 179setting the `?cursor` query value with this `next_cursor` value. 180 181Note: If the server has no locks, it must return an empty `locks` array. 182 183```js 184// HTTP/1.1 200 Ok 185// Content-Type: application/vnd.git-lfs+json 186{ 187 "locks": [ 188 { 189 "id": "some-uuid", 190 "path": "/path/to/file", 191 "locked_at": "2016-05-17T15:49:06+00:00", 192 "owner": { 193 "name": "Jane Doe" 194 } 195 } 196 ], 197 "next_cursor": "optional next ID" 198} 199``` 200 201### Unauthorized Response 202 203Lock servers should require that users have pull access to the repository before 204they can list locks. 205 206* `message` - String error message. 207* `request_id` - Optional String unique identifier for the request. Useful for 208debugging. 209* `documentation_url` - Optional String to give the user a place to report 210errors. 211 212```js 213// HTTP/1.1 403 Forbidden 214// Content-Type: application/vnd.git-lfs+json 215{ 216 "message": "You must have pull access to list locks", 217 "documentation_url": "https://lfs-server.com/docs/errors", 218 "request_id": "123" 219} 220``` 221 222### Error Response 223 224* `message` - String error message. 225* `request_id` - Optional String unique identifier for the request. Useful for 226debugging. 227* `documentation_url` - Optional String to give the user a place to report 228errors. 229 230```js 231// HTTP/1.1 500 Internal server error 232// Content-Type: application/vnd.git-lfs+json 233{ 234 "message": "unable to list locks", 235 "documentation_url": "https://lfs-server.com/docs/errors", 236 "request_id": "123" 237} 238``` 239 240## List Locks for Verification 241 242The client can use the Lock Verification endpoint to check for active locks 243that can affect a Git push. For a caller, this endpoint is very similar to the 244"List Locks" endpoint above, except: 245 246* Verification requires a `POST` request. 247* The `cursor`, `ref` and `limit` values are sent as properties in the json 248request body. 249* The response includes locks partitioned into `ours` and `theirs` properties. 250 251LFS Servers should ensure that users have push access to the repository. 252 253Clients send the following to list locks for verification by sending a `POST` 254to `/locks/verify` (appended to the LFS server url, as described above): 255 256* `ref` - Optional object describing the server ref that the locks belong to. Note: Added in v2.4. 257 * `name` - Fully-qualified server refspec. 258* `cursor` - Optional cursor to allow pagination. Servers can determine how cursors are formatted based on how they are stored internally. 259* `limit` - Optional limit to how many locks to 260return. 261 262```js 263// POST https://lfs-server.com/locks/verify 264// Accept: application/vnd.git-lfs+json 265// Content-Type: application/vnd.git-lfs+json 266// Authorization: Basic ... 267{ 268 "cursor": "optional cursor", 269 "limit": 100, // also optional 270 "ref": { 271 "name": "refs/heads/my-feature" 272 } 273} 274``` 275 276Note: As more advanced locking workflows are implemented, more details will 277likely be added to this request body in future iterations. 278 279### Successful Response 280 281A successful response will list the relevant locks: 282 283* `ours` - Array of Lock objects currently owned by the authenticated user. 284modify. 285* `theirs` - Array of Lock objects currently owned by other users. 286* `next_cursor` - Optional string cursor that the server can return if there 287are more locks matching the given filters. The client will re-do the request, 288setting the `cursor` property with this `next_cursor` value. 289 290If a Git push updates any files matching any of "our" locks, Git LFS will list 291them in the push output, in case the user will want to unlock them after the 292push. However, any updated files matching one of "their" locks will halt the 293push. At this point, it is up to the user to resolve the lock conflict with 294their team. 295 296Note: If the server has no locks, it must return an empty array in the `ours` or 297`theirs` properties. 298 299```js 300// HTTP/1.1 200 Ok 301// Content-Type: application/vnd.git-lfs+json 302{ 303 "ours": [ 304 { 305 "id": "some-uuid", 306 "path": "/path/to/file", 307 "locked_at": "2016-05-17T15:49:06+00:00", 308 "owner": { 309 "name": "Jane Doe" 310 } 311 } 312 ], 313 "theirs": [], 314 "next_cursor": "optional next ID" 315} 316``` 317 318### Not Found Response 319 320By default, an LFS server that doesn't implement any locking endpoints should 321return 404. This response will not halt any Git pushes. 322 323Any 404 will do, but Git LFS will show a better error message with a json 324response. 325 326* `message` - String error message. 327* `request_id` - Optional String unique identifier for the request. Useful for 328debugging. 329* `documentation_url` - Optional String to give the user a place to report 330errors. 331 332```js 333// HTTP/1.1 404 Not found 334// Content-Type: application/vnd.git-lfs+json 335{ 336 "message": "Not found", 337 "documentation_url": "https://lfs-server.com/docs/errors", 338 "request_id": "123" 339} 340``` 341 342### Unauthorized Response 343 344Lock servers should require that users have push access to the repository before 345they can get a list of locks to verify a Git push. 346 347* `message` - String error message. 348* `request_id` - Optional String unique identifier for the request. Useful for 349debugging. 350* `documentation_url` - Optional String to give the user a place to report 351errors. 352 353```js 354// HTTP/1.1 403 Forbidden 355// Content-Type: application/vnd.git-lfs+json 356{ 357 "message": "You must have push access to verify locks", 358 "documentation_url": "https://lfs-server.com/docs/errors", 359 "request_id": "123" 360} 361``` 362 363### Error Response 364 365* `message` - String error message. 366* `request_id` - Optional String unique identifier for the request. Useful for 367debugging. 368* `documentation_url` - Optional String to give the user a place to report 369errors. 370 371```js 372// HTTP/1.1 500 Internal server error 373// Content-Type: application/vnd.git-lfs+json 374{ 375 "message": "unable to list locks", 376 "documentation_url": "https://lfs-server.com/docs/errors", 377 "request_id": "123" 378} 379``` 380 381## Delete Lock 382 383The client can delete a lock, given its ID, by sending a `POST` to 384`/locks/:id/unlock` (appended to the LFS server url, as described above). LFS 385servers should ensure that callers have push access to the repository. They 386should also prevent a user from deleting another user's lock, unless the `force` 387property is given. 388 389Properties: 390 391* `force` - Optional boolean specifying that the user is deleting another user's 392lock. 393* `ref` - Optional object describing the server ref that the locks belong to. Note: Added in v2.4. 394 * `name` - Fully-qualified server refspec. 395 396```js 397// POST https://lfs-server.com/locks/:id/unlock 398// Accept: application/vnd.git-lfs+json 399// Content-Type: application/vnd.git-lfs+json 400// Authorization: Basic ... 401 402{ 403 "force": true, 404 "ref": { 405 "name": "refs/heads/my-feature" 406 } 407} 408``` 409 410### Successful Response 411 412Successful deletions return the deleted lock. See the "Create Lock" successful 413response section to see what Lock properties are possible. 414 415```js 416// HTTP/1.1 200 Ok 417// Content-Type: application/vnd.git-lfs+json 418{ 419 "lock": { 420 "id": "some-uuid", 421 "path": "/path/to/file", 422 "locked_at": "2016-05-17T15:49:06+00:00", 423 "owner": { 424 "name": "Jane Doe" 425 } 426 } 427} 428``` 429 430### Unauthorized Response 431 432Lock servers should require that users have push access to the repository before 433they can delete locks. Also, if the `force` parameter is omitted, or false, 434the user should only be allowed to delete locks that they created. 435 436* `message` - String error message. 437* `request_id` - Optional String unique identifier for the request. Useful for 438debugging. 439* `documentation_url` - Optional String to give the user a place to report 440errors. 441 442```js 443// HTTP/1.1 403 Forbidden 444// Content-Type: application/vnd.git-lfs+json 445{ 446 "message": "You must have push access to delete locks", 447 "documentation_url": "https://lfs-server.com/docs/errors", 448 "request_id": "123" 449} 450``` 451 452### Error response 453 454* `message` - String error message. 455* `request_id` - Optional String unique identifier for the request. Useful for 456debugging. 457* `documentation_url` - Optional String to give the user a place to report 458errors. 459 460```js 461// HTTP/1.1 500 Internal server error 462// Content-Type: application/vnd.git-lfs+json 463{ 464 "message": "unable to delete lock", 465 "documentation_url": "https://lfs-server.com/docs/errors", 466 "request_id": "123" 467} 468``` 469