Musical Shore
Musical Shore

Reputation: 1381

Is there anyway to collapse several git commits into one commit?

Let's say I commit my code at the end of each day. Most of these commits are garbage, I am saving code but most of the time I am checking in incomplete code that doesn't work. Once I finish the feature, I don't want those broken commits in the log. I want to do a final commit that works, without keeping the history of daily commits. Is this possible?

Upvotes: 0

Views: 615

Answers (4)

torek
torek

Reputation: 487725

Yes. In general git calls this "squashing" and there are a number of ways to do it. The method I'd suggest as an introduction to the process is to use interactive rebase.

If you're working with an "upstream" (a repository you push to, or otherwise picks up commits you publish) you would normally set this up as the upstream for your branch. Then git rebase -i will set things up for you. If not, you still run git rebase -i, you just need to add one more thing to it, namely, which commit(s) to interactively rebase. For instance, in this case, you might use git rebase -i HEAD~4 to work on your last four commits.

What you'll be doing is not, in fact, rebasing—you won't move the commit chain from one starting point to another—but git rebase is still the mechanism. When doing an interactive rebase, you get a list of commits:

pick 1234567   commit message
pick 2345678   another commit message

Git opens up your favorite editor on this list, which you can then tweak however you like, and then git attempts to re-apply the commits in the new order listed, with the changes you've made to the pick lines.

Changing one line from pick to squash causes that commit to be folded together with its previous (line-above) commit, at which point git opens your editor again on the commit message, so that you can modify the message for the new (single) commit that squashes together the two existing commits.

You can also change the order of commits, or omit commits.

Note that it's much harder to split a commit (though it can be done) so be sure you really want to squash some together before you do it.

(What the rebase process really does is to copy each commit, with the final commit being made once any additional squashes or fixups are inserted. Your original chain of commits is still in the repository, and you can find them with the "reflog" for your branch. Note that because it does copy commits, you generally should copy-and-modify only commits that you have not yet published. Since no one else has your unpublished work, they'll never get confused by seeing old and new versions of that work.)

Upvotes: 4

Vogel612
Vogel612

Reputation: 5647

sure it's possible. What you're looking for is sqashing, which can be done when using git rebase

You just select the commits you want to merge (they must be subsequent) and ask git to squash them during your interactive rebase

Upvotes: 0

divix
divix

Reputation: 1364

If you want to merge all local commits from your checkout do this:

//this will revert your commits but will keep your changes
git revert ...
//and then normally
git commit -m 'New feature'
git push

Upvotes: 0

skypjack
skypjack

Reputation: 50540

You can do that while doing your job, by means of the command git commit --amend.

Simply, do the first commit as usual. Then pack your stuff for the next commit by means of the command git add <your stuff>. Finally, instead of a usual commit, use the one above mentioned.

See here for further details.

Upvotes: 1

Related Questions