vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
| 1 | package lfs |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "fmt" |
| 6 | "net/http" |
| 7 | ) |
| 8 | |
| 9 | // The JSON bodies of POST .../info/lfs/objects/batch. Only the fields Vole |
| 10 | // reads or writes are modelled; git-lfs sends more (transfers, ref, hash_algo) |
| 11 | // and ignores unknown keys in the response. |
| 12 | |
| 13 | type BatchRequest struct { |
| 14 | Operation string `json:"operation"` |
| 15 | Transfers []string `json:"transfers,omitempty"` |
| 16 | HashAlgo string `json:"hash_algo,omitempty"` |
| 17 | Objects []Object `json:"objects"` |
| 18 | } |
| 19 | |
| 20 | type Object struct { |
| 21 | OID string `json:"oid"` |
| 22 | Size int64 `json:"size"` |
| 23 | } |
| 24 | |
| 25 | type BatchResponse struct { |
| 26 | Transfer string `json:"transfer,omitempty"` |
| 27 | HashAlgo string `json:"hash_algo,omitempty"` |
| 28 | Objects []ObjectResponse `json:"objects"` |
| 29 | } |
| 30 | |
| 31 | type ObjectResponse struct { |
| 32 | OID string `json:"oid"` |
| 33 | Size int64 `json:"size"` |
| 34 | Actions map[string]Action `json:"actions,omitempty"` |
| 35 | Error *ObjectError `json:"error,omitempty"` |
| 36 | } |
| 37 | |
| 38 | type Action struct { |
| 39 | Href string `json:"href"` |
| 40 | Header map[string]string `json:"header,omitempty"` |
| 41 | ExpiresIn int `json:"expires_in,omitempty"` |
| 42 | } |
| 43 | |
| 44 | type ObjectError struct { |
| 45 | Code int `json:"code"` |
| 46 | Message string `json:"message"` |
| 47 | } |
| 48 | |
| 49 | // ErrorBody is the top-level error git-lfs shows the user. |
| 50 | type ErrorBody struct { |
| 51 | Message string `json:"message"` |
| 52 | } |
| 53 | |
| 54 | // WriteError replies with the media type git-lfs expects, so the reason reaches |
| 55 | // the user instead of "unexpected content type". |
| 56 | func WriteError(w http.ResponseWriter, status int, format string, args ...any) { |
| 57 | w.Header().Set("Content-Type", MediaType) |
| 58 | w.WriteHeader(status) |
| 59 | json.NewEncoder(w).Encode(ErrorBody{Message: fmt.Sprintf(format, args...)}) |
| 60 | } |
| 61 |