2020#include "resolve-undo.h"
2121#include "submodule.h"
2222#include "argv-array.h"
23+ #include "sigchain.h"
2324
2425static const char * const checkout_usage [] = {
2526 N_ ("git checkout [options] <branch>" ),
@@ -823,6 +824,35 @@ static int switch_branches(const struct checkout_opts *opts,
823824 return ret || writeout_error ;
824825}
825826
827+ static char * junk_work_tree ;
828+ static char * junk_git_dir ;
829+ static int is_junk ;
830+ static pid_t junk_pid ;
831+
832+ static void remove_junk (void )
833+ {
834+ struct strbuf sb = STRBUF_INIT ;
835+ if (!is_junk || getpid () != junk_pid )
836+ return ;
837+ if (junk_git_dir ) {
838+ strbuf_addstr (& sb , junk_git_dir );
839+ remove_dir_recursively (& sb , 0 );
840+ strbuf_reset (& sb );
841+ }
842+ if (junk_work_tree ) {
843+ strbuf_addstr (& sb , junk_work_tree );
844+ remove_dir_recursively (& sb , 0 );
845+ }
846+ strbuf_release (& sb );
847+ }
848+
849+ static void remove_junk_on_signal (int signo )
850+ {
851+ remove_junk ();
852+ sigchain_pop (signo );
853+ raise (signo );
854+ }
855+
826856static int prepare_linked_checkout (const struct checkout_opts * opts ,
827857 struct branch_info * new )
828858{
@@ -859,8 +889,15 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
859889 strbuf_addf (& sb_repo , "%d" , counter );
860890 }
861891 name = strrchr (sb_repo .buf , '/' ) + 1 ;
892+
893+ junk_pid = getpid ();
894+ atexit (remove_junk );
895+ sigchain_push_common (remove_junk_on_signal );
896+
862897 if (mkdir (sb_repo .buf , 0777 ))
863898 die_errno (_ ("could not create directory of '%s'" ), sb_repo .buf );
899+ junk_git_dir = xstrdup (sb_repo .buf );
900+ is_junk = 1 ;
864901
865902 /*
866903 * lock the incomplete repo so prune won't delete it, unlock
@@ -873,6 +910,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
873910 if (safe_create_leading_directories_const (sb_git .buf ))
874911 die_errno (_ ("could not create leading directories of '%s'" ),
875912 sb_git .buf );
913+ junk_work_tree = xstrdup (path );
876914
877915 strbuf_reset (& sb );
878916 strbuf_addf (& sb , "%s/gitdir" , sb_repo .buf );
@@ -902,9 +940,19 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
902940 cp .git_cmd = 1 ;
903941 cp .argv = opts -> saved_argv ;
904942 ret = run_command (& cp );
943+ if (!ret ) {
944+ is_junk = 0 ;
945+ free (junk_work_tree );
946+ free (junk_git_dir );
947+ junk_work_tree = NULL ;
948+ junk_git_dir = NULL ;
949+ }
905950 strbuf_reset (& sb );
906951 strbuf_addf (& sb , "%s/locked" , sb_repo .buf );
907952 unlink_or_warn (sb .buf );
953+ strbuf_release (& sb );
954+ strbuf_release (& sb_repo );
955+ strbuf_release (& sb_git );
908956 return ret ;
909957}
910958
0 commit comments