6

I have a Git repository with the following git log information in master:

commit 23c5565d156266f3e26943d0811abaa88f7957a1 (HEAD -> master)

    Fourth commit.

commit 92c0d491c3fd537a06876d1c0fc69c27ebf3e935

    Third commit.

commit 67d604623f1b7fd8492f42edd6aebda83b075173

    Second commit.

commit 11ef1cc228c27c87771dbc1a6a3fa98b7a605fa5

    First commit.

commit 946f4fb2a02042f450090414eee6324799eb35df

    Initial commit

Using libgit2 I want to perform a rebase where I squash the top four commits together (23c556 - 11ef1) and leave the initial commit intact. I aim to solve this by rebasing the master branch onto commit 946f4, picking the first commit, and then squashing the other three. This would be similar to git rebase -i HEAD~4 with the squash command on the last three commits.

This is pseudocode that I wrote to try and solve this:

git_rebase_init( &rebase, m_repository, branch, nullptr, initialCommit, &opts );

bool shouldSquash = false;
git_oid rebaseOID = {{0}};
while ( git_rebase_next( &op, rebase ) == GIT_OK )
{
    if ( shouldSquash )
    {
        op->type = GIT_REBASE_OPERATION_SQUASH;
    }
    else
    {
        op->type = GIT_REBASE_OPERATION_PICK;
        shouldSquash = true;
    }

    git_signature * author = generateSignature();
    if ( !author ) return false;

    git_rebase_commit( &rebaseOID, rebase, author, author, nullptr, nullptr );
}

git_rebase_finish( rebase, nullptr );

Unfortunately while the rebase completes, none of the commits are squashed. They each appear as they did in the log above except they have different commit hashes.

Bryan Muscedere
  • 572
  • 2
  • 10
  • 23
  • 2
    Can you do it by the equivalents of `git reset --soft HEAD~4` and then `git commit -m "Squash"`? – eftshift0 Dec 06 '19 at 19:46
  • Doing the `git reset --soft ...` equivalent in libgit2 would work in this example but wouldn't work if I wanted to pick `Fourth commit.` and squash the other three commits (if that makes sense). – Bryan Muscedere Dec 06 '19 at 19:57
  • I don't know the libgtk2 api so I can't really know.... but "pick the last, squash the other 3" is exactly what people would do on an interactive rebase to squash the last 4 revisions, that is on plain vanilla git... which is what I do with git reset --soft and then commit. – eftshift0 Dec 06 '19 at 20:02
  • Sorry, I'm not really being clear. What I want is a way to squash `N` contiguous commits in a commit range on a branch. The other commits in that range will be picked. So for instance, squash commit SHAs `67d60` and `11ef1` together while leaving the others intact as their own commits. In vanilla Git could I still do this with `git reset --soft ...`? – Bryan Muscedere Dec 06 '19 at 20:09
  • Nope, not really. `git reset--soft` will move the **branch pointer** (of the branch you are working on... **HEAD** if on detached HEAD) wherever you want without touching the working tree..... so, if you want to squash the last 5 commits, this is one way to go... but if you wanted to squash the 4 revisions before the last 2 and pick those last 2, then you will need more than one command.. like `git checkout HEAD~2 && git reset --soft HEAD~4 && git commit -m "Squash" && git cherry-pick the-branch~2..the-branch`... but that's on vanilla git. Don't know what you can pull off from libgit2's API. – eftshift0 Dec 06 '19 at 20:18

0 Answers0