Xóa các xác nhận từ một chi nhánh trong Git


3233

Tôi muốn biết làm thế nào để xóa một cam kết.

Bởi delete, ý tôi là như thể tôi đã không thực hiện cam kết đó và khi tôi thực hiện một nỗ lực trong tương lai, những thay đổi của tôi sẽ không được đẩy đến chi nhánh từ xa.

Tôi đọc trợ giúp git, và tôi nghĩ lệnh tôi nên sử dụng là git reset --hard HEAD. Điều này có đúng không?


41
Tôi nghĩ rằng đây không phải là một bản sao của Git hoàn tác cam kết cuối cùng vì nó hỏi làm thế nào để xóa bất kỳ cam kết nào khỏi một chi nhánh. Tôi cũng nghĩ rằng không có câu trả lời thực sự giải quyết câu hỏi này. Tất cả đều tua lại các cam kết cuối cùng, không phải cherry-pickdeletemột cam kết duy nhất có thể xảy ra cách đây một thời gian.
Chris

12
@Chris, câu trả lời git rebase -i HEAD~10không giải quyết câu hỏi, vì nó cho phép bạn tùy ý chọn các cam kết để xóa. Git áp dụng các xác nhận trong phạm vi bạn chỉ định từng cái một, bỏ qua các xác nhận bạn đã xóa khỏi nhật ký. Tôi đã sử dụng lệnh này ngày hôm nay để loại bỏ các cam kết gần đây thứ hai và thứ ba đối với repo của tôi trong khi vẫn giữ vị trí hàng đầu. Tôi đồng ý rằng không có câu trả lời nào khác là thỏa đáng.
MST

@MST có, tôi nên nói, không phải trong số các tùy chọn trong câu trả lời được chấp nhận giải quyết câu hỏi này, nhưng bạn hoàn toàn đúng - lệnh đó dường như hoạt động
Chris

Câu trả lời:


4127

Cẩn thận: git reset --hard S DEL XÓA CÁC THAY ĐỔI TRỰC TIẾP LÀM VIỆC CỦA BẠN . Hãy chắc chắn để xóa bất kỳ thay đổi cục bộ nào bạn muốn giữ trước khi chạy lệnh này.

Giả sử bạn đang ngồi trên cam kết đó, thì lệnh này sẽ xử lý nó ...

git reset --hard HEAD~1

Nghĩa HEAD~1là cam kết trước đầu.

Hoặc, bạn có thể xem kết quả đầu ra git log, tìm id xác nhận của cam kết bạn muốn sao lưu và sau đó thực hiện việc này:

git reset --hard <sha1-commit-id>

Nếu bạn đã đẩy nó, bạn sẽ cần phải thực hiện một cú đẩy mạnh mẽ để thoát khỏi nó ...

git push origin HEAD --force

Tuy nhiên , nếu những người khác có thể đã kéo nó, thì bạn nên bắt đầu một chi nhánh mới. Bởi vì khi họ kéo, nó sẽ hợp nhất nó vào công việc của họ, và bạn sẽ khiến nó bị đẩy ngược trở lại.

Nếu bạn đã đẩy, có thể tốt hơn để sử dụng git revert, để tạo một cam kết "hình ảnh phản chiếu" sẽ hoàn tác các thay đổi. Tuy nhiên, cả hai cam kết sẽ có trong nhật ký.


FYI - git reset --hard HEADthật tuyệt nếu bạn muốn thoát khỏi CÔNG VIỆC TRONG TIẾN ĐỘ. Nó sẽ đặt lại bạn về cam kết gần đây nhất và xóa tất cả các thay đổi trong cây và chỉ mục làm việc của bạn.


Cuối cùng, nếu bạn cần tìm một cam kết mà bạn đã "xóa", nó thường xuất hiện git reflogtrừ khi bạn có rác được thu thập kho lưu trữ của bạn.


59
HEAD~1hoặc chỉ HEAD^. Nếu bạn đẩy, bạn nên sử dụng git revertthay thế.
Jakub Narębski

13
Rõ ràng bạn cũng có thể sử dụng HEAD~nđể "quay lại" các ncam kết từ đầu của mình. Có thể từ thời điểm này, bạn cũng có thể hiểu ... --hard HEADHEAD~0=> xóa công việc đang tiến hành.
Nuala

13
@ Beamrider9 imho git rebase hầu như luôn là cách tốt hơn để xóa các cam kết (như được mô tả trong câu trả lời của Greg Hewgill) - thực tế không phải vì rebase thực tế bao gồm một cảnh báo lớn rằng bạn sẽ xóa nội dung 4realz.

20
điều này không xóa các thay đổi từ cây cam kết mặc dù. OP yêu cầu một cam kết đã được thực hiện. Nếu bạn reset --hardvà kiểm tra log --oneline --all, các xác nhận vẫn còn trong cây. Làm thế nào để chúng ta xóa những cam kết này từ cây? Cảm ơn.
iGbanam 17/03/13

17
sử dụng reset --softđể xóa cam kết cục bộ MÀ KHÔNG hoàn nguyên công việc đang tiến hành!

704

Nếu bạn chưa đẩy cam kết ở bất cứ đâu, bạn có thể sử dụng git rebase -iđể xóa cam kết đó. Đầu tiên, tìm hiểu mức độ cam kết đó là bao xa (khoảng). Sau đó làm:

git rebase -i HEAD~N

~Nnghĩa là rebase các Ncam kết cuối cùng ( Nví dụ phải là một số HEAD~10). Sau đó, bạn có thể chỉnh sửa tệp mà Git trình bày cho bạn để xóa cam kết vi phạm. Khi lưu tệp đó, Git sau đó sẽ viết lại tất cả các cam kết sau đây như thể tệp bạn đã xóa không tồn tại.

Sách Git có một phần hay về việc nổi loạn với hình ảnh và ví dụ.

Mặc dù vậy, hãy cẩn thận với điều này, bởi vì nếu bạn thay đổi thứ gì đó mà bạn đã đẩy ở nơi khác, sẽ cần một cách tiếp cận khác trừ khi bạn có kế hoạch thực hiện một động tác đẩy.


2
Lưu ý: Nếu bạn tình cờ có bất kỳ sự hợp nhất --no-ff nào trong đợt xác nhận cuối cùng đó, rebase sẽ bán chúng :( Điều này được đề cập dưới -p trên trang này . Vấn đề là, nếu bạn thay thế -i bằng -p, bạn không còn nhận được điều đó với các lựa chọn cho "chỉnh sửa cam kết này, sqush that one", v.v ... Có ai biết giải pháp không?
Bukov

4
Điều gì nếu bạn đã đẩy nó? (chỉ tôi sử dụng repo từ xa)
Costa

6
@Costa bạn có thể sử dụng push -fđể buộc đẩy và thay thế nhánh từ xa bằng nhánh cục bộ của bạn. Nếu đó chỉ là repo từ xa của riêng bạn, không có vấn đề gì. Rắc rối bắt đầu nếu ai đó đã tìm nạp trong lúc đó.
Greg Hewgill

3
Tôi đã thêm và cam kết một tệp dữ liệu quá lớn đối với GitHub (vâng, dù sao thì nó cũng không nên có trong repo nguồn; Oh tốt). Khi tôi cố gắng đẩy, GitHub đã từ chối vì tệp quá lớn. Tất cả những gì tôi muốn làm là hoàn tác một cam kết này, trong khi lưu một vài cam kết không liên quan khác theo sau. Các git rebase -i HEAD~5lệnh là chính xác những gì tôi cần thiết để loại bỏ hoàn toàn này cam kết từ repo địa phương của tôi! Cảm ơn!
aldo 24/2/2015

4
@dumbledad: Với rebase -i, những thay đổi tương ứng với cam kết đã xóa không được giữ nguyên.
Greg Hewgill

517

Một khả năng khác là một trong những lệnh yêu thích cá nhân của tôi:

git rebase -i <commit>~1

Điều này sẽ bắt đầu rebase trong chế độ tương tác -itại điểm ngay trước khi cam kết bạn muốn đánh. Trình chỉnh sửa sẽ bắt đầu liệt kê tất cả các cam kết kể từ đó. Xóa dòng chứa cam kết bạn muốn xóa và lưu tệp. Rebase sẽ thực hiện phần còn lại của công việc, chỉ xóa cam kết đó và phát lại tất cả những thứ khác trở lại nhật ký.


3
thx, btw nếu bạn gặp phải bất kỳ vấn đề nào (như các cam kết trống) bạn có thể sử dụnggit rebase --continue
realgt

8
Thậm chí dễ dàng hơn: git rebase -i HEAD~1
mmell

2
Ái chà. git rebase -i HEAD~1thực sự làm sạch repo lên rất nhiều! Thật khó để nói chính xác những gì nó đã làm, nhưng toàn bộ mọi thứ trông gọn gàng hơn nhiều. Một chút đáng báo động, thực sự.
Charles Wood

7
Tôi nghĩ rằng đáng lưu ý rằng các cam kết không bị xóa sạch, chỉ bị xóa khỏi danh sách. Nếu bạn làm hỏng, bạn có thể lấy lại cam kết bằng cách sử dụng reflog .
Zaz

6
Là xóa dòng giống như d / drop?
Leo

345

Tôi đang nối thêm câu trả lời này vì tôi không hiểu tại sao bất cứ ai vừa cố gắng thực hiện công việc đều muốn xóa tất cả công việc đó vì một số sai lầm khi sử dụng Git!

Nếu bạn muốn giữ công việc của mình và chỉ 'hoàn tác' lệnh đó (bạn đã bắt trước khi đẩy sang repo):

git reset --soft HEAD~1

Không sử dụng cờ - trừ khi bạn muốn hủy công việc của mình trong tiến trình kể từ lần cam kết cuối cùng.


5
Đây là một ví dụ về lý do tại sao: bạn thực hiện một công việc nhỏ trên máy chủ phát triển mà bạn cam kết. Sau đó, hóa ra máy chủ đó không có quyền truy cập HTTPS, vì vậy bạn không thể thực hiện cam kết ở bất cứ đâu. Dễ nhất là giả vờ như nó không bao giờ xảy ra và làm lại bản vá từ máy cục bộ của bạn.
Steve Bennett

1
@KarthikBose sẽ luôn có reflog. ngay cả sau khi git reset --hard HEAD~1cam kết mới nhất trước đó của bạn sẽ có sẵn thông qua reflog (cho đến khi bạn hết hạn); xem thêm tại đây: git yet.com/inter liền / 2009/02/09 / từ
mã hóa

4
Cảm ơn. Câu trả lời này nên được xếp hạng cao hơn hoặc bao gồm trong câu trả lời được chấp nhận. Xóa một cam kết! = Hoàn nguyên một cam kết.
Alsciende

2
@RandolphCarter: bạn vẫn sẽ mất mọi thay đổi không được cam kết.
ness101

7
@Rob, một ví dụ là khi bạn vô tình cam kết một tệp có chứa một bí mật (ví dụ: mật khẩu) không bao giờ được kiểm soát nguồn. Cam kết cục bộ phải bị hủy , không chỉ hoàn tác, vì vậy nó sẽ không bao giờ bị đẩy đến máy chủ.
Bob Meyers

142

Xóa toàn bộ cam kết

git rebase -p --onto SHA^ SHA

Rõ ràng thay thế "SHA" bằng tham chiếu mà bạn muốn loại bỏ. "^" Trong lệnh đó là bằng chữ.

http://sethrobertson.github.io/GitFixUm/fixup.html#change_deep


26
Làm thế nào tôi có thể nâng cao hơn câu trả lời này ??? các giải pháp khác chỉ cho thấy cách thực hiện tương tác hoặc loại bỏ các cam kết hàng đầu.
ribamar

5
-p, --preserve-merges Tái tạo các cam kết hợp nhất thay vì làm phẳng lịch sử bằng cách phát lại các cam kết hợp nhất giới thiệu. Hợp nhất các giải pháp xung đột hoặc sửa đổi thủ công để hợp nhất các cam kết không được bảo tồn.
raitt

5
Đây là câu trả lời chính xác thực tế
Hamman Samuel

9
Nó nói, "thay thế SHA bằng tham chiếu mà bạn muốn loại bỏ" nhưng dòng có SHA trong đó hai lần. Đây là những gì tôi đã làm. git rebase -p --onto 5ca8832c120 ^ 5ca8832c120 Nhưng không có gì thay đổi. Tôi có nên sử dụng cùng một SHA hai lần? Nếu không, thì SHA nào cho cam kết bị xóa và SHA khác phải là gì?
Rubicksman

3
WOW, nó hoạt động hoàn hảo! Đây phải là câu trả lời được chấp nhận!
Liran H

51

Nếu bạn không công bố các thay đổi, để xóa cam kết mới nhất, bạn có thể làm

$ git reset --hard HEAD^

(lưu ý rằng điều này cũng sẽ loại bỏ tất cả các thay đổi không được cam kết; sử dụng cẩn thận).

Nếu bạn đã xuất bản cam kết bị xóa, hãy sử dụng git Revert

$ git revert HEAD

Điều đó đã không làm việc. Khi tôi git log, mọi thứ vẫn còn đó, bất kể tại sao tôi làm điều đó chỉ cần thêm nhiều cam kết. Tôi muốn làm sạch lịch sử.
Costa

@Costa: Cái gì không hoạt động (tức là bạn đã sử dụng phiên bản nào) và làm thế nào bạn git log?
Jakub Narębski

Tôi đã thử hầu hết mọi thứ trong phần hỏi đáp này. (Tôi đã thử git hoàn nguyên CHÍNH, gần đây nhất) Nhật ký git của tôi:tree = log --all --graph --format=format:'%C(bold blue)%h%C(reset) %C(dim black)%s%C(reset)%C(bold red)%d%C(reset) %C(green)by %an, %ar%C(reset)'
Costa

1
Tôi chỉ muốn xóa các xác nhận (như thể chúng chưa từng tồn tại). Tôi đã thực hiện một cuộc phiêu lưu mã hóa kỳ lạ, với một vài cam kết mới, và tất cả cuối cùng trở thành rác rưởi. Làm thế nào tôi có thể xóa chúng khỏi nhật ký git của tôi?
Costa

2
Holy crap gì đó kỳ diệu đã làm chính xác những gì tôi muốn .... một trong những lệnh đó đã làm điều đó? !!?!
Costa

44

Nói rằng chúng tôi muốn xóa cam kết 2 & 4 khỏi repo.

commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>

Lưu ý: Bạn cần có quyền quản trị đối với repo vì bạn đang sử dụng --hard-f.

  • git checkout b3d92c5 Kiểm tra các cam kết có thể sử dụng cuối cùng.
  • git checkout -b repair Tạo một chi nhánh mới để làm việc trên.
  • git cherry-pick 77b9b82 Chạy qua cam kết 3.
  • git cherry-pick 2c6a45b Chạy qua cam kết 1.
  • git checkout master Thanh toán chính chủ.
  • git reset --hard b3d92c5 Đặt lại chủ để cam kết có thể sử dụng cuối cùng.
  • git merge repair Hợp nhất chi nhánh mới của chúng tôi vào chủ.
  • git push -f origin master Đẩy chủ đến repo từ xa.

1
Bước cuối cùng sẽ git push -f origin masterkhông có tùy chọn--hard
Vivex

2
Tôi đoán commit 0là già hơn commit 1. Xin vui lòng cho tôi biết lý do tại sao đầu tiên chạy qua commit 3(bởi cherry-pick) và sau đó bởi commit 1? Sau khi thanh toán b3d92cd( commit 0) tôi sẽ mong đợi cherry-pick commit 1, sau đó commit 3. Cảm ơn.
Jarek C

@JarekC Tôi nghĩ rằng cam kết cao nhất là cam kết mới nhất ở đây, trừ khi tôi thấy có gì đó không ổn ...
Jeff Huijsmans

41
git reset --hard commitId

git push <origin> <branch> --force

PS: CommitId đề cập đến cái mà bạn muốn hoàn nguyên


git đẩy - lực lượng <origin> <BranchName>. vì không đề cập đến tên chi nhánh, nó có thể thay đổi tất cả các tập tin trên remote.
sheelpriy

39

Lịch sử thay đổi mạnh mẽ

Giả sử bạn không chỉ muốn xóa cam kết cuối cùng, nhưng bạn muốn xóa các cam kết cụ thể của n cam kết cuối cùng, hãy đi với:

git rebase -i HEAD~<number of commits to go back>, vì vậy git rebase -i HEAD~5nếu bạn muốn xem năm cam kết cuối cùng.

Sau đó, trong soạn thảo văn bản thay đổi từ pickđến dropbên cạnh mỗi cam kết mà bạn muốn loại bỏ. Lưu và thoát khỏi trình soạn thảo. Voila!

Lịch sử thay đổi bổ sung

Hãy thử git revert <commit hash>. Hoàn nguyên sẽ tạo ra một cam kết mới hoàn tác các cam kết đã chỉ định.


droptừ khóa không được xác định. Để xóa một cam kết chỉ cần xóa toàn bộ dòng.
Shaya Salehian

1
Đối với tôi drop được định nghĩa là một từ khóa, nhưng thực hiện một lần thả dường như không xóa được cam kết khỏi lịch sử. Tuy nhiên, loại bỏ dòng khỏi rebase tương tác đã làm.
Adam Parkin

Đây chính xác là những gì tôi cần. Công trình tuyệt vời; cảm ơn!
diekunstderfuge

30

Nếu bạn muốn sửa chữa cam kết mới nhất của mình, bạn có thể hoàn tác cam kết và hủy kích hoạt các tệp trong đó bằng cách thực hiện:

git reset HEAD~1

Điều này sẽ trả lại kho lưu trữ của bạn về trạng thái trước khi lệnh git add dàn dựng các tệp. Những thay đổi của bạn sẽ nằm trong thư mục làm việc của bạn. Đầu ~ 1 đề cập đến cam kết bên dưới đầu hiện tại của chi nhánh.

Nếu bạn muốn N không cam kết, nhưng hãy giữ các thay đổi mã trong thư mục làm việc của bạn:

git reset HEAD~N

Nếu bạn muốn thoát khỏi cam kết mới nhất của mình và không muốn giữ các thay đổi mã, bạn có thể thực hiện đặt lại "cứng".

git reset --hard HEAD~1

Tương tự, nếu bạn muốn loại bỏ N cam kết cuối cùng và không muốn giữ các thay đổi mã:

git reset --hard HEAD~N

22
git rebase -i HEAD~2

Ở đây '2' là số lần xác nhận bạn muốn khởi động lại.

'git rebase -i HEAD`

nếu bạn muốn rebase tất cả các cam kết.

Sau đó, bạn sẽ có thể chọn một trong những tùy chọn này.

p, pick = use commit

r, reword = use commit, but edit the commit message

e, edit = use commit, but stop for amending

s, squash = use commit, but meld into previous commit

f, fixup = like "squash", but discard this commit's log message

x, exec = run command (the rest of the line) using shell

d, drop = remove commit

Những dòng này có thể được đặt hàng lại; chúng được thực hiện từ trên xuống dưới. Nếu bạn xóa một dòng ở đây, thì CAM KẾT SILL ĐƯỢC MẤT. Tuy nhiên, nếu bạn loại bỏ mọi thứ, rebase sẽ bị hủy bỏ. Lưu ý rằng các cam kết trống được nhận xét

Bạn chỉ có thể xóa cam kết đó bằng tùy chọn "d" hoặc Xóa một dòng có cam kết của bạn.


Trong phiên bản git mới nhất không có thêm tùy chọn d . Bạn chỉ cần xóa các dòng có xác nhận từ rebase để xóa chúng.
Oleg Abrazhaev

17

Để xóa trong chi nhánh địa phương, sử dụng

git reset --hard HEAD~1

Để xóa trong một chi nhánh từ xa, sử dụng

git push origin HEAD --force

12

[Câu trả lời nhanh]

Bạn có nhiều lựa chọn thay thế, ví dụ:

  • Phương án 1:

    git rebase -i <YourCommitId>~1
    

    Thay đổi YourCommitId cho số lượng cam kết mà bạn muốn hoàn nguyên.

  • Phương án 2:

    git reset --hard YourCommitId
    git push <origin> <branch> --force
    

    Thay đổi YourCommitId cho số lượng cam kết mà bạn muốn hoàn nguyên.

    Tôi không đề xuất tùy chọn này vì bạn có thể mất công việc đang tiến hành.

  • Phương án 3:

    git reset --soft HEAD~1
    

    Bạn có thể giữ công việc của bạn và chỉ hoàn tác cam kết.


thankyou thankyou thankyou thankyou (Y)
Habib Rehman

11

Nguồn: https://gist.github.com/sagarjethi/c07723b2f4fa74ad8bdf229166cf79d8

Xóa cam kết cuối cùng

Ví dụ như cam kết cuối cùng của bạn

nguồn gốc git đẩy + aa61ab32 ^: chủ

Bây giờ bạn muốn xóa cam kết này, một cách dễ dàng để làm điều này sau đây

Các bước

  1. Đầu tiên đặt lại nhánh thành cha mẹ của cam kết hiện tại

  2. Buộc nó đẩy nó ra xa.

git reset HEAD^ --hard

git push origin -f

Đối với cam kết cụ thể, bạn muốn đặt lại theo sau

git reset bb676878^ --hard

git push origin -f

9

Đây là một cách khác để làm điều này:

Kiểm tra chi nhánh bạn muốn hoàn nguyên, sau đó đặt lại bản sao làm việc cục bộ của bạn trở lại cam kết mà bạn muốn là bản mới nhất trên máy chủ từ xa (mọi thứ sau đó sẽ tạm biệt). Để thực hiện việc này, trong SourceTree, tôi đã nhấp chuột phải vào và chọn "Đặt lại BRANCHNAME cho cam kết này". Tôi nghĩ rằng dòng lệnh là:

git reset --hard COMMIT_ID

Vì bạn vừa kiểm tra chi nhánh của mình từ xa, bạn sẽ không có bất kỳ thay đổi cục bộ nào để lo lắng về việc mất. Nhưng điều này sẽ mất chúng nếu bạn đã làm.

Sau đó điều hướng đến thư mục cục bộ của kho lưu trữ của bạn và chạy lệnh này:

git -c diff.mnemonicprefix=false -c core.quotepath=false \
push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

Điều này sẽ xóa tất cả các xác nhận sau cái hiện tại trong kho lưu trữ cục bộ của bạn nhưng chỉ cho một nhánh đó.


9

Lỗi lầm:

Tôi git rebase -i --rootlà chi nhánh của mình, thờ ơ nghĩ rằng tôi có thể điều chỉnh lại cam kết đầu tiên khác với chủ ( chế độ xem mặc định của GitHub cho Windows là so sánh với chủ, ẩn toàn bộ).

Tôi đã mọc râu ở Thung lũng Silicon trong khi hơn 900 cam kết tự nạp vào Sublime. Thoát ra mà không có thay đổi, tôi sạc pin sau đó tiến hành cạo râu, vì tất cả hơn 900 cá nhân cam kết không bị từ chối - đặt lại thời gian cam kết của họ cho đến bây giờ.

Quyết tâm đánh bại Git và giữ nguyên thời gian ban đầu, tôi đã xóa kho lưu trữ cục bộ này và sao chép lại từ xa.

Bây giờ nó đã thêm lại một cam kết không cần thiết gần đây nhất đối với chủ tôi muốn xóa, vì vậy đã tiến hành như vậy.

Làm cạn kiệt các tùy chọn:

Tôi không muốn git revert- nó sẽ tạo ra một cam kết bổ sung, giúp Git chiếm thế thượng phong.

git reset --hard HEADkhông làm gì cả, sau khi kiểm tra reflog, cái cuối cùng và duy nhất HEADlà bản sao - Git thắng.

Để có được SHA gần đây nhất, tôi đã kiểm tra kho lưu trữ từ xa trên github.com - thắng nhỏ.

Sau khi suy nghĩ git reset --hard <SHA>đã hoạt động, tôi cập nhật một chi nhánh khác thành chủ và 1 ... 2 ... gặp sự cố! cam kết đã trở lại - Git thắng.

Kiểm tra lại để làm chủ, thời gian để thử git rebase -i <SHA>, sau đó xóa dòng ... vô ích, buồn để nói. " Nếu bạn xóa một dòng ở đây, thì CAM KẾT SILL ĐƯỢC MẤT ". À ... phủ bóng lên tính năng mới troll n00b trong ghi chú phát hành 2.8.3 .

Giải pháp:

git rebase -i <SHA>sau đó d, drop = remove commit.

Để xác minh, tôi đã kiểm tra đến một chi nhánh khác và voila - không có cam kết ẩn để lấy / kéo từ chủ.

https://twitter.com/holman/status/706006896273063936

Chúc một ngày tốt lành.


8

Tất cả các lệnh trên khôi phục trạng thái của cây công việc và lập chỉ mục như trước khi thực hiện cam kết, nhưng không khôi phục trạng thái của kho lưu trữ. Nếu bạn nhìn vào nó, cam kết "bị loại bỏ" không thực sự bị xóa, nó chỉ đơn giản không phải là một trong các đầu của nhánh hiện tại.

Tôi nghĩ rằng không có cách nào để loại bỏ một cam kết với các lệnh sứ . Cách duy nhất là xóa nó khỏi nhật ký và reflog và sau đó thực thi a git prune --expire -now.


1
Thứ tự mà các câu trả lời được hiển thị trên StackOverflow không cố định. Vui lòng không tham khảo về Tất cả các lệnh ở trên. Làm cho câu trả lời của riêng bạn khép kín.
Pascal Cuoq

Câu trả lời này không hoàn toàn chính xác. git prune thực sự là một trong những lệnh "sứ" . Ngoài ra, rất hiếm khi bạn muốn xóa hoàn toàn reflog của mình (một trường hợp sử dụng là xóa thông tin nhạy cảm khỏi repo của bạn, nhưng như tôi đã nói, đó là trường hợp sử dụng hiếm gặp). Thường xuyên hơn không, bạn sẽ muốn giữ các cam kết cũ xung quanh trong reflog, trong trường hợp bạn cần khôi phục dữ liệu. Xem Pro Git: 9.7 Git Internals - Bảo trì và phục hồi dữ liệu .

8

Nếu bạn muốn giữ lịch sử, hiển thị cam kết và hoàn nguyên, bạn nên sử dụng:

git revert GIT_COMMIT_HASH

nhập tin nhắn giải thích lý do tại sao bạn hoàn nguyên và sau đó:

git push  

Khi bạn phát hành, git logbạn sẽ thấy cả thông báo nhật ký "sai" và hoàn nguyên.


Có, nhưng OP rõ ràng đó không phải là điều họ muốn.
Steve Bennett

7

Nếu bạn vừa làm hỏng cam kết cuối cùng của mình (thông báo sai, quên thêm một số thay đổi) và muốn sửa nó trước khi đẩy nó sang repo công khai tại sao không sử dụng:

git commit --amend -m "New message here"

Nếu bạn có các thay đổi mới được tổ chức, chúng sẽ được kết hợp với cam kết cuối cùng (mà bạn đang cố gắng loại bỏ) và sẽ thay thế cam kết đó.

Tất nhiên, nếu bạn sửa đổi một cam kết sau khi bạn đã đẩy nó, bạn sẽ viết lại lịch sử vì vậy nếu bạn làm điều đó chắc chắn sẽ hiểu được ý nghĩa.

Bạn cũng có thể vượt qua tùy chọn '--no-edit' thay vì '-m' nếu bạn muốn sử dụng tin nhắn của cam kết trước đó.

Tài liệu: http://git-scm.com/docs/git-commit.html


2
Đó không phải là những gì OP đang yêu cầu.
Steve Bennett

5

Nếu bạn đã đẩy, trước tiên hãy tìm cam kết bạn muốn ở CHÍNH ($ GIT_COMMIT_HASH_HERE) , sau đó chạy như sau:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

Sau đó, mỗi nơi repo đã được nhân bản, chạy:

git reset --hard origin/master

5

Những gì tôi thường làm khi tôi cam kết và thúc đẩy (nếu có ai thúc đẩy cam kết này sẽ giải quyết vấn đề):

git reset --hard HEAD~1

git push -f origin

hy vọng điều này giúp đỡ


5

Tôi đã đẩy rồi. Cần phải trả lại một số cam kết trở lại từ xa. Đã thử nhiều biến thể, nhưng chỉ có điều này từ Justin thông qua git bush hoạt động tốt với tôi:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

4

Đặt lại trên chi nhánh địa phương

git reset --hard HEAD~<Number of commit> So git reset --hard HEAD~3

Lực đẩy về nguồn gốc

git push -f origin

3

Sao lưu mã của bạn vào thư mục tạm thời. Lệnh sau sẽ thiết lập lại giống như máy chủ.

git reset --hard HEAD
git clean -f
git pull

Nếu bạn muốn giữ các thay đổi của mình và xóa các cam kết gần đây

git reset --soft HEAD^
git pull


2

xóa cam kết cục bộ

Như bạn có thể thấy trên hình ảnh trên, tôi muốn xóa xác nhận "thay đổi thử nghiệm 2" (SHA1 ID: 015b5220c50e3dfbb1063f23789d92ae1d3481a2 (bạn có thể nhận ID SHA1 bằng cách sử dụnggitk lệnh trong git bash).

Để tôi có thể sử dụng (tất cả các lệnh bên dưới chỉ hoạt động trên cục bộ. Bạn cần đẩy sau khi xóa):

  1. git reset --hard 515b5220c50e3dfbb1063f23789d92ae1d3481a2// nó sao lưu cho bạn cam kết đó (ID SHA1 của thay đổi thử nghiệm 4 cam kết là 515b5220c50e3dfbb1063f23789d92ae1d3481a2 )
  2. git reset --hard HEAD~1 // nó sao lưu bạn trước khi một cam kết.
  3. git reset --hard HEAD^ // Để xóa cam kết cuối cùng khỏi git

sau khi xóa:

sau khi xóa cam kết


2

git reset --hard HEAD~1
Bây giờ bạn sẽ ở đầu trước. Kéo cành cây. Đẩy mã mới. Cam kết sẽ bị xóa khỏi git


Trừ khi bạn đã thúc đẩy những thay đổi. Trong trường hợp đó, thiết lập lại cứng sẽ không làm sạch điều khiển từ xa của bạn. Trong trường hợp đó, rebase là lựa chọn tốt
c0der512 ngày

1

thiết lập lại git -

git đẩy nguồn gốc CHÍNH - lực lượng

Nếu một hoặc nhiều cam kết được gắn thẻ, trước tiên hãy xóa (các) thẻ. Nếu không, cam kết được gắn thẻ sẽ không được gỡ bỏ.


0

sử dụng git Revert https://git-scm.com/docs/git-revert . Nó sẽ hoàn nguyên tất cả mã sau đó bạn có thể thực hiện cam kết tiếp theo. Sau đó, đầu sẽ trỏ đến cam kết cuối cùng đó. cam kết hoàn nguyên không bao giờ xóa nhưng nó sẽ không ảnh hưởng đến lần cam kết cuối cùng của bạn.


0

Trong trường hợp của tôi, mã ma thuật của tôi cho con rối này là cái này:

git reset --hard @{u}

Kiểm tra nó và cho tôi biết. Tôi đã thử một vài cái khác nhau, nhưng cái này là thứ duy nhất giúp tôi.

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.