static int clone_internal( git_repository **out, const char *origin_url, const char *path, git_transfer_progress_callback fetch_progress_cb, void *fetch_progress_payload, git_checkout_opts *checkout_opts, bool is_bare) { int retcode = GIT_ERROR; git_repository *repo = NULL; if (!path_is_okay(path)) { return GIT_ERROR; } if (!(retcode = git_repository_init(&repo, path, is_bare))) { if ((retcode = setup_remotes_and_fetch(repo, origin_url, fetch_progress_cb, fetch_progress_payload)) < 0) { /* Failed to fetch; clean up */ git_repository_free(repo); git_futils_rmdir_r(path, NULL, GIT_DIRREMOVAL_FILES_AND_DIRS); } else { *out = repo; retcode = 0; } } if (!retcode && should_checkout(repo, is_bare, checkout_opts)) retcode = git_checkout_head(*out, checkout_opts); return retcode; }
static int checkout_branch(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature, const char *reflog_message) { int error; if (branch) error = update_head_to_branch(repo, git_remote_name(remote), branch, signature, reflog_message); /* Point HEAD to the same ref as the remote's head */ else error = update_head_to_remote(repo, remote, signature, reflog_message); if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts)) error = git_checkout_head(repo, co_opts); return error; }
int git_clone( git_repository **out, const char *url, const char *local_path, const git_clone_options *options) { int retcode = GIT_ERROR; git_repository *repo = NULL; git_clone_options normOptions; int remove_directory_on_failure = 0; assert(out && url && local_path); normalize_options(&normOptions, options); GITERR_CHECK_VERSION(&normOptions, GIT_CLONE_OPTIONS_VERSION, "git_clone_options"); if (!path_is_okay(local_path)) { return GIT_ERROR; } /* Only remove the directory on failure if we create it */ remove_directory_on_failure = !git_path_exists(local_path); if (!(retcode = git_repository_init(&repo, local_path, normOptions.bare))) { if ((retcode = setup_remotes_and_fetch(repo, url, &normOptions)) < 0) { /* Failed to fetch; clean up */ git_repository_free(repo); if (remove_directory_on_failure) git_futils_rmdir_r(local_path, NULL, GIT_RMDIR_REMOVE_FILES); else git_futils_cleanupdir_r(local_path); } else { *out = repo; retcode = 0; } } if (!retcode && should_checkout(repo, normOptions.bare, &normOptions.checkout_opts)) retcode = git_checkout_head(*out, &normOptions.checkout_opts); return retcode; }
int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch) { int error = 0, old_fetchhead; size_t nspecs; assert(repo && remote); if (!git_repository_is_empty(repo)) { giterr_set(GITERR_INVALID, "the repository is not empty"); return -1; } if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0) return error; old_fetchhead = git_remote_update_fetchhead(remote); git_remote_set_update_fetchhead(remote, 0); if ((error = git_remote_fetch(remote)) < 0) goto cleanup; if (branch) error = update_head_to_branch(repo, git_remote_name(remote), branch); /* Point HEAD to the same ref as the remote's head */ else error = update_head_to_remote(repo, remote); if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts)) error = git_checkout_head(repo, co_opts); cleanup: git_remote_set_update_fetchhead(remote, old_fetchhead); /* Remove the tags refspec */ nspecs = git_remote_refspec_count(remote); git_remote_remove_refspec(remote, nspecs); return error; }