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