简体   繁体   中英

Create NOT INITIAL commit using libgit2

Commit create without add files to commit.

  1. Init new repository (initNewRepo())
  2. Add files to index (addToIndex())
  3. Create initial commit (createInitilaCommit())
  4. Change some files
  5. Add files to index (addToIndex())
  6. Try create commit (commit())

Step 6 used method

void GitWizard::commit(const QString &textCommit)
{
    int error;
    git_oid commit_id, parentCommitId;
    git_tree *tree;
    git_commit *parent;
    git_signature *sig = nullptr;
    char oid_hex[GIT_OID_HEXSZ+1] = { 0 };

    qDebug("\n*Commit Writing*\n");

    error = git_signature_default(&sig, repo);
    checkForError(error, "Get default signature");

    error = git_reference_name_to_id(&parentCommitId, repo, "HEAD" );
    checkForError(error, "Reference to id");

    error = git_commit_lookup(&parent, repo, &parentCommitId );
    checkForError(error, "Commit lookup");

    error = git_commit_create_v(
                &commit_id, /* out id */
                repo,
                "HEAD", /* do not update the HEAD */
                sig,
                sig,
                "UTF-8", /* use default message encoding */
                "example commit",
                tree,
                1,
                parent);
    /**
     * Now we can take a look at the commit SHA we've generated.
     */
    if (!checkForError(error, "Add commit")) {
        git_oid_fmt(oid_hex, &commit_id);
        qDebug("New Commit: %s\n", oid_hex);
    }
    /**
     * Free all objects used in the meanwhile.
     */
    git_tree_free(tree);
    git_commit_free(parent);
    git_signature_free(sig);
}

void GitWizard::initNewRepo(const QString &dir)
{
    int error = git_repository_init(&repo, dir.toUtf8().constData(), false);
    if (!checkForError(error, QString("Init new repo in directory %1").arg(dir))) {
        mRepoPath = dir;
        error = git_repository_index(&idx, repo);
        checkForError(error, QString("Init index"));
    }
}

bool GitWizard::checkForError(int errorCode, QString action) const
{
    qDebug() << action;
    const git_error *error = giterr_last();
    if (!errorCode)
        return false;
    qCritical("Git Error %d <%s>: %s", errorCode, action.toUtf8().constData(),
              (error && error->message) ? error->message : "?");
    return true;
}

void GitWizard::addToIndex(const QList<QString> &files) {
    int filesSize = files.size();
    for (int i = 0; i < filesSize; i++) {
        addToIndex(files.at(i));
    }
    writeIndex();
}

void GitWizard::writeIndex()
{
    int error = git_index_write(idx);
    checkForError(error, QString("Write index to disk"));
}

void GitWizard::createInitialCommit()
{
    git_signature *sig = nullptr;
    git_oid tree_id, commit_id;
    git_tree *tree = nullptr;

    int error = git_signature_default(&sig, repo);
    if (!checkForError(error, "Get default signature")) {
        error = git_repository_index(&idx, repo);
    }
    if (!checkForError(error, "Open repository index")) {
        error = git_index_write_tree(&tree_id, idx);
    }
    if (!checkForError(error, "Look up initial tree")) {
        error = git_tree_lookup(&tree, repo, &tree_id);
    }
    if (!checkForError(error, "Write initial tree from index")) {
        error = git_commit_create_v(
                    &commit_id, repo, "HEAD", sig, sig,
                    nullptr, "Initial commit", tree, 0);
        if (!checkForError(error, "Create initail commit")) {
            getCurrentBranch();
        }
    }
    git_tree_free(tree);
    git_signature_free(sig);
}

"git log" result new commit

but changed files is not added to new commit, and "git status" show files as added to index as new files.

As I understand, need to correctly find the HEAD of the branch, which will be the parent commit for the created commit. This code works:

void GitWizard::commit(const QString &textCommit)
{
    int error;
    git_oid tree_id, commit_id, parentCommitId;
    git_tree *tree;
    git_commit *parent;
    git_signature *sig = nullptr;
    char oid_hex[GIT_OID_HEXSZ+1] = { 0 };

    qDebug("\n*Commit Writing*\n");

    error = git_signature_default(&sig, repo);
    checkForError(error, "Get default signature");

    error = git_index_write_tree(&tree_id, idx);
    checkForError(error, "Write tree");

    error = git_tree_lookup(&tree, repo, &tree_id);
    checkForError(error, "Tree lookup");

    error = git_reference_name_to_id(&parentCommitId, repo, "HEAD" );
    checkForError(error, "Reference to id");

    error = git_commit_lookup(&parent, repo, &parentCommitId );
    checkForError(error, "Commit lookup");

    error = git_commit_create_v(
                &commit_id, /* out id */
                repo,
                "HEAD", /* do not update the HEAD */
                sig,
                sig,
                "UTF-8", /* use default message encoding */
                textCommit.toUtf8().constData(),
                tree,
                1,
                parent);
    /**
     * Now we can take a look at the commit SHA we've generated.
     */
    if (!checkForError(error, "Add commit")) {
        git_oid_fmt(oid_hex, &commit_id);
        qDebug("New Commit: %s\n", oid_hex);
    }
    /**
     * Free all objects used in the meanwhile.
     */
    git_tree_free(tree);
    git_commit_free(parent);
    git_signature_free(sig);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM