git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v7 23/31] checkout: clean up half-prepared directories in --to mode

From
Eric Sunshine <sunshine@sunshineco.com>
Date
Jul 20, 2014, 23:55 UTC
Message-ID
<CAPig+cRE0xOhQM4mtJQRX_gSQ3_OMr6ws87wU03TZ1eaUXui2g@mail.gmail.com>
In-Reply-To
<1405227068-25506-24-git-send-email-pclouds@gmail.com>

On Sun, Jul 13, 2014 at 12:51 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:

Show 74 quoted lines
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
>  builtin/checkout.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 47 insertions(+), 2 deletions(-)
>
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index 81adb74..3167fd2 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_release(&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)
>  {
> @@ -822,7 +852,7 @@ static int prepare_linked_checkout(const struct checkout_opts *opts,
>         const char *path = opts->new_worktree, *name;
>         struct stat st;
>         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 = strrchr(sb_repo.buf, '/') + 1;
> +
> +       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;

I've managed to convince myself that, although junk_git_dir becomes a dangling pointer by the end of prepare_linked_checkout(), it should never afterward be accessed. Perhaps it would make sense to make this easier to follow by clearing junk_git_dir when is_junk is cleared?

Show 18 quoted lines
> +       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_common_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;
Here: perhaps also set is_junk_dir to NULL since it otherwise is about
to become a dangling pointer.
Show 10 quoted lines
> +       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.9.1.346.ga2b5940
Previous: Nguyễn Thái Ngọc DuyNext: Eric Sunshine
Message 68 of 83 in “Support multiple checkouts”
  1. 00/32 Support multiple checkoutsNguyễn Thái Ngọc Duy, Jul 9, 2014
  2. 01/32 path.c: make get_pathname() return strbuf instead of static bufferNguyễn Thái Ngọc Duy, Jul 9, 2014
  3. 02/32 path.c: make get_pathname() call sites return const char *Nguyễn Thái Ngọc Duy, Jul 9, 2014
  4. 03/32 git_snpath(): retire and replace with strbuf_git_path()Nguyễn Thái Ngọc Duy, Jul 9, 2014
  5. 04/32 path.c: rename vsnpath() to do_git_path()Nguyễn Thái Ngọc Duy, Jul 9, 2014
  6. 05/32 path.c: group git_path(), git_pathdup() and strbuf_git_path() togetherNguyễn Thái Ngọc Duy, Jul 9, 2014
  7. 06/32 setup_git_env: use git_pathdup instead of xmalloc + sprintfNguyễn Thái Ngọc Duy, Jul 9, 2014
  8. 07/32 setup_git_env(): introduce git_path_from_env() helperNguyễn Thái Ngọc Duy, Jul 9, 2014
  9. 08/32 git_path(): be aware of file relocation in $GIT_DIRNguyễn Thái Ngọc Duy, Jul 9, 2014
  10. 09/32 *.sh: respect $GIT_INDEX_FILENguyễn Thái Ngọc Duy, Jul 9, 2014
  11. 10/32 reflog: avoid constructing .lock path with git_pathNguyễn Thái Ngọc Duy, Jul 9, 2014
  12. 11/32 fast-import: use git_path() for accessing .git dir instead of get_git_dir()Nguyễn Thái Ngọc Duy, Jul 9, 2014
  13. 12/32 commit: use SEQ_DIR instead of hardcoding "sequencer"Nguyễn Thái Ngọc Duy, Jul 9, 2014
  14. 13/32 $GIT_COMMON_DIR: a new environment variableNguyễn Thái Ngọc Duy, Jul 9, 2014
  15. 14/32 git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objectsNguyễn Thái Ngọc Duy, Jul 9, 2014
  16. 15/32 *.sh: avoid hardcoding $GIT_DIR/hooks/...Nguyễn Thái Ngọc Duy, Jul 9, 2014
  17. 16/32 git-stash: avoid hardcoding $GIT_DIR/logs/....Nguyễn Thái Ngọc Duy, Jul 9, 2014
  18. 17/32 setup.c: convert is_git_directory() to use strbufNguyễn Thái Ngọc Duy, Jul 9, 2014
  19. 18/32 setup.c: detect $GIT_COMMON_DIR in is_git_directory()Nguyễn Thái Ngọc Duy, Jul 9, 2014
  20. 19/32 setup.c: convert check_repository_format_gently to use strbufNguyễn Thái Ngọc Duy, Jul 9, 2014
  21. 20/32 setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()Nguyễn Thái Ngọc Duy, Jul 9, 2014
  22. 21/32 setup.c: support multi-checkout repo setupNguyễn Thái Ngọc Duy, Jul 9, 2014
  23. 22/32 wrapper.c: wrapper to open a file, fprintf then closeNguyễn Thái Ngọc Duy, Jul 9, 2014
  24. 23/32 use new wrapper write_file() for simple file writingNguyễn Thái Ngọc Duy, Jul 9, 2014
  25. 24/32 checkout: support checking out into a new working directoryNguyễn Thái Ngọc Duy, Jul 9, 2014
  26. 25/32 checkout: clean up half-prepared directories in --to modeNguyễn Thái Ngọc Duy, Jul 9, 2014
  27. 26/32 checkout: detach if the branch is already checked out elsewhereNguyễn Thái Ngọc Duy, Jul 9, 2014
  28. Max KirillovJul 12, 2014
  29. 27/32 prune: strategies for linked checkoutsNguyễn Thái Ngọc Duy, Jul 9, 2014
  30. Eric SunshineJul 9, 2014
  31. 28/32 gc: style change -- no SP before closing bracketNguyễn Thái Ngọc Duy, Jul 9, 2014
  32. Eric SunshineJul 9, 2014
  33. Junio C HamanoJul 14, 2014
  34. 29/32 gc: support prune --reposNguyễn Thái Ngọc Duy, Jul 9, 2014
  35. Eric SunshineJul 9, 2014
  36. 30/32 count-objects: report unused files in $GIT_DIR/repos/...Nguyễn Thái Ngọc Duy, Jul 9, 2014
  37. 31/32 git_path(): keep "info/sparse-checkout" per work-treeNguyễn Thái Ngọc Duy, Jul 9, 2014
  38. 32/32 checkout: don't require a work tree when checking out into a new oneNguyễn Thái Ngọc Duy, Jul 9, 2014
  39. Dennis KaarsemakerJul 11, 2014
  40. 00/31 Support multiple checkoutsNguyễn Thái Ngọc Duy, Jul 13, 2014
  41. 01/31 path.c: make get_pathname() return strbuf instead of static bufferNguyễn Thái Ngọc Duy, Jul 13, 2014
  42. 02/31 path.c: make get_pathname() call sites return const char *Nguyễn Thái Ngọc Duy, Jul 13, 2014
  43. 03/31 git_snpath(): retire and replace with strbuf_git_path()Nguyễn Thái Ngọc Duy, Jul 13, 2014
  44. 04/31 path.c: rename vsnpath() to do_git_path()Nguyễn Thái Ngọc Duy, Jul 13, 2014
  45. 05/31 path.c: group git_path(), git_pathdup() and strbuf_git_path() togetherNguyễn Thái Ngọc Duy, Jul 13, 2014
  46. 06/31 git_path(): be aware of file relocation in $GIT_DIRNguyễn Thái Ngọc Duy, Jul 13, 2014
  47. 07/31 *.sh: respect $GIT_INDEX_FILENguyễn Thái Ngọc Duy, Jul 13, 2014
  48. 08/31 reflog: avoid constructing .lock path with git_pathNguyễn Thái Ngọc Duy, Jul 13, 2014
  49. 09/31 fast-import: use git_path() for accessing .git dir instead of get_git_dir()Nguyễn Thái Ngọc Duy, Jul 13, 2014
  50. 10/31 commit: use SEQ_DIR instead of hardcoding "sequencer"Nguyễn Thái Ngọc Duy, Jul 13, 2014
  51. 11/31 $GIT_COMMON_DIR: a new environment variableNguyễn Thái Ngọc Duy, Jul 13, 2014
  52. Eric SunshineJul 23, 2014
  53. 12/31 git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objectsNguyễn Thái Ngọc Duy, Jul 13, 2014
  54. 13/31 *.sh: avoid hardcoding $GIT_DIR/hooks/...Nguyễn Thái Ngọc Duy, Jul 13, 2014
  55. 14/31 git-stash: avoid hardcoding $GIT_DIR/logs/....Nguyễn Thái Ngọc Duy, Jul 13, 2014
  56. 15/31 setup.c: convert is_git_directory() to use strbufNguyễn Thái Ngọc Duy, Jul 13, 2014
  57. 16/31 setup.c: detect $GIT_COMMON_DIR in is_git_directory()Nguyễn Thái Ngọc Duy, Jul 13, 2014
  58. 17/31 setup.c: convert check_repository_format_gently to use strbufNguyễn Thái Ngọc Duy, Jul 13, 2014
  59. 18/31 setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()Nguyễn Thái Ngọc Duy, Jul 13, 2014
  60. 19/31 setup.c: support multi-checkout repo setupNguyễn Thái Ngọc Duy, Jul 13, 2014
  61. 20/31 wrapper.c: wrapper to open a file, fprintf then closeNguyễn Thái Ngọc Duy, Jul 13, 2014
  62. 21/31 use new wrapper write_file() for simple file writingNguyễn Thái Ngọc Duy, Jul 13, 2014
  63. 22/31 checkout: support checking out into a new working directoryNguyễn Thái Ngọc Duy, Jul 13, 2014
  64. Max KirillovJul 17, 2014
  65. Junio C HamanoJul 17, 2014
  66. Eric SunshineJul 18, 2014
  67. 23/31 checkout: clean up half-prepared directories in --to modeNguyễn Thái Ngọc Duy, Jul 13, 2014
  68. Eric SunshineJul 20, 2014
  69. Eric SunshineJul 21, 2014
  70. Duy NguyenJul 23, 2014
  71. 24/31 checkout: detach if the branch is already checked out elsewhereNguyễn Thái Ngọc Duy, Jul 13, 2014
  72. 25/31 prune: strategies for linked checkoutsNguyễn Thái Ngọc Duy, Jul 13, 2014
  73. Thomas RastJul 18, 2014
  74. Duy NguyenJul 19, 2014
  75. 26/31 gc: style change -- no SP before closing bracketNguyễn Thái Ngọc Duy, Jul 13, 2014
  76. 27/31 gc: factor out gc.pruneexpire parsing codeNguyễn Thái Ngọc Duy, Jul 13, 2014
  77. 28/31 gc: support prune --reposNguyễn Thái Ngọc Duy, Jul 13, 2014
  78. 29/31 count-objects: report unused files in $GIT_DIR/repos/...Nguyễn Thái Ngọc Duy, Jul 13, 2014
  79. 30/31 git_path(): keep "info/sparse-checkout" per work-treeNguyễn Thái Ngọc Duy, Jul 13, 2014
  80. 31/31 checkout: don't require a work tree when checking out into a new oneNguyễn Thái Ngọc Duy, Jul 13, 2014
  81. Junio C HamanoJul 14, 2014
  82. Duy NguyenJul 14, 2014
  83. Junio C HamanoJul 14, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.