Commit
+261 -15 +/-8 browse
1 | diff --git a/.dockerignore b/.dockerignore |
2 | index 8d42d79..a6a6140 100644 |
3 | --- a/.dockerignore |
4 | +++ b/.dockerignore |
5 | @@ -3,5 +3,6 @@ |
6 | |
7 | # Only include these files. |
8 | !/src/** |
9 | + !/templates/** |
10 | !/Cargo.toml |
11 | !/Cargo.lock |
12 | diff --git a/Cargo.lock b/Cargo.lock |
13 | index 4db1c72..425a6db 100644 |
14 | --- a/Cargo.lock |
15 | +++ b/Cargo.lock |
16 | @@ -44,6 +44,46 @@ dependencies = [ |
17 | ] |
18 | |
19 | [[package]] |
20 | + name = "askama" |
21 | + version = "0.8.0" |
22 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
23 | + dependencies = [ |
24 | + "askama_derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
25 | + "askama_escape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
26 | + "askama_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
27 | + ] |
28 | + |
29 | + [[package]] |
30 | + name = "askama_derive" |
31 | + version = "0.8.0" |
32 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
33 | + dependencies = [ |
34 | + "askama_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
35 | + "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", |
36 | + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", |
37 | + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", |
38 | + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", |
39 | + ] |
40 | + |
41 | + [[package]] |
42 | + name = "askama_escape" |
43 | + version = "0.2.0" |
44 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
45 | + |
46 | + [[package]] |
47 | + name = "askama_shared" |
48 | + version = "0.8.0" |
49 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
50 | + dependencies = [ |
51 | + "askama_escape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
52 | + "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
53 | + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", |
54 | + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", |
55 | + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", |
56 | + "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", |
57 | + ] |
58 | + |
59 | + [[package]] |
60 | name = "atty" |
61 | version = "0.2.11" |
62 | source = "registry+https://github.com/rust-lang/crates.io-index" |
63 | @@ -464,6 +504,11 @@ version = "0.4.0" |
64 | source = "registry+https://github.com/rust-lang/crates.io-index" |
65 | |
66 | [[package]] |
67 | + name = "humansize" |
68 | + version = "1.1.0" |
69 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
70 | + |
71 | + [[package]] |
72 | name = "humantime" |
73 | version = "1.2.0" |
74 | source = "registry+https://github.com/rust-lang/crates.io-index" |
75 | @@ -693,6 +738,15 @@ version = "0.1.13" |
76 | source = "registry+https://github.com/rust-lang/crates.io-index" |
77 | |
78 | [[package]] |
79 | + name = "nom" |
80 | + version = "4.2.3" |
81 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
82 | + dependencies = [ |
83 | + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
84 | + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
85 | + ] |
86 | + |
87 | + [[package]] |
88 | name = "num-integer" |
89 | version = "0.1.39" |
90 | source = "registry+https://github.com/rust-lang/crates.io-index" |
91 | @@ -948,6 +1002,7 @@ dependencies = [ |
92 | name = "rudolfs" |
93 | version = "0.2.2" |
94 | dependencies = [ |
95 | + "askama 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
96 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", |
97 | "chacha 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
98 | "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", |
99 | @@ -1512,6 +1567,14 @@ dependencies = [ |
100 | ] |
101 | |
102 | [[package]] |
103 | + name = "toml" |
104 | + version = "0.4.10" |
105 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
106 | + dependencies = [ |
107 | + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", |
108 | + ] |
109 | + |
110 | + [[package]] |
111 | name = "try-lock" |
112 | version = "0.2.2" |
113 | source = "registry+https://github.com/rust-lang/crates.io-index" |
114 | @@ -1591,6 +1654,11 @@ version = "0.8.1" |
115 | source = "registry+https://github.com/rust-lang/crates.io-index" |
116 | |
117 | [[package]] |
118 | + name = "version_check" |
119 | + version = "0.1.5" |
120 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
121 | + |
122 | + [[package]] |
123 | name = "want" |
124 | version = "0.0.6" |
125 | source = "registry+https://github.com/rust-lang/crates.io-index" |
126 | @@ -1688,6 +1756,10 @@ dependencies = [ |
127 | "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" |
128 | "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" |
129 | "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" |
130 | + "checksum askama 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc2a4b6d7f812d2b13d251ae792caecebd635d6401761162d4b71d5ebe1a010" |
131 | + "checksum askama_derive 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ee2fff0f22ad5d215cace1227cd036c28e81e26206763bb837b6d0e766c87d" |
132 | + "checksum askama_escape 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0de942230b5beedaa9e1d64df5b76fa1c97002e4c7982897be899cccf40621d" |
133 | + "checksum askama_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6dfa6b6d254fd066a8bbed9a8f913123e3f701db89216ad4f0aff04ad87718c" |
134 | "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" |
135 | "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" |
136 | "checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" |
137 | @@ -1739,6 +1811,7 @@ dependencies = [ |
138 | "checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a" |
139 | "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" |
140 | "checksum human-size 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bec6e801ef7367625bd94ad7e2965e6027189f3e9deef422388d993af2814a0" |
141 | + "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" |
142 | "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" |
143 | "checksum hyper 0.12.25 (registry+https://github.com/rust-lang/crates.io-index)" = "7d5b6658b016965ae301fa995306db965c93677880ea70765a84235a96eae896" |
144 | "checksum hyper-rustls 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "15b66d1bd4864ef036adf2363409caa3acd63ebb4725957b66e621c8a36631a3" |
145 | @@ -1765,6 +1838,7 @@ dependencies = [ |
146 | "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" |
147 | "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" |
148 | "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" |
149 | + "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" |
150 | "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" |
151 | "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" |
152 | "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" |
153 | @@ -1848,6 +1922,7 @@ dependencies = [ |
154 | "checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3" |
155 | "checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" |
156 | "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" |
157 | + "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" |
158 | "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" |
159 | "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" |
160 | "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" |
161 | @@ -1861,6 +1936,7 @@ dependencies = [ |
162 | "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" |
163 | "checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768" |
164 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" |
165 | + "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" |
166 | "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" |
167 | "checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" |
168 | "checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" |
169 | diff --git a/Cargo.toml b/Cargo.toml |
170 | index b97a2d5..aea5ecd 100644 |
171 | --- a/Cargo.toml |
172 | +++ b/Cargo.toml |
173 | @@ -15,6 +15,7 @@ categories = ["command-line-utilities"] |
174 | license = "MIT" |
175 | |
176 | [dependencies] |
177 | + askama = "0.8" |
178 | bytes = "0.4" |
179 | chacha = "0.3" |
180 | derive_more = "0.14" |
181 | diff --git a/src/app.rs b/src/app.rs |
182 | index 08c3ecd..1721486 100644 |
183 | --- a/src/app.rs |
184 | +++ b/src/app.rs |
185 | @@ -20,15 +20,12 @@ |
186 | use std::io; |
187 | use std::sync::Arc; |
188 | |
189 | + use askama::Template; |
190 | use futures::{ |
191 | future::{self, Either}, |
192 | Future, IntoFuture, Stream, |
193 | }; |
194 | - use http::{ |
195 | - self, header, |
196 | - uri::{Authority, Scheme}, |
197 | - StatusCode, Uri, |
198 | - }; |
199 | + use http::{self, header, StatusCode, Uri}; |
200 | use hyper::{self, service::Service, Chunk, Method, Request, Response}; |
201 | |
202 | use crate::error::Error; |
203 | @@ -36,6 +33,13 @@ use crate::hyperext::{into_request, Body, IntoResponse, RequestExt}; |
204 | use crate::lfs; |
205 | use crate::storage::{LFSObject, Namespace, Storage, StorageKey}; |
206 | |
207 | + #[derive(Template)] |
208 | + #[template(path = "index.html")] |
209 | + struct IndexTemplate<'a> { |
210 | + title: &'a str, |
211 | + api: Uri, |
212 | + } |
213 | + |
214 | /// Shared state for all instances of the `App` service. |
215 | pub struct State<S> { |
216 | // Storage backend. |
217 | @@ -63,6 +67,18 @@ where |
218 | App { state } |
219 | } |
220 | |
221 | + /// Handles the index route. |
222 | + fn index(&mut self, req: Request<Body>) -> Result<Response<Body>, Error> { |
223 | + let template = IndexTemplate { |
224 | + title: "Rudolfs", |
225 | + api: req.base_uri().path_and_query("/api").build().unwrap(), |
226 | + }; |
227 | + |
228 | + Ok(Response::builder() |
229 | + .status(StatusCode::OK) |
230 | + .body(template.render()?.into())?) |
231 | + } |
232 | + |
233 | /// Generates a "404 not found" response. |
234 | fn not_found( |
235 | &mut self, |
236 | @@ -253,15 +269,7 @@ where |
237 | namespace: Namespace, |
238 | ) -> impl Future<Item = Response<Body>, Error = Error> { |
239 | // Get the host name and scheme. |
240 | - let uri = Uri::builder() |
241 | - .scheme(req.scheme().unwrap_or(Scheme::HTTP)) |
242 | - .authority( |
243 | - req.authority() |
244 | - .unwrap_or_else(|| Authority::from_static("localhost")), |
245 | - ) |
246 | - .path_and_query("/") |
247 | - .build() |
248 | - .unwrap(); |
249 | + let uri = req.base_uri().path_and_query("/").build().unwrap(); |
250 | |
251 | let state = self.state.clone(); |
252 | |
253 | @@ -445,6 +453,10 @@ where |
254 | fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future { |
255 | let req = into_request(req); |
256 | |
257 | + if req.uri().path() == "/" { |
258 | + return self.index(req).response(); |
259 | + } |
260 | + |
261 | if req.uri().path().starts_with("/api/") { |
262 | return self.api(req).response(); |
263 | } |
264 | diff --git a/src/error.rs b/src/error.rs |
265 | index 419087d..ee5e27d 100644 |
266 | --- a/src/error.rs |
267 | +++ b/src/error.rs |
268 | @@ -19,6 +19,7 @@ |
269 | // SOFTWARE. |
270 | use std::io; |
271 | |
272 | + use askama; |
273 | use derive_more::{Display, From}; |
274 | use http; |
275 | use hyper; |
276 | @@ -38,6 +39,7 @@ pub enum Error { |
277 | Sha256VerifyError(Sha256VerifyError), |
278 | S3(storage::S3Error), |
279 | S3DiskCache(<storage::S3DiskCache as Storage>::Error), |
280 | + Askama(askama::Error), |
281 | } |
282 | |
283 | impl std::error::Error for Error {} |
284 | diff --git a/src/hyperext.rs b/src/hyperext.rs |
285 | index cd25498..c3d3f7c 100644 |
286 | --- a/src/hyperext.rs |
287 | +++ b/src/hyperext.rs |
288 | @@ -21,7 +21,7 @@ use std::ops::Deref; |
289 | |
290 | use derive_more::From; |
291 | use futures::{Future, IntoFuture, Poll, Stream}; |
292 | - use http::uri::{Authority, Scheme}; |
293 | + use http::uri::{self, Authority, Scheme, Uri}; |
294 | use hyper::{ |
295 | body::{Payload, Sender}, |
296 | Body as HBody, Chunk, HeaderMap, Request, Response, |
297 | @@ -195,6 +195,16 @@ pub trait RequestExt { |
298 | /// First checks the HTTP/2 header `:authority` and then falls back to the |
299 | /// `Host` header. |
300 | fn authority(&self) -> Option<Authority>; |
301 | + |
302 | + fn base_uri(&self) -> uri::Builder { |
303 | + let mut builder = Uri::builder(); |
304 | + builder.scheme(self.scheme().unwrap_or(Scheme::HTTP)); |
305 | + builder.authority( |
306 | + self.authority() |
307 | + .unwrap_or_else(|| Authority::from_static("localhost")), |
308 | + ); |
309 | + builder |
310 | + } |
311 | } |
312 | |
313 | impl<B> RequestExt for Request<B> { |
314 | diff --git a/templates/base.html b/templates/base.html |
315 | new file mode 100644 |
316 | index 0000000..d00a371 |
317 | --- /dev/null |
318 | +++ b/templates/base.html |
319 | @@ -0,0 +1,118 @@ |
320 | + <!doctype html> |
321 | + <html lang="en"> |
322 | + <head> |
323 | + <meta charset="utf-8"> |
324 | + |
325 | + <title>{{ title }}</title> |
326 | + <meta name="description" content="A git lfs server."> |
327 | + <meta name="author" content="Jason White"> |
328 | + |
329 | + <style> |
330 | + html { |
331 | + font-family: Helvetica, Arial, sans-serif; |
332 | + letter-spacing: 0.01em; |
333 | + } |
334 | + |
335 | + body { |
336 | + line-height: 1.6; |
337 | + color: #777; |
338 | + } |
339 | + |
340 | + h1, h2, h3, h4, h5, h6 { |
341 | + color: #4b4b4b; |
342 | + } |
343 | + |
344 | + a { |
345 | + color: #3b8bba; |
346 | + text-decoration: none; |
347 | + } |
348 | + |
349 | + a:visited { |
350 | + color: #265778; |
351 | + } |
352 | + |
353 | + pre, code { |
354 | + font-family: Consolas, Courier, monospace; |
355 | + color: #333; |
356 | + background: #fafafa; |
357 | + } |
358 | + |
359 | + code { |
360 | + padding: 0.2em 0.4em; |
361 | + white-space: nowrap; |
362 | + } |
363 | + |
364 | + .header .content { |
365 | + padding-left: 2em; |
366 | + padding-right: 2em; |
367 | + } |
368 | + |
369 | + .header { |
370 | + margin: 0 auto; |
371 | + padding: 1em; |
372 | + text-align: center; |
373 | + border-bottom: 1px solid #eee; |
374 | + letter-spacing: 0.05em; |
375 | + max-width: 768px; |
376 | + } |
377 | + |
378 | + .header h1 { |
379 | + font-size: 320%; |
380 | + font-weight: 100; |
381 | + margin: 0; |
382 | + } |
383 | + |
384 | + .header h2 { |
385 | + font-weight: 100; |
386 | + margin: 0; |
387 | + color: #666; |
388 | + letter-spacing: -0.02em; |
389 | + } |
390 | + |
391 | + .content { |
392 | + margin-left: auto; |
393 | + margin-right: auto; |
394 | + max-width: 768px; |
395 | + } |
396 | + |
397 | + .content p { |
398 | + font-size: 1.125em; |
399 | + } |
400 | + |
401 | + .code { |
402 | + margin-left: -1em; |
403 | + margin-right: -1em; |
404 | + padding: 1em; |
405 | + border: 1px solid #eee; |
406 | + border-left-width: 0; |
407 | + border-right-width: 0; |
408 | + overflow-x: auto; |
409 | + -webkit-overflow-scrolling: touch; |
410 | + } |
411 | + |
412 | + @media screen and (min-width: 48em) { |
413 | + .code { |
414 | + margin-left: auto; |
415 | + margin-right: auto; |
416 | + border-left-width: 1px; |
417 | + border-right-width: 1px; |
418 | + } |
419 | + } |
420 | + |
421 | + .content p code { |
422 | + font-size: 90%; |
423 | + } |
424 | + </style> |
425 | + </head> |
426 | + |
427 | + <body> |
428 | + <div id="main"> |
429 | + <div class="header"> |
430 | + {% block header %}{% endblock %} |
431 | + </div> |
432 | + <div class="content"> |
433 | + {% block content %}{% endblock %} |
434 | + </div> |
435 | + </div> |
436 | + </body> |
437 | + </html> |
438 | diff --git a/templates/index.html b/templates/index.html |
439 | new file mode 100644 |
440 | index 0000000..8b59f48 |
441 | --- /dev/null |
442 | +++ b/templates/index.html |
443 | @@ -0,0 +1,26 @@ |
444 | + {% extends "base.html" %} |
445 | + |
446 | + {% block header %} |
447 | + <h1><a href="https://github.com/jasonwhite/rudolfs">{{ title }}</a></h1> |
448 | + <h2>A high-performance, caching <a |
449 | + href="https://git-lfs.github.com">Git LFS</a> server.</h2> |
450 | + {% endblock header %} |
451 | + |
452 | + {% block content %} |
453 | + <p> |
454 | + To use this Git LFS server in your project, add a file named |
455 | + <code>.lfsconfig</code> to the root of your repository with the |
456 | + following contents:</p> |
457 | + <p> |
458 | + <pre class="code">[lfs] |
459 | + url = "{{ api }}/my-org/my-repo"</pre> |
460 | + </p> |
461 | + <p> |
462 | + ...where <code>my-org/my-repo</code> is the name of the Git |
463 | + repository. |
464 | + </p> |
465 | + <p> |
466 | + Please see <a href="https://git-lfs.github.com/">https://git-lfs.github.com/</a> |
467 | + for more information about how to use the Git LFS client. |
468 | + </p> |
469 | + {% endblock content %} |