From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v2 07/19] worktree setup: restore original state when things go wrong
Date: Sun, 21 Mar 2010 17:30:34 +0700 [thread overview]
Message-ID: <1269167446-7799-8-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1269167446-7799-1-git-send-email-pclouds@gmail.com>
In current state of setup_git_directory_gently(), when a repository is
not found, many things will not be the same as when setup procedure is
started (while they should be). For one thing, current working
directory will not be the same in certain cases.
This patch reorders actions in clear steps and rolls back if one step
is wrong. (Actually the last step, setting git_dir, can't be rolled
back by this patch).
The steps and their state change are:
1. Looking in working directory for repository candidates (or $GIT_DIR
if it is set)
This step may move $(cwd) to somewhere.
2. Set internal variables to record repository features, based only
on repository location and environment variables.
This step sets variables:
- inside_git_dir
- inside_work_tree
3. Inspect $GIT_DIR/config to see if it's a valid repository.
This step may change variables:
- repository_format_version
- shared_repository
- is_bare_repository_cfg
- git_work_tree_cfg
4. Save the repository location for later use.
This step calls setup_git_dir() to set many variables in environment.c
5. Calculate prefix (relative path to the original current working
directory)
Setup procedure is completed at step 5. Stopping at any other steps
is considered a setup failure.
In case of setup failure, if it's not fatal and nongit_ok is not NULL,
prefix must be calculated before returning to caller. In other words:
if (!fatal && gently)
goto step_5;
Things that go wrong before step 4 will be cleaned up by
unset_git_directory(). Step 4 is irreversible, for now.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 1 +
setup.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/cache.h b/cache.h
index 3bd219c..8e9d818 100644
--- a/cache.h
+++ b/cache.h
@@ -418,6 +418,7 @@ extern const char **get_pathspec(const char *prefix, const char **pathspec);
extern void setup_work_tree(void);
extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
+extern void unset_git_directory(const char *prefix);
extern const char *prefix_path(const char *prefix, int len, const char *path);
extern const char *prefix_filename(const char *prefix, int len, const char *path);
extern int check_filename(const char *prefix, const char *name);
diff --git a/setup.c b/setup.c
index 2c1b64f..4de7bf0 100644
--- a/setup.c
+++ b/setup.c
@@ -323,6 +323,33 @@ const char *read_gitfile_gently(const char *path)
return path;
}
+void unset_git_directory(const char *prefix)
+{
+ /*
+ * FIXME:
+ * chdir(prefix) may be enough for most of cases,
+ * if original cwd is outside worktree, prefix
+ * will always be set NULL, thus impossible to move
+ * back to orignal cwd
+ */
+ if (prefix && chdir(prefix))
+ die("Cannot change to '%s'", prefix);
+
+ if (startup_info) {
+ startup_info->prefix = NULL;
+ startup_info->have_repository = 0;
+ }
+
+ /* Initialized in setup_git_directory_gently_1() */
+ inside_work_tree = -1;
+ inside_git_dir = -1;
+
+ /* Initialized in check_repository_format_version() */
+ repository_format_version = 0xFF;
+ shared_repository = PERM_UMASK;
+ is_bare_repository_cfg = -1;
+ git_work_tree_cfg = NULL;
+}
/*
* 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.
@@ -403,6 +430,13 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
* - ../ (bare)
* - ../../.git/
* etc.
+ *
+ * When a repository is found:
+ * - inside_git_dir/inside_work_tree are set
+ * - check_repository_format_gently() is called
+ * if repo version is not supported, restore cwd
+ * - set_git_dir
+ * - calculate and return prefix
*/
offset = len = strlen(cwd);
for (;;) {
@@ -410,13 +444,15 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
if (!gitfile_dir && is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))
gitfile_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
if (gitfile_dir) {
- if (set_git_dir(gitfile_dir))
- die("Repository setup failed");
inside_git_dir = 0;
if (!work_tree_env)
inside_work_tree = 1;
- if (check_repository_format_gently(gitfile_dir, nongit_ok))
+ if (check_repository_format_gently(gitfile_dir, nongit_ok)) {
+ unset_git_directory(offset != len ? cwd + offset + 1: NULL);
return NULL;
+ }
+ if (set_git_dir(gitfile_dir))
+ die("Repository setup failed");
root_len = offset_1st_component(cwd);
git_work_tree_cfg = xstrndup(cwd, offset > root_len ? offset : root_len);
break;
@@ -425,8 +461,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
inside_git_dir = 1;
if (!work_tree_env)
inside_work_tree = 0;
- if (check_repository_format_gently(".", nongit_ok))
+ if (check_repository_format_gently(".", nongit_ok)) {
+ unset_git_directory(offset != len ? cwd + offset + 1: NULL);
return NULL;
+ }
if (offset != len) {
root_len = offset_1st_component(cwd);
cwd[offset > root_len ? offset : root_len] = '\0';
--
1.7.0.2.425.gb99f1
next prev parent reply other threads:[~2010-03-21 10:35 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-21 10:30 [PATCH v2 00/19] nd/setup part two, second round Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 01/19] Move enter_repo() to setup.c Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 02/19] enter_repo(): initialize other variables as setup_git_directory_gently() does Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 03/19] rev-parse --git-dir: print relative gitdir correctly Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 04/19] worktree setup: call set_git_dir explicitly Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 05/19] Add git_config_early() Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 06/19] Use git_config_early() instead of git_config() during repo setup Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` Nguyễn Thái Ngọc Duy [this message]
2010-03-21 10:30 ` [PATCH v2 08/19] init/clone: turn on startup->have_repository properly Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 09/19] git_config(): do not read .git/config if there is no repository Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 10/19] Do not read .git/info/exclude " Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 11/19] Do not read .git/info/attributes " Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 12/19] apply: do not check sha1 when repository has not been found Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 13/19] config: do not read .git/config if there is no repository Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 14/19] run_builtin(): save "-h" detection result for later use Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 15/19] builtins: utilize startup_info->help where possible Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 16/19] builtins: check for startup_info->help, print and exit early Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 17/19] Allow to undo setup_git_directory_gently() gracefully (and fix alias code) Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 18/19] alias: keep repository found while collecting aliases as long as possible Nguyễn Thái Ngọc Duy
2010-03-21 10:30 ` [PATCH v2 19/19] Guard unallowed access to repository when it's not set up Nguyễn Thái Ngọc Duy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1269167446-7799-8-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).