Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-06-21 22:51:16 +0400
committerRussell Belfer <rb@github.com>2013-06-21 22:55:13 +0400
commit9094ae5a3c12ee99743498cb8e895d18b932e4dd (patch)
treed9018379bf5d6b784681f256ebd5186e0662688f /src
parent00197c34d6385a2de3970c9f820714064c5bf27f (diff)
Add target directory to checkout
This adds the ability for checkout to write to a target directory instead of having to use the working directory of the repository. This makes it easier to do exports of repository data and the like. This is similar to, but not quite the same as, the --prefix option to `git checkout-index` (this will always be treated as a directory name, not just as a simple text prefix). As part of this, the workdir iterator was extended to take the path to the working directory as a parameter and fallback on the git_repository_workdir result only if it's not specified. Fixes #1332
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c25
-rw-r--r--src/iterator.c12
-rw-r--r--src/iterator.h15
3 files changed, 39 insertions, 13 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 065bb50fd..e3ae38710 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -858,7 +858,7 @@ static int checkout_submodule(
return 0;
if ((error = git_futils_mkdir(
- file->path, git_repository_workdir(data->repo),
+ file->path, data->opts.target_directory,
data->opts.dir_mode, GIT_MKDIR_PATH)) < 0)
return error;
@@ -1030,7 +1030,7 @@ static int checkout_deferred_remove(git_repository *repo, const char *path)
{
#if 0
int error = git_futils_rmdir_r(
- path, git_repository_workdir(repo), GIT_RMDIR_EMPTY_PARENTS);
+ path, data->opts.target_directory, GIT_RMDIR_EMPTY_PARENTS);
if (error == GIT_ENOTFOUND) {
error = 0;
@@ -1163,7 +1163,8 @@ static int checkout_data_init(
return -1;
}
- if ((error = git_repository__ensure_not_bare(repo, "checkout")) < 0)
+ if ((!proposed || !proposed->target_directory) &&
+ (error = git_repository__ensure_not_bare(repo, "checkout")) < 0)
return error;
data->repo = repo;
@@ -1176,6 +1177,13 @@ static int checkout_data_init(
else
memmove(&data->opts, proposed, sizeof(git_checkout_opts));
+ if (!data->opts.target_directory)
+ data->opts.target_directory = git_repository_workdir(repo);
+ else if (!git_path_isdir(data->opts.target_directory) &&
+ (error = git_futils_mkdir(data->opts.target_directory, NULL,
+ GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR)) < 0)
+ goto cleanup;
+
/* refresh config and index content unless NO_REFRESH is given */
if ((data->opts.checkout_strategy & GIT_CHECKOUT_NO_REFRESH) == 0) {
git_config *cfg;
@@ -1238,7 +1246,8 @@ static int checkout_data_init(
if ((error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 ||
(error = git_pool_init(&data->pool, 1, 0)) < 0 ||
- (error = git_buf_puts(&data->path, git_repository_workdir(repo))) < 0)
+ (error = git_buf_puts(&data->path, data->opts.target_directory)) < 0 ||
+ (error = git_path_to_dir(&data->path)) < 0)
goto cleanup;
data->workdir_len = git_buf_len(&data->path);
@@ -1286,11 +1295,13 @@ int git_checkout_iterator(
GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
if ((error = git_iterator_reset(target, data.pfx, data.pfx)) < 0 ||
- (error = git_iterator_for_workdir(
- &workdir, data.repo, iterflags | GIT_ITERATOR_DONT_AUTOEXPAND,
+ (error = git_iterator_for_workdir_ext(
+ &workdir, data.repo, data.opts.target_directory,
+ iterflags | GIT_ITERATOR_DONT_AUTOEXPAND,
data.pfx, data.pfx)) < 0 ||
(error = git_iterator_for_tree(
- &baseline, data.opts.baseline, iterflags, data.pfx, data.pfx)) < 0)
+ &baseline, data.opts.baseline,
+ iterflags, data.pfx, data.pfx)) < 0)
goto cleanup;
/* Should not have case insensitivity mismatch */
diff --git a/src/iterator.c b/src/iterator.c
index 76b0e41d0..5917f63fd 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -1321,9 +1321,10 @@ static void workdir_iterator__free(git_iterator *self)
git_ignore__free(&wi->ignores);
}
-int git_iterator_for_workdir(
+int git_iterator_for_workdir_ext(
git_iterator **out,
git_repository *repo,
+ const char *repo_workdir,
git_iterator_flag_t flags,
const char *start,
const char *end)
@@ -1331,8 +1332,11 @@ int git_iterator_for_workdir(
int error;
workdir_iterator *wi;
- if (git_repository__ensure_not_bare(repo, "scan working directory") < 0)
- return GIT_EBAREREPO;
+ if (!repo_workdir) {
+ if (git_repository__ensure_not_bare(repo, "scan working directory") < 0)
+ return GIT_EBAREREPO;
+ repo_workdir = git_repository_workdir(repo);
+ }
/* initialize as an fs iterator then do overrides */
wi = git__calloc(1, sizeof(workdir_iterator));
@@ -1352,7 +1356,7 @@ int git_iterator_for_workdir(
return error;
}
- return fs_iterator__initialize(out, &wi->fi, git_repository_workdir(repo));
+ return fs_iterator__initialize(out, &wi->fi, repo_workdir);
}
diff --git a/src/iterator.h b/src/iterator.h
index 493ff4b2a..ea88fa6a2 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -79,15 +79,26 @@ extern int git_iterator_for_index(
const char *start,
const char *end);
+extern int git_iterator_for_workdir_ext(
+ git_iterator **out,
+ git_repository *repo,
+ const char *repo_workdir,
+ git_iterator_flag_t flags,
+ const char *start,
+ const char *end);
+
/* workdir iterators will match the ignore_case value from the index of the
* repository, unless you override with a non-zero flag value
*/
-extern int git_iterator_for_workdir(
+GIT_INLINE(int) git_iterator_for_workdir(
git_iterator **out,
git_repository *repo,
git_iterator_flag_t flags,
const char *start,
- const char *end);
+ const char *end)
+{
+ return git_iterator_for_workdir_ext(out, repo, NULL, flags, start, end);
+}
/* for filesystem iterators, you have to explicitly pass in the ignore_case
* behavior that you desire