@@ -1081,29 +1081,16 @@ int rerere_forget(struct pathspec *pathspec)
1081
1081
* Garbage collection support
1082
1082
*/
1083
1083
1084
- /*
1085
- * Note that this is not reentrant but is used only one-at-a-time
1086
- * so it does not matter right now.
1087
- */
1088
- static struct rerere_id * dirname_to_id (const char * name )
1089
- {
1090
- static struct rerere_id id ;
1091
- id .collection = find_rerere_dir (name );
1092
- return & id ;
1093
- }
1094
-
1095
- static time_t rerere_created_at (const char * dir_name )
1084
+ static time_t rerere_created_at (struct rerere_id * id )
1096
1085
{
1097
1086
struct stat st ;
1098
- struct rerere_id * id = dirname_to_id (dir_name );
1099
1087
1100
1088
return stat (rerere_path (id , "preimage" ), & st ) ? (time_t ) 0 : st .st_mtime ;
1101
1089
}
1102
1090
1103
- static time_t rerere_last_used_at (const char * dir_name )
1091
+ static time_t rerere_last_used_at (struct rerere_id * id )
1104
1092
{
1105
1093
struct stat st ;
1106
- struct rerere_id * id = dirname_to_id (dir_name );
1107
1094
1108
1095
return stat (rerere_path (id , "postimage" ), & st ) ? (time_t ) 0 : st .st_mtime ;
1109
1096
}
@@ -1113,24 +1100,37 @@ static time_t rerere_last_used_at(const char *dir_name)
1113
1100
*/
1114
1101
static void unlink_rr_item (struct rerere_id * id )
1115
1102
{
1116
- unlink (rerere_path (id , "thisimage" ));
1117
- unlink (rerere_path (id , "preimage" ));
1118
- unlink (rerere_path (id , "postimage" ));
1119
- /*
1120
- * NEEDSWORK: what if this rmdir() fails? Wouldn't we then
1121
- * assume that we already have preimage recorded in
1122
- * do_plain_rerere()?
1123
- */
1124
- rmdir (rerere_path (id , NULL ));
1103
+ unlink_or_warn (rerere_path (id , "thisimage" ));
1104
+ remove_variant (id );
1105
+ id -> collection -> status [id -> variant ] = 0 ;
1106
+ }
1107
+
1108
+ static void prune_one (struct rerere_id * id , time_t now ,
1109
+ int cutoff_resolve , int cutoff_noresolve )
1110
+ {
1111
+ time_t then ;
1112
+ int cutoff ;
1113
+
1114
+ then = rerere_last_used_at (id );
1115
+ if (then )
1116
+ cutoff = cutoff_resolve ;
1117
+ else {
1118
+ then = rerere_created_at (id );
1119
+ if (!then )
1120
+ return ;
1121
+ cutoff = cutoff_noresolve ;
1122
+ }
1123
+ if (then < now - cutoff * 86400 )
1124
+ unlink_rr_item (id );
1125
1125
}
1126
1126
1127
1127
void rerere_gc (struct string_list * rr )
1128
1128
{
1129
1129
struct string_list to_remove = STRING_LIST_INIT_DUP ;
1130
1130
DIR * dir ;
1131
1131
struct dirent * e ;
1132
- int i , cutoff ;
1133
- time_t now = time (NULL ), then ;
1132
+ int i ;
1133
+ time_t now = time (NULL );
1134
1134
int cutoff_noresolve = 15 ;
1135
1135
int cutoff_resolve = 60 ;
1136
1136
@@ -1142,25 +1142,32 @@ void rerere_gc(struct string_list *rr)
1142
1142
die_errno ("unable to open rr-cache directory" );
1143
1143
/* Collect stale conflict IDs ... */
1144
1144
while ((e = readdir (dir ))) {
1145
+ struct rerere_dir * rr_dir ;
1146
+ struct rerere_id id ;
1147
+ int now_empty ;
1148
+
1145
1149
if (is_dot_or_dotdot (e -> d_name ))
1146
1150
continue ;
1147
-
1148
- then = rerere_last_used_at (e -> d_name );
1149
- if (then ) {
1150
- cutoff = cutoff_resolve ;
1151
- } else {
1152
- then = rerere_created_at (e -> d_name );
1153
- if (!then )
1154
- continue ;
1155
- cutoff = cutoff_noresolve ;
1151
+ rr_dir = find_rerere_dir (e -> d_name );
1152
+ if (!rr_dir )
1153
+ continue ; /* or should we remove e->d_name? */
1154
+
1155
+ now_empty = 1 ;
1156
+ for (id .variant = 0 , id .collection = rr_dir ;
1157
+ id .variant < id .collection -> status_nr ;
1158
+ id .variant ++ ) {
1159
+ prune_one (& id , now , cutoff_resolve , cutoff_noresolve );
1160
+ if (id .collection -> status [id .variant ])
1161
+ now_empty = 0 ;
1156
1162
}
1157
- if (then < now - cutoff * 86400 )
1163
+ if (now_empty )
1158
1164
string_list_append (& to_remove , e -> d_name );
1159
1165
}
1160
1166
closedir (dir );
1161
- /* ... and then remove them one-by-one */
1167
+
1168
+ /* ... and then remove the empty directories */
1162
1169
for (i = 0 ; i < to_remove .nr ; i ++ )
1163
- unlink_rr_item ( dirname_to_id ( to_remove .items [i ].string ));
1170
+ rmdir ( git_path ( "rr-cache/%s" , to_remove .items [i ].string ));
1164
1171
string_list_clear (& to_remove , 0 );
1165
1172
}
1166
1173
@@ -1177,8 +1184,10 @@ void rerere_clear(struct string_list *merge_rr)
1177
1184
1178
1185
for (i = 0 ; i < merge_rr -> nr ; i ++ ) {
1179
1186
struct rerere_id * id = merge_rr -> items [i ].util ;
1180
- if (!has_rerere_resolution (id ))
1187
+ if (!has_rerere_resolution (id )) {
1181
1188
unlink_rr_item (id );
1189
+ rmdir (rerere_path (id , NULL ));
1190
+ }
1182
1191
}
1183
1192
unlink_or_warn (git_path ("MERGE_RR" ));
1184
1193
}
0 commit comments