回答:
作業ツリーがきれいであることを確認してから、
git reset --soft HEAD~3
git commit -m 'new commit message'
git reset --soft HEAD~3 && git commit -m "my message"
git config alias.mysquash '!f(){ git reset --soft HEAD~$1 && git commit ${2:+-m "$2"}; };f'
。git mysquash 3 'some message'
動作しますが、私はそれを微調整したためgit musquash 3
、-mフラグを完全に省略してgit commit
、その場合はインタラクティブなUIを取得します。
私はウィルヘルムテルのソリューションを個人的に気に入っています:
git reset --soft HEAD~3
git commit -m 'new commit message'
ただし、これを実行できるように、いくつかのエラーチェックでエイリアスを作成しました。
git squash 3 'my commit message'
スクリプトを実際に実行するエイリアスを設定することをお勧めします。これにより、(a)スクリプトのコーディングが簡単になり、(b)エラーチェックでより複雑な作業を行うことができます。以下はスカッシュの機能を実行するスクリプトで、次にそれはgitエイリアスを設定するためのスクリプトです。
スカッシュ用のスクリプト(squash.sh)
#!/bin/bash
#
#get number of commits to squash
squashCount=$1
#get the commit message
shift
commitMsg=$@
#regular expression to verify that squash number is an integer
regex='^[0-9]+$'
echo "---------------------------------"
echo "Will squash $squashCount commits"
echo "Commit message will be '$commitMsg'"
echo "...validating input"
if ! [[ $squashCount =~ $regex ]]
then
echo "Squash count must be an integer."
elif [ -z "$commitMsg" ]
then
echo "Invalid commit message. Make sure string is not empty"
else
echo "...input looks good"
echo "...proceeding to squash"
git reset --soft HEAD~$squashCount
git commit -m "$commitMsg"
echo "...done"
fi
echo
exit 0
次に、そのsquash.shスクリプトをgitエイリアスに接続するには、gitエイリアスを設定する別のスクリプトを作成します(create_aliases.commandまたはcreate_aliases.sh)。
#!/bin/sh
echo '-----------------------'
echo 'adding git aliases....'
echo '-----------------------'
echo
git config --global alias.squash "!bash -c 'bash <path to scripts directory>/squash.sh \$1 \$2' -"
#add your other git aliases setup here
#and here
#etc.
echo '------------------------------------'
echo 'here is your global gitconfig file:'
echo '------------------------------------'
more ~/.gitconfig
echo
echo
echo '----------------'
echo 'end of script...'
echo '----------------'
$PATH
名前git-squash.sh
を付けて置くこともでき、自動的にとしてエイリアス化されgit squash
ます。私が知らないcreate-aiases.sh
スクリプトを使用する理由がある場合に備えて、私はあなたの答えを変更しませんでした。
wilhelmtellによる回答に追加するには、にソフトリセットしてからHEAD~2
コミットを修正すると便利ですHEAD~3
。
git reset --soft HEAD~2
git commit --all --amend --no-edit
これにより、すべてのコミットがコミットにマージされ、HEAD~3
そのコミットメッセージが使用されます。クリーンな作業ツリーから始めてください。
私が使用した:
EDITOR="sed -i '2,/^$/s/^pick\b/s/'" git rebase -i <ref>
かなりうまくいきました。"pick"で始まる行を含むコミットログを作成しないでください:)
次のコマンドを使用して、最後のコミット内の最後の4つのコミットを押しつぶします。
git squash 4
エイリアス:
squash = !"f() { NL=$1; GIT_EDITOR=\"sed -i '2,$NL s/pick/squash/;/# This is the 2nd commit message:/,$ {d}'\"; git rebase -i HEAD~$NL; }; f"
sq = !git squash $1
sqpsf = !git squash $1 && git psf
https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfigから
ブランチがマスターから分岐されてからすべてをつぶすには:
git reset --soft $(git merge-base --fork-point master) \
&& git commit --verbose --reedit-message=HEAD --reset-author
--reedit-message=HEAD
スカッシュの一部ではない最後のコミットのメッセージを使用します。これはおそらくあなたが望むものではありません。むしろのメッセージを取得するには最初に含まれるコミットのいずれか、(1)交換するHEAD
あなたがのメッセージ、またはたいコミットのハッシュと(2)最初に含まれるコミットへジャンプしますgit commit --amend --reedit-message=HEAD
。これが調和のとれた答えです。
あなたはかなり近づくことができます
git rebase --on HEAD〜4 HEAD〜マスター
これは、あなたが線形履歴を持つマスターにいることを前提としています。中間のコミットを破棄するので、それはかなりスカッシュではありません。コミットメッセージを変更するには、新しいHEADを修正する必要があります。
HEAD~4
、親として持つように書き換えられます。