summaryrefslogtreecommitdiff
path: root/setup.c
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2010-08-15 19:58:40 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2010-08-15 19:59:48 -0700
commitfc196b68905958dac66e1baaa3b66b84a2cdacfc (patch)
treeefccd657eb978e810efee668522ce27ddd163f8b /setup.c
parentconfig: run setup_git_directory_gently() sooner (diff)
parentRevert "rehabilitate 'git index-pack' inside the object store" (diff)
downloadtgif-fc196b68905958dac66e1baaa3b66b84a2cdacfc.tar.xz
Merge branch 'jn/maint-setup-fix' (early part) into jn/paginate-fix
* 'jn/maint-setup-fix' (early part): Revert "rehabilitate 'git index-pack' inside the object store" setup: do not forget working dir from subdir of gitdir t4111 (apply): refresh index before applying patches to it setup: split off get_device_or_die helper setup: split off a function to handle hitting ceiling in repo search setup: split off code to handle stumbling upon a repository setup: split off a function to checks working dir for .git file setup: split off $GIT_DIR-set case from setup_git_directory_gently tests: try git apply from subdir of toplevel t1501 (rev-parse): clarify
Diffstat (limited to 'setup.c')
-rw-r--r--setup.c171
1 files changed, 99 insertions, 72 deletions
diff --git a/setup.c b/setup.c
index 28a2b69d05..6ee1e28bd8 100644
--- a/setup.c
+++ b/setup.c
@@ -313,6 +313,93 @@ const char *read_gitfile_gently(const char *path)
return path;
}
+static const char *setup_explicit_git_dir(const char *gitdirenv,
+ const char *work_tree_env, int *nongit_ok)
+{
+ static char buffer[1024 + 1];
+ const char *retval;
+
+ if (PATH_MAX - 40 < strlen(gitdirenv))
+ die("'$%s' too big", GIT_DIR_ENVIRONMENT);
+ if (!is_git_directory(gitdirenv)) {
+ if (nongit_ok) {
+ *nongit_ok = 1;
+ return NULL;
+ }
+ die("Not a git repository: '%s'", gitdirenv);
+ }
+ if (!work_tree_env) {
+ retval = set_work_tree(gitdirenv);
+ /* config may override worktree */
+ if (check_repository_format_gently(nongit_ok))
+ return NULL;
+ return retval;
+ }
+ if (check_repository_format_gently(nongit_ok))
+ return NULL;
+ retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
+ get_git_work_tree());
+ if (!retval || !*retval)
+ return NULL;
+ set_git_dir(make_absolute_path(gitdirenv));
+ if (chdir(work_tree_env) < 0)
+ die_errno ("Could not chdir to '%s'", work_tree_env);
+ strcat(buffer, "/");
+ return retval;
+}
+
+static int cwd_contains_git_dir(const char **gitfile_dirp)
+{
+ const char *gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+ *gitfile_dirp = gitfile_dir;
+ if (gitfile_dir) {
+ if (set_git_dir(gitfile_dir))
+ die("Repository setup failed");
+ return 1;
+ }
+ return is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT);
+}
+
+static const char *setup_bare_git_dir(const char *work_tree_env,
+ int offset, int len, char *cwd, int *nongit_ok)
+{
+ int root_len;
+
+ inside_git_dir = 1;
+ if (!work_tree_env)
+ inside_work_tree = 0;
+ if (offset != len) {
+ if (chdir(cwd))
+ die_errno("Cannot come back to cwd");
+ root_len = offset_1st_component(cwd);
+ cwd[offset > root_len ? offset : root_len] = '\0';
+ set_git_dir(cwd);
+ } else
+ set_git_dir(".");
+ check_repository_format_gently(nongit_ok);
+ return NULL;
+}
+
+static const char *setup_nongit(const char *cwd, int *nongit_ok)
+{
+ if (!nongit_ok)
+ die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
+ if (chdir(cwd))
+ die_errno("Cannot come back to cwd");
+ *nongit_ok = 1;
+ return NULL;
+}
+
+static dev_t get_device_or_die(const char *path, const char *prefix)
+{
+ struct stat buf;
+ if (stat(path, &buf))
+ die_errno("failed to stat '%s%s%s'",
+ prefix ? prefix : "",
+ prefix ? "/" : "", path);
+ return buf.st_dev;
+}
+
/*
* We cannot decide in this function whether we are in the work tree or
* not, since the config can only be read _after_ this function was called.
@@ -327,7 +414,6 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
int len, offset, ceil_offset, root_len;
dev_t current_device = 0;
int one_filesystem = 1;
- struct stat buf;
/*
* Let's assume that we are in a git repository.
@@ -343,38 +429,8 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
* validation.
*/
gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
- if (gitdirenv) {
- if (PATH_MAX - 40 < strlen(gitdirenv))
- die("'$%s' too big", GIT_DIR_ENVIRONMENT);
- if (is_git_directory(gitdirenv)) {
- static char buffer[1024 + 1];
- const char *retval;
-
- if (!work_tree_env) {
- retval = set_work_tree(gitdirenv);
- /* config may override worktree */
- if (check_repository_format_gently(nongit_ok))
- return NULL;
- return retval;
- }
- if (check_repository_format_gently(nongit_ok))
- return NULL;
- retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
- get_git_work_tree());
- if (!retval || !*retval)
- return NULL;
- set_git_dir(make_absolute_path(gitdirenv));
- if (chdir(work_tree_env) < 0)
- die_errno ("Could not chdir to '%s'", work_tree_env);
- strcat(buffer, "/");
- return retval;
- }
- if (nongit_ok) {
- *nongit_ok = 1;
- return NULL;
- }
- die("Not a git repository: '%s'", gitdirenv);
- }
+ if (gitdirenv)
+ return setup_explicit_git_dir(gitdirenv, work_tree_env, nongit_ok);
if (!getcwd(cwd, sizeof(cwd)-1))
die_errno("Unable to read current working directory");
@@ -396,49 +452,20 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
*/
offset = len = strlen(cwd);
one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
- if (one_filesystem) {
- if (stat(".", &buf))
- die_errno("failed to stat '.'");
- current_device = buf.st_dev;
- }
+ if (one_filesystem)
+ current_device = get_device_or_die(".", NULL);
for (;;) {
- gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
- if (gitfile_dir) {
- if (set_git_dir(gitfile_dir))
- die("Repository setup failed");
- break;
- }
- if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))
+ if (cwd_contains_git_dir(&gitfile_dir))
break;
- if (is_git_directory(".")) {
- inside_git_dir = 1;
- if (!work_tree_env)
- inside_work_tree = 0;
- if (offset != len) {
- root_len = offset_1st_component(cwd);
- cwd[offset > root_len ? offset : root_len] = '\0';
- set_git_dir(cwd);
- } else
- set_git_dir(".");
- check_repository_format_gently(nongit_ok);
- return NULL;
- }
+ if (is_git_directory("."))
+ return setup_bare_git_dir(work_tree_env, offset,
+ len, cwd, nongit_ok);
while (--offset > ceil_offset && cwd[offset] != '/');
- if (offset <= ceil_offset) {
- if (nongit_ok) {
- if (chdir(cwd))
- die_errno("Cannot come back to cwd");
- *nongit_ok = 1;
- return NULL;
- }
- die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
- }
+ if (offset <= ceil_offset)
+ return setup_nongit(cwd, nongit_ok);
if (one_filesystem) {
- if (stat("..", &buf)) {
- cwd[offset] = '\0';
- die_errno("failed to stat '%s/..'", cwd);
- }
- if (buf.st_dev != current_device) {
+ dev_t parent_device = get_device_or_die("..", cwd);
+ if (parent_device != current_device) {
if (nongit_ok) {
if (chdir(cwd))
die_errno("Cannot come back to cwd");