File tree 4 files changed +68
-0
lines changed
4 files changed +68
-0
lines changed Original file line number Diff line number Diff line change @@ -98,6 +98,16 @@ impl crate::traits::Write for Store {
98
98
99
99
type CompressedTempfile = deflate:: Write < NamedTempFile > ;
100
100
101
+ /// Access
102
+ impl Store {
103
+ /// Return the path to the object with `id`.
104
+ ///
105
+ /// Note that is may not exist yet.
106
+ pub fn object_path ( & self , id : & gix_hash:: oid ) -> PathBuf {
107
+ loose:: hash_path ( id, self . path . clone ( ) )
108
+ }
109
+ }
110
+
101
111
impl Store {
102
112
fn dest ( & self ) -> Result < hash:: Write < CompressedTempfile > , Error > {
103
113
Ok ( hash:: Write :: new (
@@ -137,6 +147,24 @@ impl Store {
137
147
return Ok ( id) ;
138
148
}
139
149
}
150
+ #[ cfg( unix) ]
151
+ if let Ok ( mut perm) = object_path. metadata ( ) . map ( |m| m. permissions ( ) ) {
152
+ use std:: os:: unix:: fs:: PermissionsExt ;
153
+ /// For now we assume the default with standard umask. This can be more sophisticated,
154
+ /// but we have the bare minimum.
155
+ fn comp_mode ( _mode : u32 ) -> u32 {
156
+ 0o444
157
+ }
158
+ let new_mode = comp_mode ( perm. mode ( ) ) ;
159
+ if ( perm. mode ( ) ^ new_mode) & !0o170000 != 0 {
160
+ perm. set_mode ( new_mode) ;
161
+ std:: fs:: set_permissions ( & object_path, perm) . map_err ( |err| Error :: Io {
162
+ source : err,
163
+ message : "Failed to set permission bits" ,
164
+ path : object_path. clone ( ) ,
165
+ } ) ?;
166
+ }
167
+ }
140
168
res. map_err ( |err| Error :: Persist {
141
169
source : err,
142
170
target : object_path,
Original file line number Diff line number Diff line change
1
+ repo_with_loose_objects.tar.xz
Original file line number Diff line number Diff line change
1
+ #! /bin/bash
2
+ set -eu -o pipefail
3
+
4
+ git init -q
5
+
6
+ git checkout -b main
7
+ touch this
8
+ git add this
9
+ git commit -q -m c1
10
+ echo hello >> this
11
+ git commit -q -am c2
12
+
Original file line number Diff line number Diff line change @@ -71,6 +71,33 @@ mod write {
71
71
Ok ( ( ) )
72
72
}
73
73
74
+ #[ test]
75
+ #[ cfg( unix) ]
76
+ fn it_writes_objects_with_similar_permissions ( ) -> crate :: Result {
77
+ let hk = gix_hash:: Kind :: Sha1 ;
78
+ let git_store = loose:: Store :: at (
79
+ gix_testtools:: scripted_fixture_read_only ( "repo_with_loose_objects.sh" ) ?. join ( ".git/objects" ) ,
80
+ hk,
81
+ ) ;
82
+ let expected_perm = git_store
83
+ . object_path ( & gix_hash:: ObjectId :: empty_blob ( hk) )
84
+ . metadata ( ) ?
85
+ . permissions ( ) ;
86
+
87
+ let tmp = tempfile:: TempDir :: new ( ) ?;
88
+ let store = loose:: Store :: at ( tmp. path ( ) , hk) ;
89
+ store. write_buf ( gix_object:: Kind :: Blob , & [ ] ) ?;
90
+ let actual_perm = store
91
+ . object_path ( & gix_hash:: ObjectId :: empty_blob ( hk) )
92
+ . metadata ( ) ?
93
+ . permissions ( ) ;
94
+ assert_eq ! (
95
+ actual_perm, expected_perm,
96
+ "we explicitly equalize permissions to be similar to what `git` would do"
97
+ ) ;
98
+ Ok ( ( ) )
99
+ }
100
+
74
101
#[ test]
75
102
fn collisions_do_not_cause_failure ( ) -> crate :: Result {
76
103
let dir = tempfile:: tempdir ( ) ?;
You can’t perform that action at this time.
0 commit comments