void test_refs_branches_create__default_reflog_message(void) { git_reflog *log; const git_reflog_entry *entry; git_signature *sig; git_config *cfg; cl_git_pass(git_repository_config(&cfg, repo)); cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar")); cl_git_pass(git_config_set_string(cfg, "user.email", "*****@*****.**")); git_config_free(cfg); cl_git_pass(git_signature_default(&sig, repo)); retrieve_known_commit(&target, repo); cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false, NULL, NULL)); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); entry = git_reflog_entry_byindex(log, 0); cl_assert_equal_s("Branch: created", git_reflog_entry_message(entry)); cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); git_reflog_free(log); git_signature_free(sig); }
static void action_create_tag(tag_state *state) { git_repository *repo = state->repo; tag_options *opts = state->opts; git_signature *tagger; git_oid oid; git_object *target; check(!opts->tag_name, "Name required"); check(!opts->message, "Message required"); if (!opts->target) opts->target = "HEAD"; check_lg2(git_revparse_single(&target, repo, opts->target), "Unable to resolve spec", opts->target); check_lg2(git_signature_default(&tagger, repo), "Unable to create signature", NULL); check_lg2(git_tag_create(&oid, repo, opts->tag_name, target, tagger, opts->message, opts->force), "Unable to create tag", NULL); git_object_free(target); git_signature_free(tagger); }
int git_reference_rename( git_reference **out, git_reference *ref, const char *new_name, int force, const git_signature *signature, const char *log_message) { git_signature *who = (git_signature*)signature; int error; /* Should we return an error if there is no default? */ if (!who && ((error = git_signature_default(&who, ref->db->repo)) < 0) && ((error = git_signature_now(&who, "unknown", "unknown")) < 0)) { return error; } error = reference__rename(out, ref, new_name, force, who, log_message); if (!signature) git_signature_free(who); return error; }
PyObject * Repository_default_signature__get__(Repository *self) { git_signature *sig; int err; if ((err = git_signature_default(&sig, self->repo)) < 0) return Error_set(err); return build_signature(NULL, sig, "utf-8"); }
int git_reference__log_signature(git_signature **out, git_repository *repo) { int error; git_signature *who; if(((error = git_signature_default(&who, repo)) < 0) && ((error = git_signature_now(&who, "unknown", "unknown")) < 0)) return error; *out = who; return 0; }
git_signature *rugged_signature_get(VALUE rb_sig, git_repository *repo) { int error; VALUE rb_time, rb_unix_t, rb_offset, rb_name, rb_email, rb_time_offset; git_signature *sig; if (NIL_P(rb_sig)) { rugged_exception_check( git_signature_default(&sig, repo) ); return sig; } Check_Type(rb_sig, T_HASH); rb_name = rb_hash_aref(rb_sig, CSTR2SYM("name")); rb_email = rb_hash_aref(rb_sig, CSTR2SYM("email")); rb_time = rb_hash_aref(rb_sig, CSTR2SYM("time")); rb_time_offset = rb_hash_aref(rb_sig, CSTR2SYM("time_offset")); Check_Type(rb_name, T_STRING); Check_Type(rb_email, T_STRING); if (NIL_P(rb_time)) { error = git_signature_now(&sig, StringValueCStr(rb_name), StringValueCStr(rb_email)); } else { if (!rb_obj_is_kind_of(rb_time, rb_cTime)) rb_raise(rb_eTypeError, "expected Time object"); rb_unix_t = rb_funcall(rb_time, rb_intern("tv_sec"), 0); if (NIL_P(rb_time_offset)) { rb_offset = rb_funcall(rb_time, rb_intern("utc_offset"), 0); } else { Check_Type(rb_time_offset, T_FIXNUM); rb_offset = rb_time_offset; } error = git_signature_new(&sig, StringValueCStr(rb_name), StringValueCStr(rb_email), NUM2LONG(rb_unix_t), FIX2INT(rb_offset) / 60); } rugged_exception_check(error); return sig; }
void QGit::signature() { git_repository *repo = nullptr; git_signature *me = nullptr; QString email; QString name; int res = 0; QGitError error; try { res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData()); if (res) { throw QGitError("git_repository_open", res); } res = git_signature_default(&me, repo); if (res) { throw QGitError("git_signature_default", res); } name = QString::fromUtf8(me->name); email = QString::fromUtf8(me->email); } catch(const QGitError & ex) { error = ex; } emit signatureReply(name, email, error); if (me) { git_signature_free(me); me = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } }
void test_refs_branches_create__default_reflog_message(void) { git_reflog *log; git_buf buf = GIT_BUF_INIT; const git_reflog_entry *entry; git_annotated_commit *annotated; git_signature *sig; git_config *cfg; cl_git_pass(git_repository_config(&cfg, repo)); cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar")); cl_git_pass(git_config_set_string(cfg, "user.email", "*****@*****.**")); git_config_free(cfg); cl_git_pass(git_signature_default(&sig, repo)); retrieve_known_commit(&target, repo); cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false)); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); entry = git_reflog_entry_byindex(log, 0); cl_git_pass(git_buf_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target)))); cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry)); cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); cl_git_pass(git_reference_remove(repo, "refs/heads/" NEW_BRANCH_NAME)); git_reference_free(branch); git_reflog_free(log); git_buf_clear(&buf); cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "e90810b8df3")); cl_git_pass(git_branch_create_from_annotated(&branch, repo, NEW_BRANCH_NAME, annotated, true)); cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); entry = git_reflog_entry_byindex(log, 0); cl_git_pass(git_buf_printf(&buf, "branch: Created from e90810b8df3")); cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry)); cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); git_annotated_commit_free(annotated); git_buf_free(&buf); git_reflog_free(log); git_signature_free(sig); }
static int rebase_copy_note( git_rebase *rebase, const char *notes_ref, git_oid *from, git_oid *to, const git_signature *committer) { git_note *note = NULL; git_oid note_id; git_signature *who = NULL; int error; if ((error = git_note_read(¬e, rebase->repo, notes_ref, from)) < 0) { if (error == GIT_ENOTFOUND) { giterr_clear(); error = 0; } goto done; } if (!committer) { if((error = git_signature_default(&who, rebase->repo)) < 0) { if (error != GIT_ENOTFOUND || (error = git_signature_now(&who, "unknown", "unknown")) < 0) goto done; giterr_clear(); } committer = who; } error = git_note_create(¬e_id, rebase->repo, notes_ref, git_note_author(note), committer, to, git_note_message(note), 0); done: git_note_free(note); git_signature_free(who); return error; }
bool QGit::gitRepositoryDefaultSignature(const QDir &path, QString &name, QString &email) { git_repository *repo = nullptr; git_signature *me = nullptr; int result = 0; bool ret = false; result = git_repository_open(&repo, path.absolutePath().toUtf8().constData()); if (result) { goto cleanup; } result = git_signature_default(&me, repo); if (result) { goto cleanup; } name = me->name; email = me->email; ret = true; cleanup: if (me) { git_signature_free(me); me = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } return ret; }
void test_repo_init__init_with_initial_commit(void) { git_index *index; cl_set_cleanup(&cleanup_repository, "committed"); /* Initialize the repository */ cl_git_pass(git_repository_init(&_repo, "committed", 0)); /* Index will be automatically created when requested for a new repo */ cl_git_pass(git_repository_index(&index, _repo)); /* Create a file so we can commit it * * If you are writing code outside the test suite, you can create this * file any way that you like, such as: * FILE *fp = fopen("committed/file.txt", "w"); * fputs("some stuff\n", fp); * fclose(fp); * We like to use the help functions because they do error detection * in a way that's easily compatible with our test suite. */ cl_git_mkfile("committed/file.txt", "some stuff\n"); /* Add file to the index */ cl_git_pass(git_index_add_bypath(index, "file.txt")); cl_git_pass(git_index_write(index)); /* Intentionally not using cl_repo_commit_from_index here so this code * can be used as an example of how an initial commit is typically * made to a repository... */ /* Make sure we're ready to use git_signature_default :-) */ { git_config *cfg, *local; cl_git_pass(git_repository_config(&cfg, _repo)); cl_git_pass(git_config_open_level(&local, cfg, GIT_CONFIG_LEVEL_LOCAL)); cl_git_pass(git_config_set_string(local, "user.name", "Test User")); cl_git_pass(git_config_set_string(local, "user.email", "*****@*****.**")); git_config_free(local); git_config_free(cfg); } /* Create a commit with the new contents of the index */ { git_signature *sig; git_oid tree_id, commit_id; git_tree *tree; cl_git_pass(git_signature_default(&sig, _repo)); cl_git_pass(git_index_write_tree(&tree_id, index)); cl_git_pass(git_tree_lookup(&tree, _repo, &tree_id)); cl_git_pass(git_commit_create_v( &commit_id, _repo, "HEAD", sig, sig, NULL, "First", tree, 0)); git_tree_free(tree); git_signature_free(sig); } git_index_free(index); }
static int try_to_git_merge(git_repository *repo, git_reference *local, git_reference *remote, git_oid *base, const git_oid *local_id, const git_oid *remote_id) { git_tree *local_tree, *remote_tree, *base_tree; git_commit *local_commit, *remote_commit, *base_commit; git_index *merged_index; git_merge_options merge_options; if (verbose) { char outlocal[41], outremote[41]; outlocal[40] = outremote[40] = 0; git_oid_fmt(outlocal, local_id); git_oid_fmt(outremote, remote_id); fprintf(stderr, "trying to merge local SHA %s remote SHA %s\n", outlocal, outremote); } git_merge_init_options(&merge_options, GIT_MERGE_OPTIONS_VERSION); #ifdef USE_LIBGIT23_API merge_options.tree_flags = GIT_MERGE_TREE_FIND_RENAMES; #else merge_options.flags = GIT_MERGE_TREE_FIND_RENAMES; #endif merge_options.file_favor = GIT_MERGE_FILE_FAVOR_UNION; merge_options.rename_threshold = 100; if (git_commit_lookup(&local_commit, repo, local_id)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: can't get commit (%s)"), giterr_last()->message); if (git_commit_tree(&local_tree, local_commit)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: failed local tree lookup (%s)"), giterr_last()->message); if (git_commit_lookup(&remote_commit, repo, remote_id)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: can't get commit (%s)"), giterr_last()->message); if (git_commit_tree(&remote_tree, remote_commit)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: failed remote tree lookup (%s)"), giterr_last()->message); if (git_commit_lookup(&base_commit, repo, base)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: can't get commit: (%s)"), giterr_last()->message); if (git_commit_tree(&base_tree, base_commit)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: failed base tree lookup: (%s)"), giterr_last()->message); if (git_merge_trees(&merged_index, repo, base_tree, local_tree, remote_tree, &merge_options)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: merge failed (%s)"), giterr_last()->message); if (git_index_has_conflicts(merged_index)) { int error; const git_index_entry *ancestor = NULL, *ours = NULL, *theirs = NULL; git_index_conflict_iterator *iter = NULL; error = git_index_conflict_iterator_new(&iter, merged_index); while (git_index_conflict_next(&ancestor, &ours, &theirs, iter) != GIT_ITEROVER) { /* Mark this conflict as resolved */ fprintf(stderr, "conflict in %s / %s / %s -- ", ours ? ours->path : "-", theirs ? theirs->path : "-", ancestor ? ancestor->path : "-"); if ((!ours && theirs && ancestor) || (ours && !theirs && ancestor)) { // the file was removed on one side or the other - just remove it fprintf(stderr, "looks like a delete on one side; removing the file from the index\n"); error = git_index_remove(merged_index, ours ? ours->path : theirs->path, GIT_INDEX_STAGE_ANY); } else { error = git_index_conflict_remove(merged_index, ours ? ours->path : theirs ? theirs->path : ancestor->path); } if (error) { fprintf(stderr, "error at conflict resplution (%s)", giterr_last()->message); } } git_index_conflict_cleanup(merged_index); git_index_conflict_iterator_free(iter); report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: merge conflict - manual intervention needed")); } git_oid merge_oid, commit_oid; git_tree *merged_tree; git_signature *author; git_commit *commit; if (git_index_write_tree_to(&merge_oid, merged_index, repo)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: writing the tree failed (%s)"), giterr_last()->message); if (git_tree_lookup(&merged_tree, repo, &merge_oid)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: tree lookup failed (%s)"), giterr_last()->message); if (git_signature_default(&author, repo) < 0) return report_error(translate("gettextFromC", "Failed to get author: (%s)"), giterr_last()->message); if (git_commit_create_v(&commit_oid, repo, NULL, author, author, NULL, "automatic merge", merged_tree, 2, local_commit, remote_commit)) return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: git commit create failed (%s)"), giterr_last()->message); if (git_commit_lookup(&commit, repo, &commit_oid)) return report_error(translate("gettextFromC", "Error: could not lookup the merge commit I just created (%s)"), giterr_last()->message); if (git_branch_is_head(local) && !git_repository_is_bare(repo)) { git_object *parent; git_reference_peel(&parent, local, GIT_OBJ_COMMIT); if (update_git_checkout(repo, parent, merged_tree)) { report_error("Warning: checked out branch is inconsistent with git data"); } } if (git_reference_set_target(&local, local, &commit_oid, "Subsurface merge event")) return report_error("Error: failed to update branch (%s)", giterr_last()->message); set_git_id(&commit_oid); git_signature_free(author); return 0; }
static int try_to_git_merge(git_repository *repo, git_reference **local_p, git_reference *remote, git_oid *base, const git_oid *local_id, const git_oid *remote_id) { UNUSED(remote); git_tree *local_tree, *remote_tree, *base_tree; git_commit *local_commit, *remote_commit, *base_commit; git_index *merged_index; git_merge_options merge_options; if (verbose) { char outlocal[41], outremote[41]; outlocal[40] = outremote[40] = 0; git_oid_fmt(outlocal, local_id); git_oid_fmt(outremote, remote_id); fprintf(stderr, "trying to merge local SHA %s remote SHA %s\n", outlocal, outremote); } git_merge_init_options(&merge_options, GIT_MERGE_OPTIONS_VERSION); #if !LIBGIT2_VER_MAJOR && LIBGIT2_VER_MINOR > 23 merge_options.flags = GIT_MERGE_FIND_RENAMES; #else merge_options.tree_flags = GIT_MERGE_TREE_FIND_RENAMES; #endif merge_options.file_favor = GIT_MERGE_FILE_FAVOR_UNION; merge_options.rename_threshold = 100; if (git_commit_lookup(&local_commit, repo, local_id)) { fprintf(stderr, "Remote storage and local data diverged. Error: can't get commit (%s)", giterr_last()->message); goto diverged_error; } if (git_commit_tree(&local_tree, local_commit)) { fprintf(stderr, "Remote storage and local data diverged. Error: failed local tree lookup (%s)", giterr_last()->message); goto diverged_error; } if (git_commit_lookup(&remote_commit, repo, remote_id)) { fprintf(stderr, "Remote storage and local data diverged. Error: can't get commit (%s)", giterr_last()->message); goto diverged_error; } if (git_commit_tree(&remote_tree, remote_commit)) { fprintf(stderr, "Remote storage and local data diverged. Error: failed local tree lookup (%s)", giterr_last()->message); goto diverged_error; } if (git_commit_lookup(&base_commit, repo, base)) { fprintf(stderr, "Remote storage and local data diverged. Error: can't get commit (%s)", giterr_last()->message); goto diverged_error; } if (git_commit_tree(&base_tree, base_commit)) { fprintf(stderr, "Remote storage and local data diverged. Error: failed base tree lookup (%s)", giterr_last()->message); goto diverged_error; } if (git_merge_trees(&merged_index, repo, base_tree, local_tree, remote_tree, &merge_options)) { fprintf(stderr, "Remote storage and local data diverged. Error: merge failed (%s)", giterr_last()->message); // this is the one where I want to report more detail to the user - can't quite explain why return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: merge failed (%s)"), giterr_last()->message); } if (git_index_has_conflicts(merged_index)) { int error; const git_index_entry *ancestor = NULL, *ours = NULL, *theirs = NULL; git_index_conflict_iterator *iter = NULL; error = git_index_conflict_iterator_new(&iter, merged_index); while (git_index_conflict_next(&ancestor, &ours, &theirs, iter) != GIT_ITEROVER) { /* Mark this conflict as resolved */ fprintf(stderr, "conflict in %s / %s / %s -- ", ours ? ours->path : "-", theirs ? theirs->path : "-", ancestor ? ancestor->path : "-"); if ((!ours && theirs && ancestor) || (ours && !theirs && ancestor)) { // the file was removed on one side or the other - just remove it fprintf(stderr, "looks like a delete on one side; removing the file from the index\n"); error = git_index_remove(merged_index, ours ? ours->path : theirs->path, GIT_INDEX_STAGE_ANY); } else if (ancestor) { error = git_index_conflict_remove(merged_index, ours ? ours->path : theirs ? theirs->path : ancestor->path); } if (error) { fprintf(stderr, "error at conflict resplution (%s)", giterr_last()->message); } } git_index_conflict_cleanup(merged_index); git_index_conflict_iterator_free(iter); report_error(translate("gettextFromC", "Remote storage and local data diverged. Cannot combine local and remote changes")); } git_oid merge_oid, commit_oid; git_tree *merged_tree; git_signature *author; git_commit *commit; if (git_index_write_tree_to(&merge_oid, merged_index, repo)) goto write_error; if (git_tree_lookup(&merged_tree, repo, &merge_oid)) goto write_error; if (git_signature_default(&author, repo) < 0) if (git_signature_now(&author, "Subsurface", "noemail@given") < 0) goto write_error; if (git_commit_create_v(&commit_oid, repo, NULL, author, author, NULL, "automatic merge", merged_tree, 2, local_commit, remote_commit)) goto write_error; if (git_commit_lookup(&commit, repo, &commit_oid)) goto write_error; if (git_branch_is_head(*local_p) && !git_repository_is_bare(repo)) { git_object *parent; git_reference_peel(&parent, *local_p, GIT_OBJ_COMMIT); if (update_git_checkout(repo, parent, merged_tree)) { goto write_error; } } if (git_reference_set_target(local_p, *local_p, &commit_oid, "Subsurface merge event")) goto write_error; set_git_id(&commit_oid); git_signature_free(author); if (verbose) fprintf(stderr, "Successfully merged repositories"); return 0; diverged_error: return report_error(translate("gettextFromC", "Remote storage and local data diverged")); write_error: return report_error(translate("gettextFromC", "Remote storage and local data diverged. Error: writing the data failed (%s)"), giterr_last()->message); }
void QGit::stashSave(QString name) { git_repository *repo = nullptr; git_reference *head = nullptr; //git_commit *commit = nullptr; git_signature *me = nullptr; //git_index *index = nullptr; git_oid *oid = nullptr; QStringList stashes; int res = 0; QGitError error; try { res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData()); if (res) { throw QGitError("git_repository_open", res); } res = git_signature_default(&me, repo); if (res) { throw QGitError("git_signature_default", res); } res = git_repository_head(&head, repo); if (res) { throw QGitError("git_repository_head", res); } // TODO: Check if we have memory leak here! oid = const_cast<git_oid *>(git_reference_target(head)); if (!oid) { throw QGitError("git_reference_target returned NULL", 0); } res = git_stash_save(oid, repo, me, name.toUtf8().constData(), 0); if (res) { throw QGitError("git_stash_save", res); } } catch(const QGitError &ex) { error = ex; } emit stashSaveReply(error); if (oid) { // TODO: Check if we need to free memory here! //git_oid_shorten_free(); oid = nullptr; } if (head) { git_reference_delete(head); head = nullptr; } if (me) { git_signature_free(me); me = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } }
void QGit::commit(QString message) { git_repository *repo = nullptr; git_signature *me = nullptr; git_commit *parent = nullptr; git_index *index = nullptr; git_tree *tree = nullptr; git_oid new_commit_id = { {0} }; git_oid parent_id = { {0} }; git_oid tree_id = { {0} }; git_object *git_obj = nullptr; git_diff *diff = nullptr; size_t _count = 0; int unborn = 0; int res = 0; QGitError error; try { res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData()); if (res) { throw QGitError("git_repository_open", res); } /// Check if somthing is staged res = git_revparse_single(&git_obj, repo, "HEAD^{tree}"); if (res) { throw QGitError("git_revparse_single(staged)", res); } res = git_tree_lookup(&tree, repo, git_object_id(git_obj)); if (res) { throw QGitError("git_tree_lookup(staged)", res); } res = git_diff_tree_to_index(&diff, repo, tree, nullptr, nullptr); if (res) { throw QGitError("git_diff_tree_to_index(staged)", res); } _count = git_diff_num_deltas(diff); if (_count == 0) { throw QGitError("Nothing staged.", res); } if (tree) { git_tree_free(tree); tree = nullptr; } /// Check end res = git_signature_default(&me, repo); if (res) { throw QGitError("git_signature_default", res); } res = git_repository_index(&index, repo); if (res) { throw QGitError("git_repository_index", res); } res = git_index_write_tree(&tree_id, index); if (res) { throw QGitError("git_index_write_tree", res); } res = git_tree_lookup(&tree, repo, &tree_id); if (res) { throw QGitError("git_tree_lookup", res); } unborn = git_repository_head_unborn(repo); if (unborn) { res = git_commit_create_v( &new_commit_id, repo, "HEAD", /* name of ref to update */ me, /* author */ me, /* committer */ nullptr, /* nullptr = UTF-8 message encoding */ message.toUtf8().constData(), /* message */ tree, /* root tree */ 0); /* parent count */ if (res) { throw QGitError("git_commit_create_v", res); } } else { res = git_reference_name_to_id(&parent_id, repo, "HEAD"); if (res) { throw QGitError("git_reference_name_to_id", res); } res = git_commit_lookup(&parent, repo, &parent_id); if (res) { throw QGitError("git_commit_lookup", res); } res = git_commit_create_v( &new_commit_id, repo, "HEAD", /* name of ref to update */ me, /* author */ me, /* committer */ nullptr, /* nullptr = UTF-8 message encoding */ message.toUtf8().constData(), /* message */ tree, /* root tree */ 1, /* parent count */ parent); /* parent */ if (res) { throw QGitError("git_commit_create_v", res); } } } catch(const QGitError &ex) { error = ex; } emit commitReply(QString::fromUtf8(reinterpret_cast<const char *>(new_commit_id.id)), error); if (parent) { git_commit_free(parent); parent = nullptr; } if (index) { git_index_free(index); index = nullptr; } if (tree) { git_tree_free(tree); tree = nullptr; } if (me) { git_signature_free(me); me = nullptr; } if (diff) { git_diff_free(diff); diff = nullptr; } if (git_obj) { git_object_free(git_obj); git_obj = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } }