Programmatically fixup last commit into previous
Asked Answered
E

4

6

Every time I want to fixup my latest commit into the second latest commit, I do this

git rebase HEAD~2 -i
<replace pick with fixup on line 2>

Is there a way to do this in an automated script, without human interference?

I tried this and it doesn't work:

git commit --fixup=HEAD
Empyema answered 16/4, 2018 at 3:56 Comment(2)
Possible duplicate of How do I run git rebase --interactive in non-interactive manner?Eelgrass
@Eelgrass Not really, this is a different question that can be solved in many different ways.Empyema
H
12
git reset HEAD~1 --soft
git commit --amend --no-edit

or

git reset HEAD~2 --soft
git commit -C ORIG_HEAD^ --reset-author 

or

head=`git log -1 --pretty=%H HEAD~1`
git reset HEAD~2 --hard
git merge --squash ORIG_HEAD
git commit -C $head --reset-author

or

head=`git log -1 --pretty=%h HEAD~1`
git reset HEAD~2 --hard
git cherry-pick -n HEAD..ORIG_HEAD
git commit -C $head --reset-author

The first is enough in your case. The other three are just for fun here, which might be useful in other cases.

Update: the explanation of the second:

Suppose we have A-B-C as the latest three commits and C is the head. What you want is to squash B and C into a single commit which reuses B's commit message.

git reset HEAD~2 --soft resets HEAD to A and keeps the changes of B and C in the index and in the working tree. Then a following git commit creates a commit that includes the changes in the index, aka the changes of B and C.

As its name implies, ORIG_HEAD points to the original head, in this case the one before last reset, which is C. And ORIG_HEAD^ means the first parent of ORIG_HEAD, which is B. -C ORIG_HEAD^ means to reuse the commit message of B without edit.

More about --soft, -C and --reset-author.

Havre answered 16/4, 2018 at 5:39 Comment(2)
Can you explain the second one a bit? It looks useful but I'm a bit confused.Empyema
@Empyema Glad it helps.Havre
L
5

Every time I want to fixup my latest commit,

This can be done directly:

git commit --amend

For older commits:

git commit --fixup $commit
git rebase HEAD~n -i --autosquash

This will automatically interpret the fixup! prefixes generated earlier by --fixup (or manually).

Laius answered 16/4, 2018 at 4:4 Comment(2)
I think I wrote the question wrong. I want to fixup (squash but discard commit message) the latest commit into the previous one.Empyema
Don't make the commit in the first place, --amend the previous one.Laius
E
3

I'm still looking for a "canonical" solution with Git itself.

Here's my temporary solution workaround:

EDITOR="sed -i "2s/pick/fixup/'" git rebase -i HEAD~2

Basically just replaced an interactive text editor with sed.

Empyema answered 16/4, 2018 at 3:58 Comment(0)
D
0

This seems to work for me, full automatic and does does not require any specific sha or anything:

git commit -a --fixup HEAD ; GIT_SEQUENCE_EDITOR=touch git rebase --interactive --autosquash HEAD~2
Doe answered 14/5, 2019 at 14:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.