ฉันพยายามที่จะทำลายความมุ่งมั่น - HEAD to HEAD ~ 3 มีวิธีที่รวดเร็วในการทำเช่นนี้หรือฉันต้องใช้ rebase --interactive?
ฉันพยายามที่จะทำลายความมุ่งมั่น - HEAD to HEAD ~ 3 มีวิธีที่รวดเร็วในการทำเช่นนี้หรือฉันต้องใช้ rebase --interactive?
คำตอบ:
ตรวจสอบให้แน่ใจว่าต้นไม้ทำงานของคุณสะอาดแล้ว
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 แบบโต้ตอบในกรณีนั้น
โดยส่วนตัวฉันชอบวิธีแก้ปัญหาของ wilhelmtell :
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
นี่คือหนึ่งซับที่จะสควอช 2 คอมมิตสุดท้าย ในตัวอย่างนี้ข้อความของการกระทำที่สองสุดท้ายจะยังคงอยู่ คุณสามารถเปลี่ยนแปลงข้อความได้ตามที่คุณต้องการ
git commit -am "$(git log -1 --skip=1 --pretty=%B | xargs && git reset --soft HEAD~2)"
คำสั่งนี้จะมีประโยชน์มากหากคุณสร้างนามแฝงสำหรับคำสั่งนี้และใช้นามแฝงแทน
ในการสควอชทุกอย่างเนื่องจากสาขาถูกแยกออกจากมาสเตอร์:
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 - จาก HEAD ~ 4 HEAD ~ master
สิ่งนี้ถือว่าคุณเป็นผู้เชี่ยวชาญที่มีประวัติเชิงเส้น มันไม่ใช่สควอชเสียทีเดียวเพราะมันทิ้งการกระทำที่อยู่ตรงกลาง คุณต้องแก้ไข HEAD ใหม่เพื่อแก้ไขข้อความคอมมิต
HEAD~4
เป็นพาเรนต์