Vứt bỏ các cam kết địa phương trong Git


1469

Do một số lựa chọn anh đào xấu, kho Git địa phương của tôi hiện có năm cam kết trước nguồn gốc và không ở trạng thái tốt. Tôi muốn thoát khỏi tất cả các cam kết này và bắt đầu lại.

Rõ ràng, xóa thư mục làm việc của tôi và sao chép lại sẽ làm điều đó, nhưng tải xuống mọi thứ từ GitHub một lần nữa có vẻ như quá mức cần thiết, và không sử dụng tốt thời gian của tôi.

Có thể git revertlà những gì tôi cần, nhưng tôi không muốn kết thúc 10 lần cam kết trước nguồn gốc (hoặc thậm chí là sáu), ngay cả khi nó tự đưa mã trở lại đúng trạng thái. Tôi chỉ muốn giả vờ nửa tiếng cuối cùng không bao giờ xảy ra.

Có một lệnh đơn giản sẽ làm điều này? Nó có vẻ như là một trường hợp sử dụng rõ ràng, nhưng tôi không tìm thấy bất kỳ ví dụ nào về nó.


Lưu ý rằng câu hỏi này là cụ thể về các cam kết , không phải về:

  • tập tin không bị theo dõi
  • thay đổi không theo giai đoạn
  • dàn dựng, nhưng thay đổi không cam kết

Câu trả lời:


2470

Nếu các cam kết vượt quá của bạn chỉ hiển thị với bạn, bạn có thể thực hiện git reset --hard origin/<branch_name> để quay lại vị trí ban đầu. Điều này sẽ đặt lại trạng thái của kho lưu trữ về cam kết trước đó và nó sẽ loại bỏ tất cả các thay đổi cục bộ.

Làm một git revertlàm cho mới cam kết để loại bỏ cam kết theo một cách mà giữ lành mạnh lịch sử của tất cả mọi người.


91
git reset --hard <commit hash, branch, or tag>nếu bạn muốn đi đến một tài liệu tham khảo cụ thể khác với một chi nhánh từ xa.
Sam Soffes

55
Nói rõ hơn, nếu bạn không làm việc masternhưng ở một chi nhánh khác, bạn nên chạygit reset --hard origin/<your-branch-name>
Zoltán

33
Điều này sẽ không chỉ loại bỏ các cam kết cục bộ, mà còn vứt bỏ mọi thứ trong cây công việc của bạn (ví dụ: các tệp cục bộ của bạn). Nếu tất cả những gì bạn muốn làm là không phổ biến, nhưng vẫn giữ nguyên công việc của bạn, bạn nên thực hiện "git reset HEAD ^" ... mỗi stackoverflow.com/questions
2845631 / Lỗi

3
Bạn có thể muốn thực hiện Tìm nạp sau này. Điều này đã cố định bộ đếm số lần cam kết chờ đợi để được đẩy trên SourceTree.
Stan

2
git reset --hard origin/<branch_name>Nó cũng sẽ thiết lập lại cấu hình dự án, vì vậy hãy quan tâm đến điều này. Tôi có một .cfgtập tin lớn được đặt lại về mặc định. Tôi đã phải dành hàng giờ cho điều đó một lần nữa.
MAC

271

Chỉ cần xóa chi nhánh chính cục bộ của bạn và tạo lại nó như vậy:

git branch -D master
git checkout origin/master -b master

2
Điều này hoạt động tốt khi quay lại các thay đổi của bạn sẽ tốn quá nhiều thời gian, điều này đã xảy ra với tôi sau một vài lần nổi loạn.
vào

1
Hữu ích cho các vấn đề kéo / đẩy giữa các thành viên trong nhóm!
Jorge Orpinel

Điều này là hoàn hảo khi bạn muốn khôi phục một nhánh thay vì chỉ chủ.
Vladimir Ralev

1
đây không phải là một cách tốt để xóa một cam kết cục bộ. Sử dụng tốt hơngit reset --hard origin/<branch_name>
Kirit Vaghela

1
Có thể giải pháp đó sẽ hiệu quả, nhưng điều đó không có nghĩa đó là giải pháp phù hợp.
Adly

202

Thử:

git reset --hard <the sha1 hash>

để thiết lập lại đầu của bạn đến bất cứ nơi nào bạn muốn. Sử dụng gitk để xem cam kết nào bạn muốn tham gia. Bạn cũng có thể thiết lập lại trong gitk.


5
Đã đưa ra thông tin hữu ích này, nhưng câu trả lời của Ben Jackson được đánh dấu để giải quyết chính xác những gì tôi muốn - theo cách không yêu cầu tôi phải tra cứu băm. :)
David Moles

2
Đây là chi nhánh khi chi nhánh mới của bạn chưa bao giờ được đẩy về nguồn gốc
1

126

Xóa cam kết gần đây nhất:

git reset --hard HEAD~1

Xóa các cam kết gần đây nhất mà không phá hủy công việc bạn đã thực hiện:

git reset --soft HEAD~1


5
Câu trả lời hữu ích. Cảm ơn bạn! Tôi đã sử dụng git reset --soft origin / master
Tarun Kumar

2
@TarunKumar CẢM ƠN BẠN! Tôi đang sử dụng tích hợp VS và giải pháp của bạn là cách duy nhất tôi có thể xóa sạch một loạt các cam kết hợp nhất mà tôi không muốn trong một chi nhánh mà tôi không được phép đăng ký.
DVK

Cảm ơn, đúng như những gì tôi đang tìm kiếm, "git reset --soft HEAD ~ 1" đã thực hiện công việc khi tôi vô tình phạm phải và muốn hoàn nguyên nhưng có các tệp khác mà tôi không muốn bị hủy sau khi hoàn nguyên.
edvard_munch

47

Nếu bạn đang sử dụng ứng dụng Atlassian SourceTree , bạn có thể sử dụng tùy chọn đặt lại trong menu ngữ cảnh.

nhập mô tả hình ảnh ở đây


42

Trên nỗ lực chi nhánh của bạn:

git reset --hard origin/<branch_name>

Xác thực sự đảo ngược (với trạng thái, không có cam kết cục bộ), do đó sử dụng " git log" hoặc " git status".


1
@Troyseph: tất cả các câu trả lời được liệt kê ở trên, tôi đã cố gắng như vậy và không sửa được kịch bản. Cách tiếp cận chung chung, không được minh họa trong bất kỳ câu trả lời nào ở trên, là những gì đã được cố gắng trả lời ở đây.
ký sinh

3
Câu trả lời được chấp nhận giống như của bạn, trừ tên chi nhánh chung và trong các nhận xét @Zoltan nói rõ ràngJust to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph

1
Đây là câu trả lời tốt nhất theo ý kiến ​​của tôi.
dwjohnston

21

git reset --hard @{u}* xóa tất cả các thay đổi cục bộ của bạn trên nhánh hiện tại, bao gồm cả các xác nhận. Tôi ngạc nhiên không ai đăng bài này vì bạn sẽ không phải tìm kiếm những gì cam kết hoàn nguyên hoặc chơi với các chi nhánh.

* Nghĩa là, đặt lại về chi nhánh hiện tại tại @{upstream}tầm tay origin/<branchname>, nhưng không phải lúc nào cũng


1
Một số vỏ như cá sẽ diễn giải "@" vì vậy bạn có thể phải đặt '@ {u}' trong dấu ngoặc kép, ví dụ `git reset --hard '@ {u}'. Dù sao, tìm tốt!
phân tích

Câu trả lời tuyệt vời là tuyệt vời
Marko

1
Làm thế nào để bạn in giá trị của @ {u}?
Philip Rego

12

Để xem / nhận id SHA-1 của cam kết bạn cũng muốn quay lại

gitk --all

Để quay trở lại cam kết đó

git reset --hard sha1_id

!Ghi chú. Tất cả các cam kết được thực hiện sau cam kết đó sẽ bị xóa (và tất cả các sửa đổi của bạn đối với dự án). Vì vậy, đầu tiên tốt hơn nhân bản dự án sang một chi nhánh khác hoặc sao chép vào một thư mục khác.


điều này rất tốt cho các tình huống mà điều khiển từ xa không còn nữa và người ta chỉ cần đặt lại thành một số cam kết cục bộ. gitk là tuyệt vời - đã không nhận thức được nó trước đó.
theRiley

Nếu bạn đã ở trong gitk, bạn cũng có thể chỉ cần nhấp chuột phải vào cam kết và chọn "đặt lại nhánh XY về đây".
mkrieger1

Và các cam kết mới hơn sẽ không bị xóa ngay lập tức. Không còn chi nhánh nào chỉ vào họ nữa (hãy nhớ rằng, một chi nhánh không là gì ngoài "dấu trang" cho một cam kết cụ thể).
mkrieger1

9

Tôi đã có một tình huống mà tôi muốn loại bỏ một cam kết không được thúc đẩy, nhưng cam kết đó trước một cam kết khác. Để làm như vậy, tôi đã sử dụng lệnh sau

git rebase -i HEAD~2 -> nó sẽ khởi động lại hai lần xác nhận cuối cùng

Và tôi đã sử dụng 'thả' cho chữ ký cam kết mà tôi muốn xóa.


9

Xóa các tệp không bị theo dõi (thay đổi cục bộ không được cam kết)

git clean -df

Xóa vĩnh viễn tất cả các xác nhận cục bộ và nhận cam kết từ xa mới nhất

git reset --hard origin/<branch_name>

8

Đối với các xác nhận cục bộ không được đẩy, bạn cũng có thể sử dụng git rebase -iđể xóa hoặc xóa một cam kết.


1
Tôi biết đây có thể không phải là giải pháp ngắn nhất, nhưng tôi đã ủng hộ bạn vì IMHO git rebase -ilà một cách chung hơn để giải quyết nhiều vấn đề tương tự và có thể hữu ích trong nhiều tình huống.
Stefan Marinov

1
Sử dụng droptừ khóa (thay vì xóa một dòng) khi xóa tất cả các cam kết để tránh bị hủy bỏ rebase.
Michal izmazia

6

Giải pháp đơn giản sẽ phù hợp với chi nhánh chính cục bộ CHÍNH với nguồn gốc / chi nhánh chính

git reset --hard origin/master

PS: origin / master - là con trỏ từ xa đến nhánh master. Bạn có thể thay thế chủ bằng bất kỳ tên chi nhánh


4

Trước khi trả lời, hãy thêm một số nền tảng, giải thích đây là gì HEAD. vì một số tùy chọn bên dưới sẽ dẫn đến đầu bị tách ra

First of all what is HEAD?

HEADchỉ đơn giản là một tham chiếu đến cam kết hiện tại (mới nhất) trên nhánh hiện tại.
Chỉ có thể có một duy nhất HEADtại bất kỳ thời điểm nào. (không bao gồmgit worktree )

Nội dung của HEADđược lưu trữ bên trong .git/HEADvà nó chứa 40 byte SHA-1 của cam kết hiện tại.


detached HEAD

Nếu bạn không tham gia vào cam kết mới nhất - có nghĩa HEADlà chỉ đến một cam kết trước đó trong lịch sử được gọi là cam kết detached HEAD.

nhập mô tả hình ảnh ở đây

Trên dòng lệnh, nó sẽ trông như thế này- SHA-1 thay vì tên chi nhánh vì HEADnó không trỏ đến đầu của nhánh hiện tại

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Một vài lựa chọn về cách phục hồi từ một ĐẦU tách ra:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Điều này sẽ kiểm tra chi nhánh mới chỉ vào cam kết mong muốn.
Lệnh này sẽ kiểm tra một cam kết nhất định.
Tại thời điểm này, bạn có thể tạo một nhánh và bắt đầu làm việc từ thời điểm này.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Bạn luôn có thể sử dụng refloglà tốt.
git reflogsẽ hiển thị bất kỳ thay đổi nào đã cập nhật HEADvà kiểm tra mục nhập reflog mong muốn sẽ đặt HEADlại cho cam kết này.

Mỗi khi sửa đổi ĐẦU sẽ có một mục mới trong reflog

git reflog
git checkout HEAD@{...}

Điều này sẽ đưa bạn trở lại cam kết mong muốn của bạn

nhập mô tả hình ảnh ở đây


git reset --hard <commit_id>

"Di chuyển" ĐẦU của bạn trở lại cam kết mong muốn.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Lưu ý: ( Kể từ Git 2.7 ),
    bạn cũng có thể sử dụng git rebase --no-autostash.

git revert <sha-1>

"Hoàn tác" phạm vi cam kết hoặc cam kết đã cho.
Lệnh đặt lại sẽ "hoàn tác" mọi thay đổi được thực hiện trong cam kết đã cho.
Một cam kết mới với bản vá hoàn tác sẽ được cam kết trong khi cam kết ban đầu cũng sẽ vẫn còn trong lịch sử.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Lược đồ này minh họa lệnh nào làm gì.
Như bạn có thể thấy có reset && checkoutsửa đổi HEAD.

nhập mô tả hình ảnh ở đây


3

Đối với những người quan tâm đến giải pháp Visual Studio, đây là bài tập:

  1. Trong Team Explorercửa sổ, kết nối với repo mục tiêu.
  2. Sau đó Branches, nhấp chuột phải vào nhánh quan tâm và chọnView history .
  3. Nhấp chuột phải vào một cam kết trong Historycửa sổ và chọn Reset -> Delete changes (--hard).

Điều đó sẽ loại bỏ các cam kết cục bộ của bạn và đặt lại trạng thái repo của bạn thành cam kết đã chọn. Tức là những thay đổi của bạn sau khi bạn kéo repo sẽ bị mất.


2

Nếu chi nhánh của bạn đi trước ' origin/XXX' bởi 5 lần cam kết.

Bạn có thể phát hành:

git reset --hard HEAD~5

Và nó sẽ loại bỏ 5 cam kết cuối cùng.


0
git reset --hard <SHA-Code>

Điều này sẽ có ích nếu bạn đã mắc một số lỗi trên bản sao cục bộ mà bạn muốn đảm bảo không bị đẩy đến chi nhánh từ xa do nhầm lẫn.

Mã SHA có thể thu được bằng cách xem webVersion của bảng điều khiển git của bạn để biết lần cam kết cuối cùng trên nhánh.

Bằng cách này bạn có thể được đồng bộ hóa với cam kết cuối cùng trên chi nhánh.

Bạn có thể làm git pullsau khi hoàn thành thiết lập lại cứng để xác nhận không có gì mới để đồng bộ tức là bạn có thể xem tin nhắn.

Chi nhánh của bạn được cập nhật với Origin/<Branch Name>


0

Nếu bạn nhận được repo cục bộ của mình thành một mớ hỗn độn, thì một cách đáng tin cậy để loại bỏ các cam kết cục bộ trong Git là ...

  1. Sử dụng "git config --get remote.origin.url" để lấy URL có nguồn gốc từ xa
  2. Đổi tên thư mục git cục bộ thành "my_broken_local_Vpo"
  3. Sử dụng "git clone <url_from_1>" để có bản sao cục bộ mới của kho git từ xa

Theo kinh nghiệm của tôi, Eclipse xử lý thế giới thay đổi xung quanh nó khá tốt. Tuy nhiên, bạn có thể cần chọn các dự án bị ảnh hưởng trong Eclipse và làm sạch chúng để buộc Eclipse xây dựng lại chúng. Tôi đoán các IDE khác cũng có thể cần phải xây dựng lại.

Một lợi ích phụ của quy trình trên là bạn sẽ tìm hiểu xem dự án của bạn có dựa vào các tệp cục bộ không được đưa vào git hay không. Nếu bạn thấy bạn đang thiếu các tệp thì bạn có thể sao chép chúng từ "my_broken_local_Vpo" và thêm chúng vào git. Khi bạn tin tưởng rằng repo cục bộ mới của bạn có mọi thứ bạn cần thì bạn có thể xóa "my_broken_local_Vpo".


0

Nếu bạn chỉ muốn loại bỏ các xác nhận cục bộ và giữ các sửa đổi được thực hiện trong các tệp thì hãy thực hiện
git reset @ ~
Các câu trả lời khác giải quyết việc thiết lập lại cứng

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.