ฉันจะเปลี่ยนการเปลี่ยนแปลงในพื้นที่ทั้งหมดในโครงการที่จัดการ Git กลับไปเป็นสถานะก่อนหน้าได้อย่างไร


1913

git initผมมีโครงการที่ฉันวิ่ง หลังจากทำคอมมิทหลายครั้งฉันก็git statusบอกทุกอย่างให้ทันสมัยและไม่มีการเปลี่ยนแปลงในท้องถิ่น

จากนั้นฉันทำการเปลี่ยนแปลงติดต่อกันหลายครั้งและตระหนักว่าฉันต้องการทิ้งทุกอย่างและกลับสู่สภาพเดิม คำสั่งนี้จะทำเพื่อฉันได้ไหม

git reset --hard HEAD

คำตอบ:


3388

หากคุณต้องการยกเลิกการเปลี่ยนแปลงที่ทำกับสำเนาที่ใช้งานได้ให้ทำสิ่งนี้:

git checkout .

หากคุณต้องการยกเลิกการเปลี่ยนแปลงที่ทำกับดัชนี (เช่นที่คุณเพิ่มไว้) ให้ทำเช่นนี้ คำเตือนสิ่งนี้จะรีเซ็ตการไม่ได้กดตกลงทั้งหมดของคุณเป็นหลัก! :

git reset

หากคุณต้องการคืนค่าการเปลี่ยนแปลงที่คุณทำไว้ให้ทำดังนี้

git revert <commit 1> <commit 2>

หากคุณต้องการลบไฟล์ที่ไม่ได้ติดตาม (เช่นไฟล์ใหม่ไฟล์ที่สร้าง):

git clean -f

หรือไดเรกทอรีที่ไม่ได้ติดตาม (เช่นไดเรกทอรีใหม่หรือสร้างขึ้นโดยอัตโนมัติ):

git clean -fd

133
หลังจากนั้นเป็นเวลานานgit checkout path/to/fileจะเปลี่ยนการเปลี่ยนแปลงในท้องถิ่นเป็นpath/to/file
Matijs

29
+1 กับคำตอบด้านล่างนี้ยังกล่าวถึง git clean -f (เพื่อลบการเปลี่ยนแปลงที่ไม่ได้ติดตาม) และ -fd (เพื่อลบไดเรกทอรีที่ไม่ได้ติดตาม)
ptdev

3
และถ้าคุณต้องการทำความสะอาดไฟล์ที่ไม่ได้ติดตามอ่านstackoverflow.com/questions/61212/
Surasin Tancharoen

9
git checkout .และgit reset [--hard HEAD]ไม่ได้ผลฉันต้องทำgit clean -fdเพื่อยกเลิกการเปลี่ยนแปลงของฉัน
BrainSlugs83

7
git resetไม่ได้ตั้งค่าการเปลี่ยนแปลงของคุณgit reset --hardไม่ว่า
Cerin

388

หมายเหตุ: คุณอาจต้องการเรียกใช้

git clean -fd

เช่น

git reset --hard

จะไม่ลบไฟล์ที่ไม่ได้ติดตามซึ่งเป็น git-clean จะลบไฟล์ใด ๆ จากไดเรกทอรีรากที่ถูกติดตามซึ่งไม่ได้อยู่ภายใต้การติดตามคอมไพล์ คำเตือน - ระวังสิ่งนี้! มันจะมีประโยชน์ในการรัน dry-run ด้วย git-clean ก่อนเพื่อดูว่ามันจะลบอะไร

สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อคุณได้รับข้อความแสดงข้อผิดพลาด

~"performing this command will cause an un-tracked file to be overwritten"

ซึ่งสามารถเกิดขึ้นได้เมื่อทำหลายสิ่งหนึ่งกำลังอัปเดตสำเนาที่ใช้งานได้เมื่อคุณและเพื่อนของคุณได้เพิ่มไฟล์ใหม่ที่มีชื่อเดียวกัน แต่เขามุ่งมั่นในการควบคุมซอร์สก่อนและคุณไม่สนใจที่จะลบสำเนาที่ไม่ได้ติดตาม .

ในสถานการณ์เช่นนี้การรันแบบแห้งจะช่วยแสดงรายการของไฟล์ที่จะถูกเขียนทับ


13
คำสั่ง clean file คือ "git clean -f" ไดเรกทอรีที่ไม่ได้ติดตามจะถูกลบออกด้วย "git clean -d"
โจนาธานมิทเชล

35
git clean -fd (บังคับให้ใช้สำหรับ -d)
electblake

14
-n หรือ --dry-run เป็นแฟล็กสำหรับการรันแบบแห้ง
stephenbez

2
git clean -ffd ถ้าคุณมีที่เก็บ git อื่นในที่เก็บ git ของคุณ หากไม่มีดับเบิ้ล f มันจะไม่ถูกลบออก
Trismegistos

148

Re-โคลน

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ลบการกระทำที่ไม่ได้ทำไว้ในระบบ
  • verts ย้อนกลับการเปลี่ยนแปลงที่คุณทำกับไฟล์ที่ถูกติดตาม
  • ✅กู้คืนไฟล์ที่ถูกติดตามที่คุณลบ
  • ✅ลบไฟล์ / dirs อยู่ในรายการ.gitignore(เช่นสร้างไฟล์)
  • ✅ลบไฟล์ / dirs ที่ไม่ได้ติดตามและไม่เข้า .gitignore
  • 😀คุณจะไม่ลืมวิธีการนี้
  • bandwidth เสียแบนด์วิดธ์

ต่อไปนี้เป็นคำสั่งอื่น ๆ ที่ฉันลืมทุกวัน

ทำความสะอาดและรีเซ็ต

git clean --force -d -x
git reset --hard
  • ❌ลบการกระทำที่ไม่ได้ทำไว้ในระบบ
  • verts ย้อนกลับการเปลี่ยนแปลงที่คุณทำกับไฟล์ที่ถูกติดตาม
  • ✅กู้คืนไฟล์ที่ถูกติดตามที่คุณลบ
  • ✅ลบไฟล์ / dirs อยู่ในรายการ.gitignore(เช่นสร้างไฟล์)
  • ✅ลบไฟล์ / dirs ที่ไม่ได้ติดตามและไม่เข้า .gitignore

สะอาด

git clean --force -d -x
  • ❌ลบการกระทำที่ไม่ได้ทำไว้ในระบบ
  • verts ย้อนกลับการเปลี่ยนแปลงที่คุณทำกับไฟล์ที่ถูกติดตาม
  • ❌กู้คืนไฟล์ที่ถูกติดตามที่คุณลบ
  • ✅ลบไฟล์ / dirs อยู่ในรายการ.gitignore(เช่นสร้างไฟล์)
  • ✅ลบไฟล์ / dirs ที่ไม่ได้ติดตามและไม่เข้า .gitignore

ตั้งค่าใหม่

git reset --hard
  • ❌ลบการกระทำที่ไม่ได้ทำไว้ในระบบ
  • verts ย้อนกลับการเปลี่ยนแปลงที่คุณทำกับไฟล์ที่ถูกติดตาม
  • ✅กู้คืนไฟล์ที่ถูกติดตามที่คุณลบ
  • ❌ลบไฟล์ / dirs อยู่ในรายการ.gitignore(เช่นสร้างไฟล์)
  • ❌ลบไฟล์ / dirs ที่ไม่ได้ติดตามและไม่เข้า .gitignore

หมายเหตุ

กรณีทดสอบเพื่อยืนยันทั้งหมดข้างต้น (ใช้ bash หรือ sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

ดูสิ่งนี้ด้วย

  • git revert เพื่อทำการคอมมิทใหม่ที่เลิกทำการคอมมิชชันก่อนหน้า
  • git checkout เพื่อย้อนเวลากลับไปก่อนหน้า (อาจต้องใช้คำสั่งด้านบนก่อน)
  • git stashเช่นเดียวกับgit resetข้างต้น แต่คุณสามารถยกเลิกได้

ขออภัยที่ขโมยจากคำตอบข้างต้น ฉันใช้อ้างอิงนี้อย่างต่อเนื่องโพสต์ส่วนใหญ่สำหรับฉัน
William Entriken

1
ผมค่อนข้างมั่นใจว่าตัวเลือกแรก ( Re-โคลน ) ไม่จริง "ลบท้องถิ่นกระทำที่ไม่ผลักดัน" :)
Marandil

1
@styfle ✅บางสิ่งบางอย่างมันไม่❌เป็นสิ่งที่ไม่ได้ทำ
วิลเลียม Entriken

3
@ FullDecent มันสับสนในการอ่าน "❌ไม่ต้องลบการคอมมิทที่ไม่ใช่การผลัก" ซึ่งหมายความว่าจะไม่ลบ ลบหมายความว่ามันจะลบ?
styfle

1
เกี่ยวกับแฟล็ก -x ในgit clean -f -d -x: หากระบุตัวเลือก -x ไฟล์ที่ถูกละเว้นจะถูกลบเช่นกัน ตัวอย่างเช่นนี้สามารถเป็นประโยชน์ในการลบผลิตภัณฑ์สร้างทั้งหมด. - จากเอกสาร GIT
อเล็กซ์

82

หากคุณต้องการยกเลิกการเปลี่ยนแปลงทั้งหมดและเป็นข้อมูลล่าสุดกับต้นแบบระยะไกลปัจจุบัน (ตัวอย่างเช่นคุณพบว่าหัวหน้าต้นแบบได้ย้ายไปข้างหน้าเนื่องจากคุณแยกสาขาออกและการกดของคุณถูก 'ปฏิเสธ') คุณสามารถใช้

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.

ดูเหมือนว่าสิ่งสำคัญที่จะระบุoriginในgit reset --hard origin/master(ที่ทำงาน) - โดยไม่ได้ (คือgit reset --hard) ไม่มีอะไรดูเหมือนว่าจะมีการเปลี่ยนแปลง
Jake

ฉันมีการเปลี่ยนแปลงบางอย่างในตัวเครื่องและไม่สามารถกำจัดได้โดยคำสั่งใด ๆ ที่ฉันได้ทำการตั้งค่าใหม่ - แหล่งกำเนิด / ต้นแบบและมันสามารถดึงการเปลี่ยนแปลงของเจ้านายได้เช่นกัน
abhishek ringsia

50

มองเข้าไปใน git-reflog มันจะแสดงรายการทุกรัฐที่จำได้ (ค่าเริ่มต้นคือ 30 วัน) และคุณสามารถชำระเงินที่คุณต้องการ ตัวอย่างเช่น:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d

ขอบคุณวิลเลียมตันสำหรับการอ้างอิงคอมไพล์ ฉันรีเซ็ตแผนผังของฉันเป็นเวอร์ชันเก่าและไม่แน่ใจว่าจะกลับไปเป็นล่าสุดได้อย่างไร refit คอมไพล์ของคุณช่วยฉัน ขอบคุณอีกครั้ง
palaniraja

1
ช่วยฉันด้วย! ในกรณีของฉันการผจญภัยของฉันด้วยgit rebase -iผิดพลาด (จบลงด้วยการลบความมุ่งมั่นเนื่องจากความผิดพลาดในการแก้ไข) ขอบคุณเคล็ดลับนี้ฉันกลับมาอยู่ในสถานะที่ดี!
paneer_tikka

คุณหมายถึงอะไรโดยเริ่มต้น 30 วัน!
Mohe TheDreamy

@MoheTheDreamy ฉันหมายถึงมีการ จำกัด เวลา ในที่สุดตัวรวบรวมขยะจะลบการอ้างอิงที่ไม่สามารถเข้าถึงได้เมื่ออายุเกินขีด จำกัด นั้น ค่าเริ่มต้นเคยเป็น (และอาจจะยังคงอยู่) 30 วัน ดังนั้นการอ้างอิงที่เก่ากว่าอาจไม่สามารถใช้ได้
วิลเลียม Pursell

36

อันตรายข้างหน้า: (โปรดอ่านความคิดเห็นการใช้คำสั่งที่เสนอในคำตอบของฉันอาจลบได้มากกว่าที่คุณต้องการ)

เพื่อลบไฟล์ทั้งหมดอย่างสมบูรณ์รวมถึงไดเรกทอรีที่ฉันต้องเรียกใช้

git clean -f -d

13
เพื่อช่วยให้ทุกคนได้รับความเจ็บปวดฉันเพิ่งผ่านไป: นี่จะลบไฟล์. gitignore-d ด้วย
แลนดอน

ขอโทษถ้าฉันทำให้คุณมีปัญหาใด ๆ ย้อนกลับไปฉันเพิ่งลองย้อนกลับและลบทุกอย่างในโฟลเดอร์นั้น ฉันจำสถานการณ์ที่ไม่แน่นอน แต่ "-d" เป็นสิ่งเดียวที่ทำงานได้สำหรับฉัน ฉันหวังว่าฉันไม่ได้ทำให้คุณเจ็บปวดมากเกินไป :-)
Tobias Gassmann

1
ไม่ทำอันตราย ฉันมีการสำรองข้อมูล แต่สิ่งนี้อาจรับประกันได้ว่าข้อจำกัดความรับผิดชอบ;)
landons

35

หลังจากอ่านคำตอบจำนวนมากแล้วลองพวกเขาพบว่ามีกรณีขอบต่าง ๆ ซึ่งหมายความว่าบางครั้งพวกเขาไม่ได้ทำความสะอาดสำเนาที่ใช้งานได้ทั้งหมด

นี่คือสคริปต์ทุบตีปัจจุบันของฉันที่ใช้ทำซึ่งใช้ได้ตลอดเวลา

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

เรียกใช้จากไดเรกทอรีรากทำงานคัดลอก


10
คำสั่งสุดท้ายให้ฉันerror: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L

1
มันใช้งานได้สำหรับฉันเมื่อฉันเอา "-" ออก git checkout HEAD
ตลก

4
git reset --hardย้อนกลับไฟล์ที่ถูกติดตาม (ฉากหรือไม่), git clean -f -dลบไฟล์ที่ไม่ได้ติดตาม, git checkout -- HEADทำไมเราต้องใช้มัน?
v.shashenko

เราไม่ต้องการยัติภังค์สองเท่า ต้องเป็นตัวพิมพ์ผิด
Farax

35

เพียงแค่รัน -

git stash

มันจะลบการเปลี่ยนแปลงในพื้นที่ทั้งหมดของคุณ และคุณยังสามารถใช้ในภายหลังโดยดำเนินการ -

git stash apply 

3
การใช้งานgit stash popจะลบการเปลี่ยนแปลงที่เก็บไว้ให้คุณโดยอัตโนมัติ
Arrow Cen

8
git stash dropเพื่อลบสถานะที่ถูกจัดเก็บล่าสุดโดยไม่ใช้กับสำเนาการทำงาน
Deerchao

git stash ใช้ไม่เพิ่มไฟล์ที่สร้างขึ้นใหม่
Ravistm

27

ฉันพบปัญหาที่คล้ายกัน วิธีแก้ไขคือใช้git logเพื่อค้นหาเวอร์ชันของการคอมมิตแบบโลคัลที่แตกต่างจากรีโมต (เช่นรุ่นเป็น3c74a11530697214cbcc4b7b98bf7a65952a34ec)

จากนั้นใช้git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ecเพื่อยกเลิกการเปลี่ยนแปลง


16

ฉันค้นหาปัญหาที่คล้ายกัน

ต้องการทิ้งความมุ่งมั่นในท้องถิ่น:

  1. โคลนที่เก็บ (โคลน git)
  2. เปลี่ยนเป็นสาขาของ dev (git checkout dev)
  3. ได้กระทำไม่กี่ (คอมไพล์กระทำ -m "กระทำ 1")
  4. แต่ตัดสินใจทิ้งสิ่งเหล่านี้ในท้องถิ่นเพื่อกลับไปที่รีโมต (แหล่งกำเนิด / dev)

ดังนั้นด้านล่าง:

git reset --hard origin/dev

ตรวจสอบ:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

ตอนนี้คอมมิชชันท้องถิ่นสูญหายไปกลับสู่สถานะเริ่มต้นโคลนจุด 1 ด้านบน


1
ขอบคุณนั่นเป็นสิ่งเดียวที่ทำงานให้ฉัน - "การรีเซ็ต git
Nisim Naim

ดีใจที่รู้ว่าช่วยได้
Manohar Reddy Poreddy

7

คุณอาจไม่ต้องการ / จำเป็นต้องซ่อนงาน / ไฟล์ในไดเร็กตอรี่การทำงานของคุณ แต่เพียงแค่กำจัดมันออกไปให้หมด คำสั่งgit cleanจะทำสิ่งนี้ให้คุณ

กรณีการใช้งานทั่วไปบางกรณีสำหรับการทำเช่นนี้คือการลบ cruftที่สร้างขึ้นโดยการผสานหรือเครื่องมือภายนอกหรือลบไฟล์อื่น ๆ เพื่อให้คุณสามารถเรียกใช้งานบิลด์แบบใหม่ได้

โปรดทราบว่าคุณจะต้องระมัดระวังคำสั่งนี้เนื่องจากได้รับการออกแบบมาเพื่อลบไฟล์ออกจากไดเรกทอรีการทำงานในพื้นที่ที่ไม่ได้ถูกติดตาม หากคุณเปลี่ยนใจหลังจากดำเนินการคำสั่งนี้อย่างไม่มีสติคุณจะไม่กลับไปดูเนื้อหาของไฟล์ที่ถูกลบไป ทางเลือกที่ปลอดภัยกว่าคือการดำเนินการ

git stash --all

ซึ่งจะลบทุกอย่าง แต่บันทึกไว้ทั้งหมดในที่ซ่อน ที่เก็บนี้สามารถใช้ในภายหลังได้

อย่างไรก็ตามหากคุณต้องการลบไฟล์ทั้งหมดและล้างไดเรกทอรีการทำงานของคุณคุณควรดำเนินการ

git clean -f -d

การทำเช่นนี้จะเป็นการลบไฟล์และไดเรกทอรีย่อยที่ไม่มีรายการใด ๆ อันเป็นผลมาจากคำสั่ง สิ่งที่ต้องทำก่อนดำเนินการgit clean -f -dคำสั่งคือการเรียกใช้

git clean -f -d -n

ซึ่งจะแสดงตัวอย่างของสิ่งที่จะถูกลบหลังจากดำเนินการ git clean -f -d

ดังนั้นนี่คือบทสรุปของตัวเลือกของคุณตั้งแต่ก้าวร้าวไปจนถึงก้าวร้าวน้อยที่สุด


ตัวเลือกที่ 1 : ลบไฟล์ทั้งหมดในเครื่อง (ก้าวร้าวมากที่สุด)

git clean -f -d

ตัวเลือกที่ 2 : ดูตัวอย่างผลกระทบข้างต้น (ดูตัวอย่างแบบก้าวร้าวมากที่สุด)

git clean -f -d -n

ตัวเลือก 3 : ซ่อนไฟล์ทั้งหมด (ก้าวร้าวน้อยที่สุด)

`git stash --all` 

6

ลองใช้วิธีนี้เพื่อยกเลิกการเปลี่ยนแปลงทั้งหมดที่ไม่ได้รับการตอบกลับในสาขาท้องถิ่น

$ git reset --hard HEAD

แต่ถ้าคุณเห็นข้อผิดพลาดเช่นนี้:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

คุณสามารถนำทางไปยังโฟลเดอร์ '.git' จากนั้นลบไฟล์ index.lock:

$ cd /directory/for/your/project/.git/
$ rm index.lock

ขั้นสุดท้ายให้รันคำสั่งอีกครั้ง:

$ git reset --hard HEAD

0

คำถามนี้เกี่ยวกับการรีเซ็ต / เปลี่ยนที่เก็บในวงกว้างที่กว้างขึ้น แต่ในกรณีที่คุณสนใจที่จะคืนค่าการเปลี่ยนแปลงแต่ละครั้ง - ฉันได้เพิ่มคำตอบที่คล้ายกันไว้ที่นี่:

https://stackoverflow.com/a/60890371/2338477

คำตอบสำหรับคำถาม:

  • วิธีการย้อนกลับการเปลี่ยนแปลงรายบุคคลโดยมีหรือไม่มีการเปลี่ยนแปลงที่สงวนไว้ในประวัติคอมไพล์

  • วิธีการคืนกลับเป็นเวอร์ชันเก่าเพื่อรีสตาร์ทจากสถานะเดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.