Joff
Joff

Reputation: 12187

git: cleanup or delete commit to cleanup the commit history

The docs and searching is just confusing me about what to do to cleanup a commit history.

Say I have a branch called tests that I use to push builds to travis-ci and I have a build failing. I would then have to make some small commits to try to fix the error message and re-push the tests branch.

This could lead to a chain of small and nearly pointless commits that I do not really want to make, but I am forced to nonetheless. How would I compact these into one commit? I think rebase is what I am looking for but I am confused about a few things.

If I use squash, I find that I run into a ton of merge conflicts that I have to then go and solve manually.

I think the solution may be to just delete the commits, but then I am not sure if I will be deleting some history that my final "working" commit needs.

Say my commit history looks like this:

commit1: some new feature
commit2: crap, builds failing, trying fix
commit3: more build attempts
commit4: Ahh I think I got it this time
commit5: ok finally fixed, build passing

Now I would essentially like to have only one commit to merge back into the master. What would you do here that isn't going to lead to merge conflicts?

Upvotes: 3

Views: 5876

Answers (3)

Vinay Veluri
Vinay Veluri

Reputation: 6855

Git Squash works with merging of commits to one.

As all mentioned, git rebase -i HEAD~n replace n with number of commits you wish to squash and force push the changes if required.

Ideally, a commit is made when it is required to be noted and the trails made. Commit history plays important role in rebase, checking the code versions, creation of branches at instance. When recording changes to git, make sure that the changes are relevant and needed to be persisted.

Go for squash only when it is really not needed to make a point about the changes that you are doing. This modifies the report of work done.

Upvotes: 1

qantik
qantik

Reputation: 1097

How about

git reset --soft HEAD~[n]
git commit

That should squash your n last commits.

Upvotes: 9

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521639

What would you do here that isn't going to lead to merge conflicts?

Unfortunately, merge conflicts may be unavoidable if you squash the commits.

You can try doing an interactive rebase in which you combine the hotfix commits into a single commit. Keep in mind that this solution is only recommended in general if you have not yet pushed this branch to the remote. So, if you have made commits 1-5 locally, not pushed them, and you want to combine them, then interactive rebase is a good choice.

Start with the following:

git checkout tests
git rebase -i HEAD~5

This should bring up a window showing you the following list of 5 commits, going from the oldest commit 1 to the newest commit 5 your tests branch:

pick 07c5abd message for commit 1
pick dl398cn message for commit 2
pick 93nmcdu message for commit 3
pick lst28e4 message for commit 4
pick 398nmol message for commit 5

You can see that by default, the option for each commit is pick. If you finished the rebase now, you would just be retaining each commit as it is, which is effectively a no-op. But since you want to squash certain middle commits, edit and change the list to this:

pick 07c5abd message for commit 1
squash dl398cn message for commit 2
squash 93nmcdu message for commit 3
squash lst28e4 message for commit 4
squash 398nmol message for commit 5

Save and close file, then complete the rebase.

Note carefully what is happening above. By typing squash you are telling Git to merge that commit into the one above it, which is the commit which came immediately before it. So this says to squash commit 5 backwards into commit 4, and then to squash 4 into 3, and so on, leaving you with just one commit for commits 1 through 5. The other commits which occurred before commit 1 remain as is.

If the commits you just squashed have not been pushed, and commit 1 be ahead of origin/tests, then you should simply be able to push this branch via:

git push origin tests

If this doesn't work, you may have to force push the branch:

git push --force origin tests

But keep in mind that this rewrites the remote history, and you should ideally not have to do this.

Upvotes: 1

Related Questions