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