fix update-maintenance-badge goal
[storage-units.git] / README.asciidoc
blobf685c6ce4463b2552a0e6eb68ea0eca5bc481536
1 = Storage-Units image:https://img.shields.io/badge/email-%40metio-brightgreen.svg?style=social&label=mail["Discuss on Google Groups", link="https://groups.google.com/forum/#!forum/metio"] image:https://img.shields.io/badge/irc-%23metio.wtf-brightgreen.svg?style=social&label=IRC["Chat on IRC", link="http://webchat.freenode.net/?channels=metio.wtf"]
2 Sebastian Hoß <http://seb.xn--ho-hia.de/[@sebhoss]>
3 :github-org: sebhoss
4 :project-name: storage-units
5 :project-group: de.xn--ho-hia.storage_units
6 :coverity-project: 2658
7 :codacy-project: d3cfbbc415c14b79a661d573ac11e68c
8 :toc:
9 :toc-placement: preamble
11 image:https://img.shields.io/badge/license-cc%20zero-000000.svg?style=flat-square["CC Zero", link="http://creativecommons.org/publicdomain/zero/1.0/"]
12 pass:[<span class="image"><a class="image" href="https://maven-badges.herokuapp.com/maven-central/de.xn--ho-hia.storage_units/storage-units"><img src="https://img.shields.io/maven-central/v/de.xn--ho-hia.storage_units/storage-units.svg?style=flat-square" alt="Maven Central"></a></span>]
13 pass:[<span class="image"><a class="image" href="https://www.javadoc.io/doc/de.xn--ho-hia.storage_units/storage-units"><img src="https://www.javadoc.io/badge/de.xn--ho-hia.storage_units/storage-units.svg?style=flat-square&color=blue" alt="Read JavaDocs"></a></span>]
14 image:https://reposs.herokuapp.com/?path={github-org}/{project-name}&style=flat-square["Repository size"]
15 image:https://www.openhub.net/p/{project-name}/widgets/project_thin_badge.gif["Open Hub statistics", link="https://www.openhub.net/p/{project-name}"]
17 image:https://img.shields.io/travis/{github-org}/{project-name}/master.svg?style=flat-square["Build Status", link="https://travis-ci.org/{github-org}/{project-name}"]
18 image:https://img.shields.io/coveralls/{github-org}/{project-name}/master.svg?style=flat-square["Code Coverage", link="https://coveralls.io/github/{github-org}/{project-name}"]
19 image:https://img.shields.io/coverity/scan/{coverity-project}.svg?style=flat-square["Coverity Scan Result", link="https://scan.coverity.com/projects/{github-org}-{project-name}"]
20 image:https://img.shields.io/codacy/grade/{codacy-project}.svg?style=flat-square["Codacy Code Quality", link="https://www.codacy.com/app/mail_7/{project-name}"]
21 image:https://img.shields.io/badge/forkable-yes-brightgreen.svg?style=flat-square["Can this project be forked?", link="https://basicallydan.github.io/forkability/?u={github-org}&r={project-name}"]
22 image:https://img.shields.io/maintenance/yes/2016.svg?style=flat-square["Is this thing still maintained?"]
23 image:https://img.shields.io/bountysource/team/metio/activity.svg?style=flat-square["Bounties on open tickets", link="https://www.bountysource.com/teams/metio"]
25 https://www.java.com[Java] library for storage-/byte-units. All units defined in link:http://en.wikipedia.org/wiki/ISO/IEC_80000[ISO IEC 80000-13:2008] are supported, as well as other commonly found units, like 1 Kilobyte = 1024 Byte.
27 === Features
29 * Immutable, type- and thread-safe object model for storage units
30 * Convenience factories to create units
31 * Basic arithmetic operators
32 * Comparisons and equality checks between units
33 * Lossless conversion between all units
34 * Human readable text format, including custom formats
35 * Compatible with any `java.lang.Number`
36 * Custom serializers for Jackson, MongoDB & EclipseLink
38 ==== Available Units
40 .Binary units
41 |===
42 | Name | Symbol | Exponential | Absolute | Class
44 | Byte
45 | B
46 | 2 ^0^ Byte
47 | 1 Byte
48 | `Byte`
50 | Kibibyte
51 | KiB
52 | 2 ^10^ Byte
53 | 1 024 Byte
54 | `Kibibyte`
56 | Mebibyte
57 | MiB
58 | 2 ^20^ Byte
59 | 1 048 576 Byte
60 | `Mebibyte`
62 | Gibibyte
63 | GiB
64 | 2 ^30^ Byte
65 | 1 073 741 824 Byte
66 | `Gibibyte`
68 | Tebibyte
69 | TiB
70 | 2 ^40^ Byte
71 | 1 099 511 627 776 Byte
72 | `Tebibyte`
74 | Pebibyte
75 | PiB
76 | 2 ^50^ Byte
77 | 1 125 899 906 842 624 Byte
78 | `Pebibyte`
80 | Exbibyte
81 | EiB
82 | 2 ^60^ Byte
83 | 1 152 921 504 606 846 976 Byte
84 | `Exbibyte`
86 | Zebibyte
87 | ZiB
88 | 2 ^70^ Byte
89 | 1 180 591 620 717 411 303 424 Byte
90 | `Zebibyte`
92 | Yobibyte
93 | YiB
94 | 2 ^80^ Byte
95 | 1 208 925 819 614 629 174 706 176 Byte
96 | `Yobibyte`
97 |===
99 .Decimal units
100 |===
101 | Name | Symbol | Exponential | Absolute | Class
103 | Byte
104 | kB
105 | 10 ^0^ Byte
106 | 1 Byte
107 | `Byte`
109 | Kilobyte
110 | kB
111 | 10 ^3^ Byte
112 | 1 000 Byte
113 | `Kilobyte`
115 | Megabyte
116 | MB
117 | 10 ^6^ Byte
118 | 1 000 000 Byte
119 | `Megabyte`
121 | Gigabyte
122 | GB
123 | 10 ^9^ Byte
124 | 1 000 000 000 Byte
125 | `Gigabyte`
127 | Terabyte
128 | TB
129 | 10 ^12^ Byte
130 | 1 000 000 000 000 Byte
131 | `Terabyte`
133 | Petabyte
134 | PB
135 | 10 ^15^ Byte
136 | 1 000 000 000 000 000 Byte
137 | `Petabyte`
139 | Exabyte
140 | EB
141 | 10 ^18^ Byte
142 | 1 000 000 000 000 000 000 Byte
143 | `Exabyte`
145 | Zettabyte
146 | ZB
147 | 10 ^21^ Byte
148 | 1 000 000 000 000 000 000 000 Byte
149 | `Zettabyte`
151 | Yottabyte
152 | YB
153 | 10 ^24^ Byte
154 | 1 000 000 000 000 000 000 000 000 Byte
155 | `Yottabyte`
156 |===
158 .Common units
159 |===
160 | Name | Symbol | Exponential | Absolute | Class
162 | Byte
163 | kB
164 | 2 ^0^ Byte
165 | 1 Byte
166 | `Byte`
168 | Kilobyte
169 | kB
170 | 2 ^10^ Byte
171 | 1 024 Byte
172 | `CommonKilobyte`
174 | Megabyte
175 | MB
176 | 2 ^20^ Byte
177 | 1 048 576 Byte
178 | `CommonMegabyte`
180 | Gigabyte
181 | GB
182 | 2 ^30^ Byte
183 | 1 073 741 824 Byte
184 | `CommonGigabyte`
186 | Terabyte
187 | TB
188 | 2 ^40^ Byte
189 | 1 099 511 627 776 Byte
190 | `CommonTerabyte`
192 | Petabyte
193 | PB
194 | 2 ^50^ Byte
195 | 1 125 899 906 842 624 Byte
196 | `CommonPetabyte`
198 | Exabyte
199 | EB
200 | 2 ^60^ Byte
201 | 1 152 921 504 606 846 976 Byte
202 | `CommonExabyte`
204 | Zettabyte
205 | ZB
206 | 2 ^70^ Byte
207 | 1 180 591 620 717 411 303 424 Byte
208 | `CommonZettabyte`
210 | Yottabyte
211 | YB
212 | 2 ^80^ Byte
213 | 1 208 925 819 614 629 174 706 176 Byte
214 | `CommonYottabyte`
215 |===
217 === Development Status
219 All units are implemented. For future ideas, take a look at the link:https://github.com/sebhoss/storage-units/issues[open tickets] in case you are interested.
222 == Usage
224 === Factories
226 Each unit implements a Byte-based static factory method (`valueOf(BigInteger)` or `valueOf(long)`) that can be used to represent a given number of bytes in a specific unit. Note that `Long.MAX_VALUE == 8 Exabyte`, thus use `BigInteger` if you want to work with anything bigger than a eight Exabyte. When in doubt, always use `BigInteger`.
228 [source,java]
229 ----
230 // 'long' based
231 Kilobyte unit = Kilobyte.valueOf(500)               // 500 Byte or "0.50 kB"
232 Kibibyte unit = Kibibyte.valueOf(512)               // 512 Byte or "0.50 KiB"
233 CommonKilobyte unit = CommonKilobyte.valueOf(512)   // 512 Byte or "0.50 kB"
235 Megabyte unit = Megabyte.valueOf(1_000_000)             // 1 000 000 Byte or "1.00 MB"
236 Mebibyte unit = Mebibyte.valueOf(1_048_576)             // 1 048 576 Byte or "1.00 MiB"
237 CommonMegabyte unit = CommonMegabyte.valueOf(1_048_576) // 1 048 576 Byte or "1.00 MB"
239 // 'BigInteger' based
240 Kilobyte unit = Kilobyte.valueOf(BigInteger.valueOf(500))               // 500 Byte or "0.50 kB"
241 Kibibyte unit = Kibibyte.valueOf(BigInteger.valueOf(512))               // 512 Byte or "0.50 KiB"
242 CommonKilobyte unit = CommonKilobyte.valueOf(BigInteger.valueOf(512))   // 512 Byte or "0.50 KB"
244 Megabyte unit = Megabyte.valueOf(BigInteger.valueOf(1000000))               // 1 000 000 Byte or "1.00 MB"
245 Mebibyte unit = Mebibyte.valueOf(BigInteger.valueOf(1_048_576))             // 1 048 576 Byte or "1.00 MB"
246 CommonMegabyte unit = CommonMegabyte.valueOf(BigInteger.valueOf(1_048_576)) // 1 048 576 Byte or "1.00 MB"
247 ----
249 The `StorageUnits` class offers three factory methods that automatically pick the best-matching unit for a given number of bytes.
251 ==== Binary Units
253 [source,java]
254 ----
255 // 'long' based
256 StorageUnit<?> unit = StorageUnits.binaryValueOf(256)       // Kibibyte (0.25 KiB)
257 StorageUnit<?> unit = StorageUnits.binaryValueOf(1048576)   // Mebibyte (1.00 MiB)
259 // 'BigInteger' based
260 StorageUnit<?> unit = StorageUnits.binaryValueOf(BigInteger.valueOf(256))     // Kibibyte (0.25 MiB)
261 StorageUnit<?> unit = StorageUnits.binaryValueOf(BigInteger.valueOf(1048576)) // Mebibyte (1.00 MiB)
262 ----
264 ==== Decimal Units
266 [source,java]
267 ----
268 // 'long' based
269 StorageUnit<?> unit = StorageUnits.decimalValueOf(120000)    // Kilobyte (120.00 kB)
270 StorageUnit<?> unit = StorageUnits.decimalValueOf(1000000)   // Megabyte (1.00 MB)
272 // 'BigInteger' based
273 StorageUnit<?> unit = StorageUnits.decimalValueOf(BigInteger.valueOf(120000))    // Kilobyte (120.00 kB)
274 StorageUnit<?> unit = StorageUnits.decimalValueOf(BigInteger.valueOf(1000000))   // Megabyte (1.00 MB)
275 ----
277 ==== Common Units
279 [source,java]
280 ----
281 // 'long' based
282 StorageUnit<?> unit = StorageUnits.commonValueOf(256)       // CommonKilobyte (0.25 kB)
283 StorageUnit<?> unit = StorageUnits.commonValueOf(1048576)   // CommonMebibyte (1.00 MB)
285 // 'BigInteger' based
286 StorageUnit<?> unit = StorageUnits.commonValueOf(BigInteger.valueOf(256))     // CommonKilobyte (0.25 kB)
287 StorageUnit<?> unit = StorageUnits.commonValueOf(BigInteger.valueOf(1048576)) // CommonMebibyte (1.00 MB)
288 ----
290 Additionally high-level factory methods are also available in the `StorageUnits` class.
292 [source,java]
293 ----
294 import static de.xn__ho_hia.storage_unit.StorageUnits.*;
296 Kibibyte unit = kibibyte(1)   // 1 024 Byte
297 Mebibyte unit = mebibyte(1)   // 1 048 576 Byte
298 Gibibyte unit = gibibyte(1)   // 1 073 741 824 Byte
299 Tebibyte unit = tebibyte(1)   // 1 099 511 627 776 Byte
300 Pebibyte unit = pebibyte(1)   // 1 125 899 906 842 624 Byte
301 Exbibyte unit = exbibyte(1)   // 1 152 921 504 606 846 976 Byte
302 Zebibyte unit = zebibyte(1)   // 1 180 591 620 717 411 303 424 Byte
303 Yobibyte unit = yobibyte(1)   // 1 208 925 819 614 629 174 706 176 Byte
305 Kilobyte unit = kilobyte(1)   // 1 000 Byte
306 Megabyte unit = megabyte(1)   // 1 000 000 Byte
307 Gigabyte unit = gigabyte(1)   // 1 000 000 000 Byte
308 Terabyte unit = terabyte(1)   // 1 000 000 000 000 Byte
309 Petabyte unit = petabyte(1)   // 1 000 000 000 000 000 Byte
310 Exabyte unit = exabyte(1)     // 1 000 000 000 000 000 000 Byte
311 Zettabyte unit = zettabyte(1) // 1 000 000 000 000 000 000 000 Byte
312 Yottabyte unit = yottabyte(1) // 1 000 000 000 000 000 000 000 000 Byte
314 CommonKilobyte unit = commonKilobyte(1)   // 1 024 Byte
315 CommonMegabyte unit = commonMegabyte(1)   // 1 048 576 Byte
316 CommonGigabyte unit = commonGigabyte(1)   // 1 073 741 824 Byte
317 CommonTerabyte unit = commonTerabyte(1)   // 1 099 511 627 776 Byte
318 CommonPetabyte unit = commonPetabyte(1)   // 1 125 899 906 842 624 Byte
319 CommonExabyte unit = commonExabyte(1)     // 1 152 921 504 606 846 976 Byte
320 CommonZettabyte unit = commonZettabyte(1) // 1 180 591 620 717 411 303 424 Byte
321 CommonYottabyte unit = commonYottabyte(1) // 1 208 925 819 614 629 174 706 176 Byte
322 ----
324 === Add, Subtract, Multiply, Divide
326 Each unit implements the basic four math operations. All operations retain their original type, e.g. `[Kilobyte] + [Megabyte] = [Kilobyte]`
328 [source,java]
329 ----
330 import static de.xn__ho_hia.storage_unit.StorageUnits.*;
332 kilobyte(4).add(kilobyte(8))        // 4 Kilobyte + 8 Kilobyte = 12 Kilobyte = 12 000 Byte
333 kibibyte(1).add(1024)               // 1 Kibibyte + 1 024 Byte = 2 Kibibyte = 2 048 Byte
334 kibibyte(1).subtract(24)            // 1 024 Byte - 24 Byte = 1 000 Byte
335 megabyte(5).subtract(kilobyte(500)) // 5 Megabyte - 500 Kilobyte = 4.5 Megabyte = 4 500 Kilobyte = 4 500 000 Byte
336 gigabyte(1).multiply(5)             // 1 Gigabyte times 5 = 5 Gigabyte
337 terabyte(1).divide(5)               // 1 Terabyte divided by 5 = 0.2 Terabyte = 200 Gigabyte
338 ----
340 === Comparison & Equality
342 Each unit is comparable to each other unit.
344 [source,java]
345 ----
346 import static de.xn__ho_hia.storage_unit.StorageUnits.*;
348 kibibyte(1024).compareTo(mebibyte(1)) == 0 // true
349 kibibyte(1000).compareTo(mebibyte(1)) == 0 // false
350 petabyte(3).compareTo(terabyte(3000)) == 0 // true
352 megabyte(1000).equals(gigabyte(1))         // true
353 megabyte(1024).equals(gigabyte(1))         // false
354 terabyte(12).equals(gigabyte(12000))       // true
355 ----
357 === Formatting
359 Each unit prints a human-readable string, representing the amount of bytes in the given unit using the symbol specified in ISO IEC 80000-13:2008.
361 [source,java]
362 ----
363 import static de.xn__ho_hia.storage_unit.StorageUnits.*;
365 // default pattern '0.00'
366 terabyte(2).toString()                         // "2.00 TB"
367 gigabyte(1).add(megabyte(200)).toString()      // "1.20 GB"
368 petabyte(1).subtract(terabyte(250)).toString() // "0.75 PB"
370 // use custom pattern
371 kilobyte(212345).toString("0.0")                                    // "212345.0 kB"
372 gibibyte(2123458).asTebibyte().toString("#,###.000")                // "2,073.689 TiB"
373 kilobyte(120).asMegabyte().add(gigabyte(1)).toString("#,##0.00000") // "1,000.12000 MB"
375 // use custom pattern with specific Locale
376 kilobyte(212345).toString("0.0", Locale.GERMAN)                     // "212345,0 kB"
377 gibibyte(2123458).asTebibyte().toString("#,###.000", Locale.GERMAN) // "2.073,689 TiB"
379 // use custom format
380 Format customFormat = new DecimalFormat("#.00000");
381 terabyte(4).asTebibyte().toString(customFormat) // "3.63798 TiB"
383 // without creating unit type first
384 long numberOfBytes = 1_000_000_000_000_000L;
385 formatAsPetabyte(numberOfBytes) // "1.00 PB"
386 formatAsTerabyte(numberOfBytes) // "1000.00 TB"
387 formatAsPebibyte(numberOfBytes) // "0.89 PiB"
389 // use custom pattern
390 formatAsTerabyte(numberOfBytes, "#0.#####") // "1000 TB"
391 formatAsPebibyte(numberOfBytes, "#0.#####") // "0.88818 PiB"
393 // use custom pattern with specific Locale
394 formatAsTerabyte(numberOfBytes, "#0.#####", Locale.GERMAN) // "1000 TB"
395 formatAsPebibyte(numberOfBytes, "#0.#####", Locale.GERMAN) // "0,88818 PiB"
397 // use custom format
398 formatAsTerabyte(numberOfBytes, customFormat) // "1000.00000 TB"
399 formatAsPebibyte(numberOfBytes, customFormat) // ".88818 PiB"
400 ----
402 === Conversions
404 Each unit can be converted to each other unit without loss of information.
406 [source,java]
407 ----
408 import static de.xn__ho_hia.storage_unit.StorageUnits.*;
410 Megabyte unit = kilobyte(1000).asMegabyte() // "1.00 MB"
411 Kilobyte unit = gigabyte(12).asKilobyte()   // "12000000.00 kB"
412 Gigabyte unit = terabyte(1).asGigabyte()    // "1000.00 GB"
414 // convert to best-match
415 kilobyte(1100).asBestMatchingUnit()          // "1.10 MB"
416 kilobyte(1100).asBestMatchingBinaryUnit()    // "1.05 MiB"
417 kilobyte(1100).asBestMatchingDecimalUnit()   // "1.10 MB"
418 kilobyte(1100).asBestMatchingCommonUnit()    // "1.05 MB"
419 ----
421 Each unit can be expressed as a fraction of another unit (precise up to 24 decimal places) 
423 [source,java]
424 ----
425 import static de.xn__ho_hia.storage_unit.StorageUnits.*;
427 BigDecimal kilobytes = megabyte(1).inKilobyte()  // 1 000
428 BigInteger bytes = kibibyte(2).inByte()          // 2 048
429 BigDecimal terabytes = gigabyte(15).inTerabyte() // 0.015
430 ----
432 === Serialization
434 The storage-units-(eclipselink|mongodb|jackson) modules provide custom serializers to store storage units.
436 ==== EclipseLink
438 Use any of the three converters like this:
440 [source, java]
441 ----
442 @Entity
443 public class HardDisk implements Serializable {
445     @Basic
446     @Converter (
447         name="binaryConverter",
448         converterClass=de.xn__ho_hia.storage_unit.eclipselink.BinaryStorageUnitConverter.class
449     )
450     @Convert("binaryConverter")
451     public StorageUnit<?> getFreeSize() {
452         return freeSize;
453     }
455     @Basic
456     @Converter (
457         name="commonConverter",
458         converterClass=de.xn__ho_hia.storage_unit.eclipselink.CommonStorageUnitConverter.class
459     )
460     @Convert("commonConverter")
461     public StorageUnit<?> getUsedSize() {
462         return usedSize;
463     }
465     @Basic
466     @Converter (
467         name="decimalConverter",
468         converterClass=de.xn__ho_hia.storage_unit.eclipselink.DecimalyStorageUnitConverter.class
469     )
470     @Convert("decimalConverter")
471     public StorageUnit<?> getTotalSize() {
472         return totalSize;
473     }
476 ----
478 ==== MongoDB
480 Use any of the three codecs like this:
482 [source, java]
483 ----
484 CodecRegistry binaryRegistry = CodecRegistries.fromCodecs(new BinaryStorageUnitCodec(), ...);
485 CodecRegistry commonRegistry = CodecRegistries.fromCodecs(new CommonStorageUnitCodec(), ...);
486 CodecRegistry decimalRegistry = CodecRegistries.fromCodecs(new DecimalStorageUnitCodec(), ...);
487 ----
489 ==== Jackson
491 Use the provided `StorageUnitModule` like this:
493 [source, java]
494 ----
495 ObjectMapper objectMapper = new ObjectMapper();
496 objectMapper.registerModule(new StorageUnitModule()); // defaults to binary units
497 objectMapper.registerModule(new StorageUnitModule(StorageUnitModule.PreferredUnitType.BINARY));
498 objectMapper.registerModule(new StorageUnitModule(StorageUnitModule.PreferredUnitType.COMMON));
499 objectMapper.registerModule(new StorageUnitModule(StorageUnitModule.PreferredUnitType.DECIMAL));
500 ----
502 === Integration
504 To use this project just declare the following dependency inside your POM:
506 [source,xml,subs="attributes,verbatim"]
507 ----
508 <dependencies>
509   <dependency>
510     <groupId>{project-group}</groupId>
511     <artifactId>storage-units</artifactId>
512     <version>${version.storage-units}</version>
513   </dependency>
515   <!-- EclipseLink ONLY -->
516   <dependency>
517     <groupId>{project-group}</groupId>
518     <artifactId>storage-units-eclipselink</artifactId>
519     <version>${version.storage-units}</version>
520   </dependency>
521   <!-- EclipseLink ONLY -->
523   <!-- MongoDB ONLY -->
524   <dependency>
525     <groupId>{project-group}</groupId>
526     <artifactId>storage-units-mongodb</artifactId>
527     <version>${version.storage-units}</version>
528   </dependency>
529   <!-- MongoDB ONLY -->
531   <!-- Jackson ONLY -->
532   <dependency>
533     <groupId>{project-group}</groupId>
534     <artifactId>storage-units-jackson</artifactId>
535     <version>${version.storage-units}</version>
536   </dependency>
537   <!-- Jackson ONLY -->
538 </dependencies>
539 ----
541 Replace `${version.storage-units}` with the link:++http://search.maven.org/#search%7Cga%7C1%7Cg%3Ade.xn--ho-hia.storage_units++[latest release]. This project follows the link:http://semver.org/[semantic versioning guidelines].
543 === Compatibility
545 This project is compatible with the following Java versions:
547 .Java compatibility
548 |===
549 | | 1.X.Y | 2.X.Y | 3.X.Y | 4.X.Y
551 | Java 8
552 | ✓
553 | ✓
554 | ✓
555 | ✓
557 | Java 7
558 | ✓
562 |===
564 == Reference
566 Originally inspired by link:https://github.com/twitter/util#space[Twitters util] package.
568 == Alternatives
570 * link:https://github.com/JakeWharton/byteunits[Byte Units]
571 * link:https://github.com/trivago/triava[triava]
573 == License
575 To the extent possible under law, the author(s) have dedicated all copyright
576 and related and neighboring rights to this software to the public domain
577 worldwide. This software is distributed without any warranty.
579 You should have received a copy of the CC0 Public Domain Dedication along
580 with this software. If not, see http://creativecommons.org/publicdomain/zero/1.0/.
582 == Mirrors
584 * https://github.com/sebhoss/{project-name}
585 * https://bitbucket.org/sebhoss/{project-name}
586 * https://gitlab.com/sebastian.hoss/{project-name}
587 * http://v2.pikacode.com/sebhoss/{project-name}
588 * http://repo.or.cz/{project-name}.git