mirror of
https://github.com/git/git
synced 2024-10-30 14:03:28 +00:00
da81d473fc
Many git commands that deal with working tree files try to remove a directory that becomes empty (i.e. "git switch" from a branch that has the directory to another branch that does not would attempt remove all files in the directory and the directory itself). This drops users into an unfamiliar situation if the command was run in a subdirectory that becomes subject to removal due to the command. The commands have been taught to keep an empty directory if it is the directory they were started in to avoid surprising users. * en/keep-cwd: t2501: simplify the tests since we can now assume desired behavior dir: new flag to remove_dir_recurse() to spare the original_cwd dir: avoid incidentally removing the original_cwd in remove_path() stash: do not attempt to remove startup_info->original_cwd rebase: do not attempt to remove startup_info->original_cwd clean: do not attempt to remove startup_info->original_cwd symlinks: do not include startup_info->original_cwd in dir removal unpack-trees: add special cwd handling unpack-trees: refuse to remove startup_info->original_cwd setup: introduce startup_info->original_cwd t2501: add various tests for removing the current working directory
64 lines
1.6 KiB
C
64 lines
1.6 KiB
C
#include "cache.h"
|
|
#include "exec-cmd.h"
|
|
#include "attr.h"
|
|
|
|
/*
|
|
* Many parts of Git have subprograms communicate via pipe, expect the
|
|
* upstream of a pipe to die with SIGPIPE when the downstream of a
|
|
* pipe does not need to read all that is written. Some third-party
|
|
* programs that ignore or block SIGPIPE for their own reason forget
|
|
* to restore SIGPIPE handling to the default before spawning Git and
|
|
* break this carefully orchestrated machinery.
|
|
*
|
|
* Restore the way SIGPIPE is handled to default, which is what we
|
|
* expect.
|
|
*/
|
|
static void restore_sigpipe_to_default(void)
|
|
{
|
|
sigset_t unblock;
|
|
|
|
sigemptyset(&unblock);
|
|
sigaddset(&unblock, SIGPIPE);
|
|
sigprocmask(SIG_UNBLOCK, &unblock, NULL);
|
|
signal(SIGPIPE, SIG_DFL);
|
|
}
|
|
|
|
int main(int argc, const char **argv)
|
|
{
|
|
int result;
|
|
struct strbuf tmp = STRBUF_INIT;
|
|
|
|
trace2_initialize_clock();
|
|
|
|
/*
|
|
* Always open file descriptors 0/1/2 to avoid clobbering files
|
|
* in die(). It also avoids messing up when the pipes are dup'ed
|
|
* onto stdin/stdout/stderr in the child processes we spawn.
|
|
*/
|
|
sanitize_stdfds();
|
|
restore_sigpipe_to_default();
|
|
|
|
git_resolve_executable_dir(argv[0]);
|
|
|
|
git_setup_gettext();
|
|
|
|
initialize_the_repository();
|
|
|
|
attr_start();
|
|
|
|
trace2_initialize();
|
|
trace2_cmd_start(argv);
|
|
trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
|
|
|
|
if (!strbuf_getcwd(&tmp))
|
|
tmp_original_cwd = strbuf_detach(&tmp, NULL);
|
|
|
|
result = cmd_main(argc, argv);
|
|
|
|
/*
|
|
* We define exit() to call trace2_cmd_exit_fl() in
|
|
* git-compat-util.h. Whether we reach this or exit()
|
|
* elsewhere we'll always run our trace2 exit handler.
|
|
*/
|
|
exit(result);
|
|
}
|