mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Collect and convert git repo data to 'struct git_info'
We have this nasty habit of randomly passing down all the different things that we use to look up the local and remote git repository, and the information associated with it. Start collecting the data into a 'struct git_info' instead, so that it is easier to manage, and easier and more logical to just look up different parts of the puzzle. This is a fairly mechanical conversion, but has moved all the basic information collection to the 'is_git_repository()' function. That function no longer actually opens the repository (so the 'dry_run' argument is gone, and instead a successful 'is_git_repository()' is followed by 'opn_git_repository()' if you actually want the old non-dry_run semantics. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
acc4dc57af
commit
7e632173e0
11 changed files with 365 additions and 349 deletions
|
@ -1178,7 +1178,7 @@ static void create_commit_message(struct membuffer *msg, bool create_empty)
|
|||
SSRF_INFO("Commit message:\n\n%s\n", mb_cstring(msg));
|
||||
}
|
||||
|
||||
static int create_new_commit(git_repository *repo, const char *remote, const char *branch, git_oid *tree_id, bool create_empty)
|
||||
static int create_new_commit(struct git_info *info, git_oid *tree_id, bool create_empty)
|
||||
{
|
||||
int ret;
|
||||
git_reference *ref;
|
||||
|
@ -1188,19 +1188,19 @@ static int create_new_commit(git_repository *repo, const char *remote, const cha
|
|||
git_commit *commit;
|
||||
git_tree *tree;
|
||||
|
||||
ret = git_branch_lookup(&ref, repo, branch, GIT_BRANCH_LOCAL);
|
||||
ret = git_branch_lookup(&ref, info->repo, info->branch, GIT_BRANCH_LOCAL);
|
||||
switch (ret) {
|
||||
default:
|
||||
return report_error("Bad branch '%s' (%s)", branch, strerror(errno));
|
||||
return report_error("Bad branch '%s' (%s)", info->branch, strerror(errno));
|
||||
case GIT_EINVALIDSPEC:
|
||||
return report_error("Invalid branch name '%s'", branch);
|
||||
return report_error("Invalid branch name '%s'", info->branch);
|
||||
case GIT_ENOTFOUND: /* We'll happily create it */
|
||||
ref = NULL;
|
||||
parent = try_to_find_parent(saved_git_id, repo);
|
||||
parent = try_to_find_parent(saved_git_id, info->repo);
|
||||
break;
|
||||
case 0:
|
||||
if (git_reference_peel(&parent, ref, GIT_OBJ_COMMIT))
|
||||
return report_error("Unable to look up parent in branch '%s'", branch);
|
||||
return report_error("Unable to look up parent in branch '%s'", info->branch);
|
||||
|
||||
if (saved_git_id) {
|
||||
if (existing_filename && verbose)
|
||||
|
@ -1208,7 +1208,7 @@ static int create_new_commit(git_repository *repo, const char *remote, const cha
|
|||
const git_oid *id = git_commit_id((const git_commit *) parent);
|
||||
/* if we are saving to the same git tree we got this from, let's make
|
||||
* sure there is no confusion */
|
||||
if (same_string(existing_filename, remote) && git_oid_strcmp(id, saved_git_id))
|
||||
if (same_string(existing_filename, info->url) && git_oid_strcmp(id, saved_git_id))
|
||||
return report_error("The git branch does not match the git parent of the source");
|
||||
}
|
||||
|
||||
|
@ -1216,10 +1216,10 @@ static int create_new_commit(git_repository *repo, const char *remote, const cha
|
|||
break;
|
||||
}
|
||||
|
||||
if (git_tree_lookup(&tree, repo, tree_id))
|
||||
if (git_tree_lookup(&tree, info->repo, tree_id))
|
||||
return report_error("Could not look up newly created tree");
|
||||
|
||||
if (get_authorship(repo, &author))
|
||||
if (get_authorship(info->repo, &author))
|
||||
return report_error("No user name configuration in git repo");
|
||||
|
||||
/* If the parent commit has the same tree ID, do not create a new commit */
|
||||
|
@ -1235,13 +1235,13 @@ static int create_new_commit(git_repository *repo, const char *remote, const cha
|
|||
struct membuffer commit_msg = { 0 };
|
||||
|
||||
create_commit_message(&commit_msg, create_empty);
|
||||
if (git_commit_create_v(&commit_id, repo, NULL, author, author, NULL, mb_cstring(&commit_msg), tree, parent != NULL, parent)) {
|
||||
if (git_commit_create_v(&commit_id, info->repo, NULL, author, author, NULL, mb_cstring(&commit_msg), tree, parent != NULL, parent)) {
|
||||
git_signature_free(author);
|
||||
return report_error("Git commit create failed (%s)", strerror(errno));
|
||||
}
|
||||
free_buffer(&commit_msg);
|
||||
|
||||
if (git_commit_lookup(&commit, repo, &commit_id)) {
|
||||
if (git_commit_lookup(&commit, info->repo, &commit_id)) {
|
||||
git_signature_free(author);
|
||||
return report_error("Could not look up newly created commit");
|
||||
}
|
||||
|
@ -1250,8 +1250,8 @@ static int create_new_commit(git_repository *repo, const char *remote, const cha
|
|||
git_signature_free(author);
|
||||
|
||||
if (!ref) {
|
||||
if (git_branch_create(&ref, repo, branch, commit, 0))
|
||||
return report_error("Failed to create branch '%s'", branch);
|
||||
if (git_branch_create(&ref, info->repo, info->branch, commit, 0))
|
||||
return report_error("Failed to create branch '%s'", info->branch);
|
||||
}
|
||||
/*
|
||||
* If it's a checked-out branch, try to also update the working
|
||||
|
@ -1260,17 +1260,17 @@ static int create_new_commit(git_repository *repo, const char *remote, const cha
|
|||
* the object database), but it can cause extreme confusion, so
|
||||
* warn about it.
|
||||
*/
|
||||
if (git_branch_is_head(ref) && !git_repository_is_bare(repo)) {
|
||||
if (update_git_checkout(repo, parent, tree)) {
|
||||
if (git_branch_is_head(ref) && !git_repository_is_bare(info->repo)) {
|
||||
if (update_git_checkout(info->repo, parent, tree)) {
|
||||
const git_error *err = giterr_last();
|
||||
const char *errstr = err ? err->message : strerror(errno);
|
||||
report_error("Git branch '%s' is checked out, but worktree is dirty (%s)",
|
||||
branch, errstr);
|
||||
info->branch, errstr);
|
||||
}
|
||||
}
|
||||
|
||||
if (git_reference_set_target(&ref, ref, &commit_id, "Subsurface save event"))
|
||||
return report_error("Failed to update branch '%s'", branch);
|
||||
return report_error("Failed to update branch '%s'", info->branch);
|
||||
|
||||
/*
|
||||
* if this was the empty commit to initialize a new repo, don't remember the
|
||||
|
@ -1312,12 +1312,15 @@ static int write_git_tree(git_repository *repo, struct dir *tree, git_oid *resul
|
|||
return ret;
|
||||
}
|
||||
|
||||
int do_git_save(git_repository *repo, const char *branch, const char *remote, bool select_only, bool create_empty)
|
||||
int do_git_save(struct git_info *info, bool select_only, bool create_empty)
|
||||
{
|
||||
struct dir tree;
|
||||
git_oid id;
|
||||
bool cached_ok;
|
||||
|
||||
if (!info->repo)
|
||||
return report_error("Unable to open git repository '%s[%s]'", info->url, info->branch);
|
||||
|
||||
if (verbose)
|
||||
SSRF_INFO("git storage: do git save\n");
|
||||
|
||||
|
@ -1328,43 +1331,66 @@ int do_git_save(git_repository *repo, const char *branch, const char *remote, bo
|
|||
* Check if we can do the cached writes - we need to
|
||||
* have the original git commit we loaded in the repo
|
||||
*/
|
||||
cached_ok = try_to_find_parent(saved_git_id, repo);
|
||||
cached_ok = try_to_find_parent(saved_git_id, info->repo);
|
||||
|
||||
/* Start with an empty tree: no subdirectories, no files */
|
||||
tree.name[0] = 0;
|
||||
tree.subdirs = NULL;
|
||||
if (git_treebuilder_new(&tree.files, repo, NULL))
|
||||
if (git_treebuilder_new(&tree.files, info->repo, NULL))
|
||||
return report_error("git treebuilder failed");
|
||||
|
||||
if (!create_empty)
|
||||
/* Populate our tree data structure */
|
||||
if (create_git_tree(repo, &tree, select_only, cached_ok))
|
||||
if (create_git_tree(info->repo, &tree, select_only, cached_ok))
|
||||
return -1;
|
||||
|
||||
if (verbose)
|
||||
SSRF_INFO("git storage, write git tree\n");
|
||||
|
||||
if (write_git_tree(repo, &tree, &id))
|
||||
if (write_git_tree(info->repo, &tree, &id))
|
||||
return report_error("git tree write failed");
|
||||
|
||||
/* And save the tree! */
|
||||
if (create_new_commit(repo, remote, branch, &id, create_empty))
|
||||
if (create_new_commit(info, &id, create_empty))
|
||||
return report_error("creating commit failed");
|
||||
|
||||
/* now sync the tree with the remote server */
|
||||
if (remote && !git_local_only)
|
||||
return sync_with_remote(repo, remote, branch, url_to_remote_transport(remote));
|
||||
if (info->url && !git_local_only)
|
||||
return sync_with_remote(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_save_dives(struct git_repository *repo, const char *branch, const char *remote, bool select_only)
|
||||
int git_save_dives(struct git_info *info, bool select_only)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (repo == dummy_git_repository)
|
||||
return report_error("Unable to open git repository '%s'", branch);
|
||||
ret = do_git_save(repo, branch, remote, select_only, false);
|
||||
git_repository_free(repo);
|
||||
free((void *)branch);
|
||||
/*
|
||||
* FIXME!! This open_git_repository() will
|
||||
* sync with the cloud. That is NOT what
|
||||
* we actually want to do here. We want
|
||||
* to just open the local repo, and then
|
||||
* sync with the clound after having saved.
|
||||
*
|
||||
* NOTE! The "we already have a repo" case
|
||||
* case is fairly easy (we can just treat
|
||||
* it as a local repository and open it
|
||||
* as-is). But the "need to create it by
|
||||
* cloning" case is what we currently also
|
||||
* do in 'open_git_repository()', and that
|
||||
* all needs to be thought about a lot.
|
||||
*
|
||||
* Do we want to have the rule that you
|
||||
* can't save to a git repo unless you first
|
||||
* opened it for reading, and make all that
|
||||
* complexity be a load-time thing? That
|
||||
* would make the saving rules be very clear
|
||||
* and simple.
|
||||
*/
|
||||
if (!open_git_repository(info))
|
||||
report_error(translate("gettextFromC", "Failed to save dives to %s[%s] (%s)"), info->url, info->branch, strerror(errno));
|
||||
|
||||
ret = do_git_save(info, select_only, false);
|
||||
git_repository_free(info->repo);
|
||||
free((void *)info->branch);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue