@@ -21,11 +21,13 @@ enum deny_action {
2121static int deny_deletes = 0 ;
2222static int deny_non_fast_forwards = 0 ;
2323static enum deny_action deny_current_branch = DENY_UNCONFIGURED ;
24+ static enum deny_action deny_delete_current = DENY_UNCONFIGURED ;
2425static int receive_fsck_objects ;
2526static int receive_unpack_limit = -1 ;
2627static int transfer_unpack_limit = -1 ;
2728static int unpack_limit = 100 ;
2829static int report_status ;
30+ static const char * head_name ;
2931
3032static char capabilities [] = " report-status delete-refs " ;
3133static int capabilities_sent ;
@@ -77,6 +79,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
7779 return 0 ;
7880 }
7981
82+ if (strcmp (var , "receive.denydeletecurrent" ) == 0 ) {
83+ deny_delete_current = parse_deny_action (var , value );
84+ return 0 ;
85+ }
86+
8087 return git_default_config (var , value , cb );
8188}
8289
@@ -203,16 +210,12 @@ static int run_update_hook(struct command *cmd)
203210
204211static int is_ref_checked_out (const char * ref )
205212{
206- unsigned char sha1 [20 ];
207- const char * head ;
208-
209213 if (is_bare_repository ())
210214 return 0 ;
211215
212- head = resolve_ref ("HEAD" , sha1 , 0 , NULL );
213- if (!head )
216+ if (!head_name )
214217 return 0 ;
215- return !strcmp (head , ref );
218+ return !strcmp (head_name , ref );
216219}
217220
218221static char * warn_unconfigured_deny_msg [] = {
@@ -244,6 +247,32 @@ static void warn_unconfigured_deny(void)
244247 warning (warn_unconfigured_deny_msg [i ]);
245248}
246249
250+ static char * warn_unconfigured_deny_delete_current_msg [] = {
251+ "Deleting the current branch can cause confusion by making the next" ,
252+ "'git clone' not check out any file." ,
253+ "" ,
254+ "You can set 'receive.denyDeleteCurrent' configuration variable to" ,
255+ "'refuse' in the remote repository to disallow deleting the current" ,
256+ "branch." ,
257+ "" ,
258+ "You can set it to 'ignore' to allow such a delete without a warning." ,
259+ "" ,
260+ "To make this warning message less loud, you can set it to 'warn'." ,
261+ "" ,
262+ "Note that the default will change in a future version of git" ,
263+ "to refuse deleting the current branch unless you have the" ,
264+ "configuration variable set to either 'ignore' or 'warn'."
265+ };
266+
267+ static void warn_unconfigured_deny_delete_current (void )
268+ {
269+ int i ;
270+ for (i = 0 ;
271+ i < ARRAY_SIZE (warn_unconfigured_deny_delete_current_msg );
272+ i ++ )
273+ warning (warn_unconfigured_deny_delete_current_msg [i ]);
274+ }
275+
247276static const char * update (struct command * cmd )
248277{
249278 const char * name = cmd -> ref_name ;
@@ -278,12 +307,30 @@ static const char *update(struct command *cmd)
278307 "but I can't find it!" , sha1_to_hex (new_sha1 ));
279308 return "bad pack" ;
280309 }
281- if (deny_deletes && is_null_sha1 (new_sha1 ) &&
282- !is_null_sha1 (old_sha1 ) &&
283- !prefixcmp (name , "refs/heads/" )) {
284- error ("denying ref deletion for %s" , name );
285- return "deletion prohibited" ;
310+
311+ if (!is_null_sha1 (old_sha1 ) && is_null_sha1 (new_sha1 )) {
312+ if (deny_deletes && !prefixcmp (name , "refs/heads/" )) {
313+ error ("denying ref deletion for %s" , name );
314+ return "deletion prohibited" ;
315+ }
316+
317+ if (!strcmp (name , head_name )) {
318+ switch (deny_delete_current ) {
319+ case DENY_IGNORE :
320+ break ;
321+ case DENY_WARN :
322+ case DENY_UNCONFIGURED :
323+ if (deny_delete_current == DENY_UNCONFIGURED )
324+ warn_unconfigured_deny_delete_current ();
325+ warning ("deleting the current branch" );
326+ break ;
327+ case DENY_REFUSE :
328+ error ("refusing to delete the current branch: %s" , name );
329+ return "deletion of the current branch prohibited" ;
330+ }
331+ }
286332 }
333+
287334 if (deny_non_fast_forwards && !is_null_sha1 (new_sha1 ) &&
288335 !is_null_sha1 (old_sha1 ) &&
289336 !prefixcmp (name , "refs/heads/" )) {
@@ -377,6 +424,7 @@ static void run_update_post_hook(struct command *cmd)
377424static void execute_commands (const char * unpacker_error )
378425{
379426 struct command * cmd = commands ;
427+ unsigned char sha1 [20 ];
380428
381429 if (unpacker_error ) {
382430 while (cmd ) {
@@ -394,6 +442,8 @@ static void execute_commands(const char *unpacker_error)
394442 return ;
395443 }
396444
445+ head_name = resolve_ref ("HEAD" , sha1 , 0 , NULL );
446+
397447 while (cmd ) {
398448 cmd -> error_string = update (cmd );
399449 cmd = cmd -> next ;
0 commit comments