Signed by hanna SSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
assets/base.css +15 −0 crates/git/src/attributes.rs +6 −0 crates/git/src/repo.rs +26 −7 crates/web/src/repo.rs +16 −5 assets/base.css +15 −0 Expand 2267 hidden lines 2268 2268 border-top : none ; 2269 2269 border-radius : 0 0 var ( --fb-radius ) var ( --fb-radius ) ; 2270 2270 } 2271 + 2272 + 2273 + . blob-image { 2274 + background : var ( --fb-bg-inset ) ; 2275 + border : 1px solid var ( --fb-border ) ; 2276 + border-top : none ; 2277 + border-radius : 0 0 var ( --fb-radius ) var ( --fb-radius ) ; 2278 + overflow : hidden ; 2279 + line-height : 0 ; 2280 + } 2281 + . blob-image img { 2282 + display : block ; 2283 + max-width : 100% ; 2284 + margin : 0 auto ; 2285 + } 2271 2286 2272 2287 2273 2288 . blob-code {
crates/git/src/attributes.rs +6 −0 Expand 118 hidden lines 119 119 pub fn is_vendored ( & self ) -> bool { 120 120 self . is_set ( "linguist-vendored" ) 121 121 } 122 + 123 + 124 + # [ must_use ] 125 + pub fn is_lfs ( & self ) -> bool { 126 + matches ! ( self . map. get ( "filter" ) , Some ( AttrValue :: Value ( v) ) if v == "lfs" ) 127 + } 122 128 } 123 129 124 130
crates/git/src/repo.rs +26 −7 Expand 170 hidden lines 171 171 . map ( |b| parse_gitmodules ( b. content ( ) ) ) 172 172 . unwrap_or_default ( ) ; 173 173 174 + 175 + 176 + let attrs = self . attributes_set ( & rev. oid) . ok ( ) ; 177 + let dir_prefix = path_string ( path) ; 178 + 174 179 let tree = if path. components ( ) . next ( ) . is_none ( ) { 175 180 Some ( root) 176 181 } else { Expand 5 hidden lines 182 187 let mut lfs = std:: collections:: HashSet :: new ( ) ; 183 188 if let Some ( tree) = tree { 184 189 for entry in & tree { 185 - if entry. kind ( ) == Some ( git2:: ObjectType :: Blob ) 186 - && let Ok ( obj) = entry. to_object ( & self . inner) 187 - && let Some ( blob) = obj. as_blob ( ) 188 - && blob. size ( ) < POINTER_MAX 189 - && is_lfs_pointer ( blob. content ( ) ) 190 - && let Some ( name) = entry. name ( ) 191 - { 190 + let Some ( name) = entry. name ( ) else { continue } ; 191 + if entry. kind ( ) != Some ( git2:: ObjectType :: Blob ) { 192 + continue ; 193 + } 194 + let full = if dir_prefix. is_empty ( ) { 195 + name. to_string ( ) 196 + } else { 197 + format ! ( "{dir_prefix}/{name}" ) 198 + } ; 199 + let tracked = attrs 200 + . as_ref ( ) 201 + . is_some_and ( |set| set. attributes ( & full) . is_lfs ( ) ) ; 202 + let pointer = entry 203 + . to_object ( & self . inner) 204 + . ok ( ) 205 + . and_then ( |o| { 206 + o. as_blob ( ) 207 + . map ( |b| b. size ( ) < POINTER_MAX && is_lfs_pointer ( b. content ( ) ) ) 208 + } ) 209 + . unwrap_or ( false ) ; 210 + if tracked || pointer { 192 211 lfs. insert ( name. to_string ( ) ) ; 193 212 } 194 213 }
crates/web/src/repo.rs +16 −5 Expand 690 hidden lines 691 691 } ) 692 692 . await ?; 693 693 694 - 695 - let ( blob, attr_lang) = git_read ( state, & ctx. repo. id, { 694 + 695 + let ( blob, attr_lang, is_lfs) = git_read ( state, & ctx. repo. id, { 696 696 let rev = rev. clone ( ) ; 697 697 let path = path. clone ( ) ; 698 698 move |repo| { 699 699 let blob = repo. blob ( & rev, FsPath :: new ( & path) ) ?; 700 700 let attrs = repo. attributes_set ( & rev. oid) . ok ( ) ; 701 - let lang = attrs. and_then ( |set| set. attributes ( & path) . language ( ) . map ( str:: to_string) ) ; 702 - Ok ( ( blob, lang) ) 701 + let resolved = attrs. map ( |set| set. attributes ( & path) ) ; 702 + let lang = resolved 703 + . as_ref ( ) 704 + . and_then ( |a| a. language ( ) . map ( str:: to_string) ) ; 705 + let is_lfs = resolved. as_ref ( ) . is_some_and ( git:: Attributes :: is_lfs) 706 + || ( blob. size < 1024 707 + && blob 708 + . content 709 + . starts_with ( b"version https://git-lfs.github.com/spec/v1" ) ) ; 710 + Ok ( ( blob, lang, is_lfs) ) 703 711 } 704 712 } ) 705 713 . await ?; Expand 4 hidden lines 710 718 & path, 711 719 & blob, 712 720 attr_lang. as_deref ( ) , 721 + is_lfs, 713 722 source_view, 714 723 ) ; 715 724 Expand 62 hidden lines 778 787 path : & str , 779 788 blob : & git:: Blob , 780 789 attr_lang : Option < & str > , 790 + is_lfs : bool , 781 791 source_view : bool , 782 792 ) -> Markup { 783 793 let base = format ! ( "/{}/{}" , ctx. owner. username, ctx. repo. path) ; Expand 6 hidden lines 790 800 html ! { 791 801 div class="blob-header" { 792 802 span class="muted" { ( blob. size) " bytes" } 803 + @if is_lfs { span class="badge lfs-pill" { "LFS" } } 793 804 div class="blob-actions" { 794 805 @if previewable { 795 806 a class=( toggle_class ( show_preview) ) href=( blob_url. clone ( ) ) { "Preview" } Expand 6 hidden lines 802 813 } 803 814 } 804 815 @if is_image ( filename) { 805 - p { img src=( raw_url) alt=( filename) style="max-width:100%" ; } 816 + div class="blob-image" { img src=( raw_url) alt=( filename) ; } 806 817 } @else if blob. is_binary { 807 818 div class="card" { 808 819 p class="muted" { "Binary file not shown." }