diff options
author | Jameson Miller <jamill@microsoft.com> | 2014-08-20 10:24:41 -0400 |
---|---|---|
committer | Jameson Miller <jamill@microsoft.com> | 2014-09-02 21:07:26 -0400 |
commit | bc737620dd0d331cb80c22d074569fe29b7ab585 (patch) | |
tree | 02845048ed92a316433bf6c38d8283408d6b530f /src | |
parent | 0ee9f31c3b11116ab5806ab80d03b1d37197d6ce (diff) | |
download | libgit2-jamill/relative_gitlink.tar.gz |
Introduce option to use relative paths for repository work directoryjamill/relative_gitlink
Teach git_repository_init_ext to use relative paths for the gitlink
to the work directory. This is used when creating a sub repository
where the sub repository resides in the parent repository's
.git directory.
Diffstat (limited to 'src')
-rw-r--r-- | src/repository.c | 32 | ||||
-rw-r--r-- | src/submodule.c | 106 |
2 files changed, 97 insertions, 41 deletions
diff --git a/src/repository.c b/src/repository.c index 4f7a5feab..d86d8905a 100644 --- a/src/repository.c +++ b/src/repository.c @@ -994,7 +994,7 @@ static int repo_init_config( uint32_t mode) { int error = 0; - git_buf cfg_path = GIT_BUF_INIT; + git_buf cfg_path = GIT_BUF_INIT, worktree_path = GIT_BUF_INIT; git_config *config = NULL; bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0); bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0); @@ -1019,9 +1019,16 @@ static int repo_init_config( if (!is_bare) { SET_REPO_CONFIG(bool, "core.logallrefupdates", true); - if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) - SET_REPO_CONFIG(string, "core.worktree", work_dir); - else if (is_reinit) { + if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) { + if ((error = git_buf_sets(&worktree_path, work_dir)) < 0) + goto cleanup; + + if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK)) + if ((error = git_path_make_relative(&worktree_path, repo_dir)) < 0) + goto cleanup; + + SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr); + } else if (is_reinit) { if (git_config_delete_entry(config, "core.worktree") < 0) giterr_clear(); } @@ -1038,6 +1045,7 @@ static int repo_init_config( cleanup: git_buf_free(&cfg_path); + git_buf_free(&worktree_path); git_config_free(config); return error; @@ -1126,10 +1134,11 @@ static int repo_write_template( } static int repo_write_gitlink( - const char *in_dir, const char *to_repo) + const char *in_dir, const char *to_repo, bool use_relative_path) { int error; git_buf buf = GIT_BUF_INIT; + git_buf path_to_repo = GIT_BUF_INIT; struct stat st; git_path_dirname_r(&buf, to_repo); @@ -1157,13 +1166,20 @@ static int repo_write_gitlink( git_buf_clear(&buf); - error = git_buf_printf(&buf, "%s %s", GIT_FILE_CONTENT_PREFIX, to_repo); + error = git_buf_sets(&path_to_repo, to_repo); + + if (!error && use_relative_path) + error = git_path_make_relative(&path_to_repo, in_dir); + + if (!error) + error = git_buf_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr); if (!error) error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr); cleanup: git_buf_free(&buf); + git_buf_free(&path_to_repo); return error; } @@ -1207,7 +1223,7 @@ static int repo_init_structure( if ((opts->flags & GIT_REPOSITORY_INIT_BARE) == 0 && (opts->flags & GIT_REPOSITORY_INIT__NATURAL_WD) == 0) { - if (repo_write_gitlink(work_dir, repo_dir) < 0) + if (repo_write_gitlink(work_dir, repo_dir, opts->flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK) < 0) return -1; } @@ -1635,7 +1651,7 @@ int git_repository_set_workdir( if (git_repository_config__weakptr(&config, repo) < 0) return -1; - error = repo_write_gitlink(path.ptr, git_repository_path(repo)); + error = repo_write_gitlink(path.ptr, git_repository_path(repo), false); /* passthrough error means gitlink is unnecessary */ if (error == GIT_PASSTHROUGH) diff --git a/src/submodule.c b/src/submodule.c index b1291df8e..ccc8ad117 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -306,6 +306,56 @@ void git_submodule_cache_free(git_repository *repo) submodule_cache_free(cache); } +static int submodule_repo_init( + git_repository **out, + git_repository *parent_repo, + const char *path, + const char *url, + bool use_gitlink) +{ + int error = 0; + git_buf workdir = GIT_BUF_INIT, repodir = GIT_BUF_INIT; + git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT; + git_repository *subrepo = NULL; + + error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path); + if (error < 0) + goto cleanup; + + initopt.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_NO_REINIT; + initopt.origin_url = url; + + /* init submodule repository and add origin remote as needed */ + + /* New style: sub-repo goes in <repo-dir>/modules/<name>/ with a + * gitlink in the sub-repo workdir directory to that repository + * + * Old style: sub-repo goes directly into repo/<name>/.git/ + */ + if (use_gitlink) { + error = git_buf_join3( + &repodir, '/', git_repository_path(parent_repo), "modules", path); + if (error < 0) + goto cleanup; + + initopt.workdir_path = workdir.ptr; + initopt.flags |= + GIT_REPOSITORY_INIT_NO_DOTGIT_DIR | + GIT_REPOSITORY_INIT_RELATIVE_GITLINK; + + error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt); + } else + error = git_repository_init_ext(&subrepo, workdir.ptr, &initopt); + +cleanup: + git_buf_free(&workdir); + git_buf_free(&repodir); + + *out = subrepo; + + return error; +} + int git_submodule_add_setup( git_submodule **out, git_repository *repo, @@ -317,7 +367,6 @@ int git_submodule_add_setup( git_config_backend *mods = NULL; git_submodule *sm = NULL; git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT; - git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT; git_repository *subrepo = NULL; assert(repo && url && path); @@ -371,41 +420,14 @@ int git_submodule_add_setup( if (error < 0) goto cleanup; - /* New style: sub-repo goes in <repo-dir>/modules/<name>/ with a - * gitlink in the sub-repo workdir directory to that repository - * - * Old style: sub-repo goes directly into repo/<name>/.git/ + /* if the repo does not already exist, then init a new repo and add it. + * Otherwise, just add the existing repo. */ - - initopt.flags = GIT_REPOSITORY_INIT_MKPATH | - GIT_REPOSITORY_INIT_NO_REINIT; - initopt.origin_url = real_url.ptr; - - if (git_path_exists(name.ptr) && - git_path_contains(&name, DOT_GIT)) - { - /* repo appears to already exist - reinit? */ - } - else if (use_gitlink) { - git_buf repodir = GIT_BUF_INIT; - - error = git_buf_join3( - &repodir, '/', git_repository_path(repo), "modules", path); - if (error < 0) + if (!(git_path_exists(name.ptr) && + git_path_contains(&name, DOT_GIT))) { + if ((error = submodule_repo_init(&subrepo, repo, path, real_url.ptr, use_gitlink)) < 0) goto cleanup; - - initopt.workdir_path = name.ptr; - initopt.flags |= GIT_REPOSITORY_INIT_NO_DOTGIT_DIR; - - error = git_repository_init_ext(&subrepo, repodir.ptr, &initopt); - - git_buf_free(&repodir); } - else { - error = git_repository_init_ext(&subrepo, name.ptr, &initopt); - } - if (error < 0) - goto cleanup; /* add submodule to hash and "reload" it */ @@ -437,6 +459,23 @@ cleanup: return error; } +int git_submodule_repo_init( + git_repository **out, + const git_submodule *sm, + int use_gitlink) +{ + int error; + git_repository *sub_repo = NULL; + + assert(out && sm); + + error = submodule_repo_init(&sub_repo, sm->repo, sm->path, sm->url, use_gitlink); + + *out = sub_repo; + + return error; +} + int git_submodule_add_finalize(git_submodule *sm) { int error; @@ -1897,6 +1936,7 @@ static void submodule_get_index_status(unsigned int *status, git_submodule *sm) *status |= GIT_SUBMODULE_STATUS_INDEX_MODIFIED; } + static void submodule_get_wd_status( unsigned int *status, git_submodule *sm, |