@@ -115,6 +115,33 @@ static void git_hash_sha1_final_oid(struct object_id *oid, git_hash_ctx *ctx)
115115 oid -> algo = GIT_HASH_SHA1 ;
116116}
117117
118+ static void git_hash_sha1_init_fast (git_hash_ctx * ctx )
119+ {
120+ git_SHA1_Init_fast (& ctx -> sha1_fast );
121+ }
122+
123+ static void git_hash_sha1_clone_fast (git_hash_ctx * dst , const git_hash_ctx * src )
124+ {
125+ git_SHA1_Clone_fast (& dst -> sha1_fast , & src -> sha1_fast );
126+ }
127+
128+ static void git_hash_sha1_update_fast (git_hash_ctx * ctx , const void * data ,
129+ size_t len )
130+ {
131+ git_SHA1_Update_fast (& ctx -> sha1_fast , data , len );
132+ }
133+
134+ static void git_hash_sha1_final_fast (unsigned char * hash , git_hash_ctx * ctx )
135+ {
136+ git_SHA1_Final_fast (hash , & ctx -> sha1_fast );
137+ }
138+
139+ static void git_hash_sha1_final_oid_fast (struct object_id * oid , git_hash_ctx * ctx )
140+ {
141+ git_SHA1_Final_fast (oid -> hash , & ctx -> sha1_fast );
142+ memset (oid -> hash + GIT_SHA1_RAWSZ , 0 , GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ );
143+ oid -> algo = GIT_HASH_SHA1 ;
144+ }
118145
119146static void git_hash_sha256_init (git_hash_ctx * ctx )
120147{
@@ -189,6 +216,11 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
189216 .update_fn = git_hash_unknown_update ,
190217 .final_fn = git_hash_unknown_final ,
191218 .final_oid_fn = git_hash_unknown_final_oid ,
219+ .fast_init_fn = git_hash_unknown_init ,
220+ .fast_clone_fn = git_hash_unknown_clone ,
221+ .fast_update_fn = git_hash_unknown_update ,
222+ .fast_final_fn = git_hash_unknown_final ,
223+ .fast_final_oid_fn = git_hash_unknown_final_oid ,
192224 .empty_tree = NULL ,
193225 .empty_blob = NULL ,
194226 .null_oid = NULL ,
@@ -204,6 +236,11 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
204236 .update_fn = git_hash_sha1_update ,
205237 .final_fn = git_hash_sha1_final ,
206238 .final_oid_fn = git_hash_sha1_final_oid ,
239+ .fast_init_fn = git_hash_sha1_init_fast ,
240+ .fast_clone_fn = git_hash_sha1_clone_fast ,
241+ .fast_update_fn = git_hash_sha1_update_fast ,
242+ .fast_final_fn = git_hash_sha1_final_fast ,
243+ .fast_final_oid_fn = git_hash_sha1_final_oid_fast ,
207244 .empty_tree = & empty_tree_oid ,
208245 .empty_blob = & empty_blob_oid ,
209246 .null_oid = & null_oid_sha1 ,
@@ -219,6 +256,11 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
219256 .update_fn = git_hash_sha256_update ,
220257 .final_fn = git_hash_sha256_final ,
221258 .final_oid_fn = git_hash_sha256_final_oid ,
259+ .fast_init_fn = git_hash_sha256_init ,
260+ .fast_clone_fn = git_hash_sha256_clone ,
261+ .fast_update_fn = git_hash_sha256_update ,
262+ .fast_final_fn = git_hash_sha256_final ,
263+ .fast_final_oid_fn = git_hash_sha256_final_oid ,
222264 .empty_tree = & empty_tree_oid_sha256 ,
223265 .empty_blob = & empty_blob_oid_sha256 ,
224266 .null_oid = & null_oid_sha256 ,
@@ -1944,17 +1986,71 @@ static void write_object_file_prepare_literally(const struct git_hash_algo *algo
19441986 hash_object_body (algo , & c , buf , len , oid , hdr , hdrlen );
19451987}
19461988
1989+ static int check_collision (const char * filename_a , const char * filename_b )
1990+ {
1991+ char buf_a [4096 ], buf_b [4096 ];
1992+ int fd_a = -1 , fd_b = -1 ;
1993+ int ret = 0 ;
1994+
1995+ fd_a = open (filename_a , O_RDONLY );
1996+ if (fd_a < 0 ) {
1997+ ret = error_errno (_ ("unable to open %s" ), filename_a );
1998+ goto out ;
1999+ }
2000+
2001+ fd_b = open (filename_b , O_RDONLY );
2002+ if (fd_b < 0 ) {
2003+ ret = error_errno (_ ("unable to open %s" ), filename_b );
2004+ goto out ;
2005+ }
2006+
2007+ while (1 ) {
2008+ ssize_t sz_a , sz_b ;
2009+
2010+ sz_a = read_in_full (fd_a , buf_a , sizeof (buf_a ));
2011+ if (sz_a < 0 ) {
2012+ ret = error_errno (_ ("unable to read %s" ), filename_a );
2013+ goto out ;
2014+ }
2015+
2016+ sz_b = read_in_full (fd_b , buf_b , sizeof (buf_b ));
2017+ if (sz_b < 0 ) {
2018+ ret = error_errno (_ ("unable to read %s" ), filename_b );
2019+ goto out ;
2020+ }
2021+
2022+ if (sz_a != sz_b || memcmp (buf_a , buf_b , sz_a )) {
2023+ ret = error (_ ("files '%s' and '%s' differ in contents" ),
2024+ filename_a , filename_b );
2025+ goto out ;
2026+ }
2027+
2028+ if (sz_a < sizeof (buf_a ))
2029+ break ;
2030+ }
2031+
2032+ out :
2033+ if (fd_a > -1 )
2034+ close (fd_a );
2035+ if (fd_b > -1 )
2036+ close (fd_b );
2037+ return ret ;
2038+ }
2039+
19472040/*
19482041 * Move the just written object into its final resting place.
19492042 */
19502043int finalize_object_file (const char * tmpfile , const char * filename )
19512044{
2045+ struct stat st ;
19522046 int ret = 0 ;
19532047
19542048 if (object_creation_mode == OBJECT_CREATION_USES_RENAMES )
19552049 goto try_rename ;
19562050 else if (link (tmpfile , filename ))
19572051 ret = errno ;
2052+ else
2053+ unlink_or_warn (tmpfile );
19582054
19592055 /*
19602056 * Coda hack - coda doesn't like cross-directory links,
@@ -1969,16 +2065,22 @@ int finalize_object_file(const char *tmpfile, const char *filename)
19692065 */
19702066 if (ret && ret != EEXIST ) {
19712067 try_rename :
1972- if (!rename (tmpfile , filename ))
2068+ if (!stat (filename , & st ))
2069+ ret = EEXIST ;
2070+ else if (!rename (tmpfile , filename ))
19732071 goto out ;
1974- ret = errno ;
2072+ else
2073+ ret = errno ;
19752074 }
1976- unlink_or_warn (tmpfile );
19772075 if (ret ) {
19782076 if (ret != EEXIST ) {
2077+ int saved_errno = errno ;
2078+ unlink_or_warn (tmpfile );
2079+ errno = saved_errno ;
19792080 return error_errno (_ ("unable to write file %s" ), filename );
19802081 }
1981- /* FIXME!!! Collision check here ? */
2082+ if (check_collision (tmpfile , filename ))
2083+ return -1 ;
19822084 }
19832085
19842086out :
0 commit comments