$ git reset -- <file_path>
สามารถรีเซ็ตตามเส้นทาง
อย่างไรก็ตาม$ git reset (--hard|--soft) <file_path>
จะรายงานข้อผิดพลาดดังต่อไปนี้:
Cannot do hard|soft reset with paths.
$ git reset -- <file_path>
สามารถรีเซ็ตตามเส้นทาง
อย่างไรก็ตาม$ git reset (--hard|--soft) <file_path>
จะรายงานข้อผิดพลาดดังต่อไปนี้:
Cannot do hard|soft reset with paths.
คำตอบ:
เนื่องจากไม่มีประเด็น (คำสั่งอื่น ๆ มีฟังก์ชันนั้นอยู่แล้ว) และจะช่วยลดโอกาสในการทำสิ่งผิดพลาดโดยบังเอิญ
เพียงแค่ทำการ "ฮาร์ดรีเซ็ต" สำหรับเส้นทางgit checkout HEAD -- <path>
(ตรวจสอบเวอร์ชันที่มีอยู่ของไฟล์)
ซอฟต์รีเซ็ตสำหรับพา ธ ไม่สมเหตุสมผล
การรีเซ็ตแบบผสมสำหรับเส้นทางคือสิ่งที่git reset -- <path>
ทำ
git checkout -- <path>
ไม่ทำการฮาร์ดรีเซ็ต จะแทนที่เนื้อหาแผนผังการทำงานด้วยเนื้อหาที่จัดฉาก git checkout HEAD -- <path>
ทำการฮาร์ดรีเซ็ตสำหรับเส้นทางโดยแทนที่ทั้งดัชนีและแผนผังการทำงานด้วยเวอร์ชันจาก HEAD คอมมิต
reset --hard
ด้วยเส้นทางจะให้ชิ้นส่วนที่ขาดหายไปนี้ Git นั้นทรงพลังมากจนข้ออ้าง "เราไม่ปล่อยให้คุณทำเพื่อปกป้องตัวเอง" ถือเป็นศูนย์: มีหลายวิธีที่จะทำสิ่งที่ผิด "โดยบังเอิญ" git reflog
ไม่มีใครที่มีความสำคัญอยู่แล้วเมื่อคุณมี
git reset --hard -- <path>
แต่ฉันก็ยังหวังว่าสักวันหนึ่งเราจะได้รับ มีกรณีการใช้งานที่ถูกต้องตามกฎหมาย
git checkout HEAD <path>
คุณสามารถประสบความสำเร็จในสิ่งที่คุณกำลังพยายามที่จะทำโดยใช้
ที่กล่าวว่าข้อความแสดงข้อผิดพลาดที่ให้มาไม่สมเหตุสมผลสำหรับฉัน (เนื่องจากใช้git reset
งานได้ดีในไดเรกทอรีย่อย) และฉันไม่เห็นเหตุผลว่าทำไมgit reset --hard
ไม่ควรทำตามที่คุณต้องการ
คำถามที่ว่ามีอยู่แล้วตอบผมจะอธิบายว่าทำไมส่วนหนึ่ง
ดังนั้นสิ่งที่จะรีเซ็ตคอมไพล์ทำอย่างไร ขึ้นอยู่กับพารามิเตอร์ที่ระบุมันสามารถทำสองสิ่งที่แตกต่างกัน:
หากคุณระบุพา ธ จะแทนที่ไฟล์ที่ตรงกันในดัชนีด้วยไฟล์จากคอมมิต (HEAD ตามค่าดีฟอลต์) การดำเนินการนี้ไม่ส่งผลกระทบต่อโครงสร้างการทำงานเลยและโดยปกติจะใช้ตรงกันข้ามกับ git add
หากคุณไม่ได้ระบุเส้นทางระบบจะย้ายส่วนหัวสาขาปัจจุบันไปยังการคอมมิตที่ระบุและพร้อมกับเลือกที่จะรีเซ็ตดัชนีและโครงสร้างการทำงานเป็นสถานะของการคอมมิตนั้น นี้เพิ่มเติมพฤติกรรมที่ถูกควบคุมโดยพารามิเตอร์โหมด:
--soft : ไม่ได้สัมผัสดัชนีและต้นไม้ทำงาน
--mixed (ค่าเริ่มต้น): รีเซ็ตดัชนี แต่ไม่ใช่โครงสร้างการทำงาน
- ฮาร์ด : รีเซ็ตดัชนีและโครงสร้างการทำงาน
นอกจากนี้ยังมีตัวเลือกอื่น ๆ โปรดดูเอกสารสำหรับรายการทั้งหมดและกรณีการใช้งานบางส่วน
เมื่อคุณไม่ได้ระบุการคอมมิตจะมีค่าเริ่มต้นเป็น HEAD ดังนั้นgit reset --soft
จะไม่ทำอะไรเลยเนื่องจากเป็นคำสั่งให้ย้ายส่วนหัวไปที่ HEAD (ไปยังสถานะปัจจุบัน) git reset --hard
ในทางกลับกันก็สมเหตุสมผลเนื่องจากผลข้างเคียงมันบอกว่าให้ย้ายหัวไปที่ HEAD และรีเซ็ตดัชนีและโครงสร้างการทำงานเป็น HEAD
ฉันคิดว่าตอนนี้มันควรจะชัดเจนแล้วว่าทำไมการดำเนินการนี้ไม่ได้มีไว้สำหรับไฟล์บางไฟล์ตามธรรมชาติ - มันมีจุดประสงค์เพื่อย้ายหัวสาขาในตอนแรกรีเซ็ตโครงสร้างการทำงานและดัชนีเป็นฟังก์ชันรอง
git checkout
คำสั่ง? และการรีเซ็ตเพื่อทำสิ่งเดียวกันนี้จะทำให้ผู้ใช้สับสนต่อไป คำตอบของฉันคือ--hard
ตัวเลือกนั้นไม่สามารถใช้ได้กับไฟล์บางไฟล์เนื่องจากเป็นโหมดสำหรับการรีเซ็ตสาขาไม่ใช่การรีเซ็ตดัชนี และการรีเซ็ตทรีการทำงานมีชื่อว่าการชำระเงินดังที่คุณสามารถอ่านได้ในคำตอบอื่น ๆ ทั้งหมดนี้เป็นเพียงการออกแบบอินเทอร์เฟซผู้ใช้ IMHO ของ Git ที่ไม่ดี
git checkout
: git reset --
กำหนดดัชนีเท่านั้นในขณะที่git checkout --
กำหนดโครงสร้างการทำงานเท่านั้น?
มีเหตุผลที่สำคัญมากที่อยู่เบื้องหลังที่: หลักการของcheckout
reset
และ
ในเงื่อนไข Git การชำระเงินหมายถึง "นำเข้าสู่โครงสร้างการทำงานปัจจุบัน" และด้วยการgit checkout
ที่เราสามารถกรอกต้นการทำงานกับข้อมูลจากการใด ๆในพื้นที่เป็นได้จากกระทำในแฟ้มที่เก็บข้อมูลหรือบุคคลจากการกระทำหรือพื้นที่การแสดงละคร (ซึ่งก็คือแม้เริ่มต้น)
ในทางกลับกันการรีเซ็ตคอมไพล์ไม่มีบทบาทนี้ ตามชื่อที่แนะนำมันจะรีเซ็ตการอ้างอิงปัจจุบัน แต่จะมีที่เก็บเป็นแหล่งที่มาเสมอโดยไม่ขึ้นกับ "reach" (--soft, --mixed หรือ --hard)
สรุป:
ดังนั้นสิ่งที่อาจทำให้สับสนเล็กน้อยคือการมีอยู่ของgit reset COMMIT -- files
ตั้งแต่ "การเขียนทับ HEAD" กับไฟล์บางไฟล์เท่านั้นที่ไม่สมเหตุสมผล!
ในกรณีที่ไม่มีคำอธิบายอย่างเป็นทางการฉันสามารถคาดเดาได้ว่านักพัฒนา git พบว่าreset
ยังคงเป็นชื่อที่ดีที่สุดของคำสั่งที่จะละทิ้งการเปลี่ยนแปลงที่เกิดขึ้นกับพื้นที่การแสดงละครและเนื่องจากแหล่งข้อมูลเดียวคือที่เก็บจากนั้น " ขอขยาย การทำงาน "แทนการสร้างคำสั่งใหม่
ดังนั้นจึงgit reset -- <files>
มีความพิเศษอยู่แล้ว: มันจะไม่เขียนทับ HEAD IMHO รูปแบบดังกล่าวทั้งหมดจะเป็นข้อยกเว้น แม้ว่าเราจะสามารถสร้าง--hard
เวอร์ชันได้ แต่คนอื่น ๆ (เช่น--soft
) ก็ไม่สมเหตุสมผล
git reset -- <files>
ดูเหมือนว่ามันถูกเพิ่มเข้ามาเพราะนี่เป็นคุณสมบัติที่มีประโยชน์ แต่ไม่มีใครแน่ใจว่าควรใส่คำสั่งใด โชคดีที่ตอนนี้เรามีสติมากขึ้นgit restore
ซึ่งมีฟังก์ชันการทำงานgit checkout -- <path>
git checkout <commit> -- <path>
และgit reset [<commit>] -- <path>
มีค่าเริ่มต้นที่ดีกว่าและคุณสมบัติอื่น ๆ ที่คุณไม่สามารถทำได้มาก่อน (ตรงกันข้ามกับคำตอบที่ยอมรับกล่าวในที่สุดคุณก็สามารถกู้คืนโครงสร้างที่ใช้งานได้โดยไม่ต้องสัมผัสดัชนี)
ตรวจสอบให้แน่ใจว่าคุณใส่เครื่องหมายทับระหว่างต้นทางหรือต้นน้ำ (ต้นทาง) และสาขาจริง:
git reset --hard origin/branch
หรือ
git reset --hard upstream/branch`
git reset
คู่มือรายการ 3 วิธีในการภาวนา:
2 เป็นไฟล์ที่ชาญฉลาด: สิ่งเหล่านี้ไม่ส่งผลกระทบต่อโครงสร้างการทำงานแต่ทำงานเฉพาะกับไฟล์ในดัชนีที่ระบุโดย<paths>
:
git reset [-q] [<tree-ish>] [--] <paths>..
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
1 คือการกระทำที่ชาญฉลาด: ทำงานกับไฟล์ทั้งหมดในการอ้างอิง<commit>
และอาจส่งผลต่อโครงสร้างการทำงาน:
git reset [<mode>] [<commit>]
ไม่มีโหมดการเรียกใช้ที่ทำงานเฉพาะกับไฟล์ที่ระบุและส่งผลต่อโครงสร้างการทำงาน
หากคุณต้องการทั้งสอง:
คุณสามารถใช้นามแฝงนี้ในไฟล์กำหนดค่า git ของคุณ:
[alias]
reco = !"cd \"${GIT_PREFIX:-.}\" && git reset \"$@\" && git checkout \"$@\" && git status --short #" # Avoid: "fatal: Cannot do hard reset with paths."
จากนั้นคุณสามารถเลือกทำอย่างใดอย่างหนึ่ง:
$ git reco <paths>
$ git reco <branch/commit> <paths>
$ git reco -- <paths>
(Mnenonic สำหรับreco
: re
set && c
heck o
ut)
git reset --soft HEAD ~ 1 ชื่อไฟล์เลิกทำการคอมมิต แต่การเปลี่ยนแปลงยังคงอยู่ในโลคัล ชื่อไฟล์อาจเป็น - สำหรับไฟล์ที่คอมมิตทั้งหมด
Cannot do soft reset with paths.
git checkout -- <path>
ควรจะแทนที่ด้วยgit reset --hard <path>
. มันเข้าท่ากว่ามาก ...