ave
ave

Reputation: 19523

Squash unpushed commits automatically

I currently just use rebase for it, e.g.

git rebase -i origin/master

this brings me my text editor and then I manually mark all the commits with s except the first commit.

Is it possible to do this automatically, without editing textual file?

Upvotes: 3

Views: 663

Answers (2)

William Pursell
William Pursell

Reputation: 212534

If you just want a new commit that shares the tree of HEAD, use git commit-tree. That is, if your current history looks like:

A-B-C-D-E 

And you want

 A-B-E'

Where E' and E have the same content (here, B would be origin/master), just do:

git reset $( git commit-tree $(git cat-file -p HEAD | 
    awk '/tree/{print $2}') -p origin/master -m 'Squash')

There's probably a better way to get the tree of HEAD that doesn't involve piping to awk, but this should work just fine.

-- EDIT --

Thanks to @Guildenstern, modern git allows you to do:

git reset $(git commit-tree HEAD^{tree} -p origin/master -m 'Squash')

Upvotes: 2

twalberg
twalberg

Reputation: 62469

Assuming you are on master (the local one), and that it is ahead of origin/master by some commits, you could just do this:

git checkout -b tempbranch origin/master
git merge --squash master
git checkout master
git reset --hard tempbranch
git branch -D tempbranch

Now your master branch has a single commit ahead of origin/master that is the result of squashing all your previous commits.

The process would be similar if you're on a side branch, except steps 2 and 3 above would reference that branch instead of master. The results might not be quite as expected, though, depending on where git merge-base mybranch origin/master is relative to origin/master (i.e. if origin/master has advanced since the side branch was created). We'd have to know more about your actual branch topology to give better advice in that case...

Upvotes: 2

Related Questions