Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 builtin/checkout.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2b856a6..f961604 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -20,6 +20,7 @@
 #include "resolve-undo.h"
 #include "submodule.h"
 #include "argv-array.h"
+#include "sigchain.h"
 
 static const char * const checkout_usage[] = {
        N_("git checkout [options] <branch>"),
@@ -814,6 +815,35 @@ static int switch_branches(const struct checkout_opts 
*opts,
        return ret || writeout_error;
 }
 
+static const char *junk_work_tree;
+static const char *junk_git_dir;
+static int is_junk;
+static pid_t junk_pid;
+
+static void remove_junk(void)
+{
+       struct strbuf sb = STRBUF_INIT;
+       if (!is_junk || getpid() != junk_pid)
+               return;
+       if (junk_git_dir) {
+               strbuf_addstr(&sb, junk_git_dir);
+               remove_dir_recursively(&sb, 0);
+               strbuf_reset(&sb);
+       }
+       if (junk_work_tree) {
+               strbuf_addstr(&sb, junk_work_tree);
+               remove_dir_recursively(&sb, 0);
+               strbuf_reset(&sb);
+       }
+}
+
+static void remove_junk_on_signal(int signo)
+{
+       remove_junk();
+       sigchain_pop(signo);
+       raise(signo);
+}
+
 static int prepare_linked_checkout(const struct checkout_opts *opts,
                                   struct branch_info *new)
 {
@@ -823,7 +853,7 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
        struct stat st;
        const char *name;
        struct child_process cp;
-       int counter = 0, len;
+       int counter = 0, len, ret;
 
        if (!new->commit)
                die(_("no branch specified"));
@@ -848,13 +878,21 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
                strbuf_addf(&sb_repo, "%d", counter);
        }
        name = sb_repo.buf + len - strlen(name);
+
+       junk_pid = getpid();
+       atexit(remove_junk);
+       sigchain_push_common(remove_junk_on_signal);
+
        if (mkdir(sb_repo.buf, 0777))
                die_errno(_("could not create directory of '%s'"), sb_repo.buf);
+       junk_git_dir = sb_repo.buf;
+       is_junk = 1;
 
        strbuf_addf(&sb_git, "%s/.git", path);
        if (safe_create_leading_directories_const(sb_git.buf))
                die_errno(_("could not create leading directories of '%s'"),
                          sb_git.buf);
+       junk_work_tree = path;
 
        write_file(sb_git.buf, 1, "gitdir: %s/repos/%s\n",
                   real_path(get_git_dir()), name);
@@ -879,7 +917,14 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
        memset(&cp, 0, sizeof(cp));
        cp.git_cmd = 1;
        cp.argv = opts->saved_argv;
-       return run_command(&cp);
+       ret = run_command(&cp);
+       if (!ret)
+               is_junk = 0;
+       strbuf_release(&sb);
+       strbuf_release(&sb_repo);
+       strbuf_release(&sb_git);
+       return ret;
+
 }
 
 static int git_checkout_config(const char *var, const char *value, void *cb)
-- 
1.8.5.2.240.g8478abd

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to