gitsquash

git - How can I squash all commits till branch starts?


I want to Squash all commit in the branch, while preserve their commit messages into the squashed commit. For example here, I want to squash [8015a49, 38a7b5a, 4c7e9e2, 49a7b5a] commits into one but keeping till 70d79f9 unchanged.

*   8015a49 - (HEAD -> dev, origin/dev) Merge branch 'feature/0' into dev (3 seconds ago)
|\
| * 49a7b5a - Fix me. (1 minutes ago)
| * 38a7b5a - Use 2 space in the code. (3 minutes ago)
| * 4c7e9e2 - Add minor improvements. (12 hours ago)
|/
* 70d79f9 - Replace ipfs with ipfsid. (2 days ago)
* 10d79f9 - Add README.md. (3 days ago)

After:

* 1234567 - New Squashed commit (1 second aga) // [8015a49, 38a7b5a, 4c7e9e2, 49a7b5a] 
* 70d79f9 - Replace ipfs with ipfsid. (2 days ago)
* 10d79f9 - Add README.md. (3 days ago)

When I tried following answer for How to squash my last x commits together?, git reset --soft HEAD~1 ; 70d79f9 also take place in the squash in between all the commits in the branch also considered.

My approach:

git fetch --all --quiet
git reset --soft HEAD~1 
output_1=$(git log -1 --pretty=%B)
output_2=$(git log --pretty=%B --reverse HEAD..HEAD@{1})
output="$output_1\n\n$output_2"
message=$(echo -e "$output" | awk 'NF{$1=$1};!NF||!seen[$0]++')
git commit --amend --quiet --no-verify --edit -m "$message"

Solution

  • The problem is because of what you stated in a comment:

    I was doing git reset --soft HEAD~1 and then git commit --amend --quiet --no-verify --edit ; which may end up changing modifying 70d79f9 as well

    Why did you add --amend to your commit command? If you use --amend you are instructing Git to change your current commit, which in this case would be 70d79f9. You essentially squashed everything into that commit. Remove the --amend option and you'll get a new commit like you intended.