Câu hỏi Cách hoàn nguyên kho lưu trữ Git thành commit trước


Làm cách nào để hoàn nguyên từ trạng thái hiện tại của tôi sang ảnh chụp nhanh được thực hiện trên một cam kết nhất định?

Nếu tôi làm git log, sau đó tôi nhận được kết quả sau:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Cách hoàn nguyên cam kết từ ngày 3 tháng 11, nghĩa là cam kết 0d1d7fc?


6021
2017-11-06 16:58


gốc


Liên quan Làm thế nào để hoàn tác cam kết Git cuối cùng?.
Đây là một bài viết rất rõ ràng và kỹ lưỡng về việc hoàn tác mọi thứ trong git, trực tiếp từ Github. - Nobita
Liên quan: Rollback cho một Git cũ cam kết trong một repo công cộng. Lưu ý rằng câu hỏi đó thêm một ràng buộc rằng repo là công khai.
Tôi yêu git, nhưng thực tế là có 35 câu trả lời cho một cái gì đó nên cực kỳ đơn giản cho thấy một vấn đề lớn với git. Hay đó là tài liệu? - The Muffin Man


Các câu trả lời:


Điều này phụ thuộc rất nhiều vào ý bạn bằng cách "hoàn nguyên".

Tạm thời chuyển sang một cam kết khác

Nếu bạn muốn tạm thời quay trở lại với nó, đánh lừa xung quanh, sau đó quay trở lại nơi bạn đang ở, tất cả những gì bạn phải làm là kiểm tra cam kết mong muốn:

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

Hoặc nếu bạn muốn thực hiện cam kết trong khi bạn ở đó, hãy tiếp tục và tạo một chi nhánh mới trong khi bạn ở đó:

git checkout -b old-state 0d1d7fc32

Để quay trở lại nơi bạn đang ở, chỉ cần kiểm tra các chi nhánh bạn đang ở trên một lần nữa. (Nếu bạn đã thực hiện thay đổi, như thường lệ khi chuyển đổi nhánh, bạn sẽ phải đối phó với chúng khi thích hợp. Bạn có thể đặt lại để ném chúng đi; bạn có thể stash, checkout, stash pop để mang chúng theo bên mình; họ đến một chi nhánh ở đó nếu bạn muốn có một chi nhánh ở đó.)

Xóa khó cam kết chưa được xuất bản

Mặt khác, nếu bạn muốn loại bỏ mọi thứ bạn đã làm, có hai khả năng. Một, nếu bạn chưa xuất bản bất kỳ cam kết nào trong số này, chỉ cần đặt lại:

# 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.

Nếu bạn lộn xộn, bạn đã vứt bỏ những thay đổi cục bộ của mình, nhưng ít nhất bạn cũng có thể quay lại nơi bạn đã ở trước bằng cách đặt lại lần nữa.

Hoàn tác các cam kết đã được xuất bản với các cam kết mới

Mặt khác, nếu bạn đã xuất bản tác phẩm, có thể bạn không muốn đặt lại nhánh, vì đó là lịch sử viết lại hiệu quả. Trong trường hợp đó, bạn thực sự có thể hoàn nguyên các cam kết. Với Git, việc hoàn nguyên có ý nghĩa rất cụ thể: tạo một cam kết với bản vá ngược lại để hủy bỏ nó. Bằng cách này bạn không viết lại bất kỳ lịch sử nào.

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

Các git-revert manpage thực sự bao gồm rất nhiều điều này trong mô tả của nó. Một liên kết hữu ích khác là phần git-scm.com này thảo luận về git-revert.

Nếu bạn quyết định bạn không muốn hoàn nguyên sau khi tất cả, bạn có thể hoàn nguyên hoàn nguyên (như được mô tả ở đây) hoặc đặt lại về trước khi hoàn nguyên (xem phần trước).

Bạn cũng có thể thấy câu trả lời này hữu ích trong trường hợp này:
Làm thế nào để di chuyển HEAD trở lại vị trí trước đó? (Đầu tách rời)


7841
2017-11-06 17:04



Nhận xét của @ Rod trên git revert HEAD~3 là wat tốt nhất để quay trở lại 3 cam kết là một quy ước quan trọng. - New Alexandria
Bạn có thể viết toàn bộ số không? như: git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50 - Spoeken
@MathiasMadsenStav Có, tất nhiên bạn có thể chỉ định các cam kết bằng toàn bộ SHA1. Tôi đã sử dụng băm viết tắt để làm cho câu trả lời dễ đọc hơn và bạn cũng có xu hướng sử dụng chúng nếu bạn đang gõ. Nếu bạn đang sao chép và dán, bằng mọi cách, hãy sử dụng hàm băm đầy đủ. Xem Chỉ định sửa đổi trong man git rev-parse để có mô tả đầy đủ về cách bạn có thể đặt tên cho các cam kết. - Cascabel
Để quay lại lệnh hiện tại là 'git checkout master' - Xavier John
Bạn có thể dùng git revert --no-commit hash1 hash2 ... và sau này chỉ cam kết mỗi lần hoàn nguyên trong một lần commit git commit -m "Message" - Mirko Akov


Hoàn nguyên bản sao làm việc cho Cam kết gần đây nhất

Để hoàn nguyên về cam kết trước đó, bỏ qua bất kỳ thay đổi nào:

git reset --hard HEAD

trong đó HEAD là cam kết cuối cùng trong nhánh hiện tại của bạn

Hoàn nguyên bản sao làm việc cho một cam kết cũ hơn

Để hoàn nguyên về cam kết cũ hơn cam kết mới nhất:

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

Tín dụng đi đến một câu hỏi Stack Overflow tương tự, Hoàn nguyên về cam kết bằng hàm băm SHA trong Git?.


1262
2017-08-21 06:19



Tôi đã làm điều đó, nhưng sau đó tôi đã không thể cam kết và đẩy đến kho lưu trữ từ xa. Tôi muốn một cam kết cụ thể cũ hơn để trở thành HEAD ... - Lennon
Nó có nghĩa là bạn đã đẩy vào các cam kết mà bạn muốn hoàn nguyên. Nó có thể tạo ra rất nhiều vấn đề cho những người đã kiểm tra mã của bạn và làm việc trên nó. Vì họ không thể áp dụng cam kết của bạn suôn sẻ hơn họ. Trong trường hợp như vậy tốt hơn làm một git trở lại. Nếu bạn là người duy nhất sử dụng repo. Làm một git push -f (Nhưng hãy suy nghĩ hai lần trước khi làm điều đó) - vinothkr
Cảnh báo bắt buộc: không đặt lại khó nếu bạn đang chia sẻ chi nhánh của mình với những người khác có bản sao của các cam kết cũ, bởi vì việc đặt lại cứng như thế này sẽ buộc họ phải đồng bộ hóa lại công việc của họ với nhánh mới được đặt lại. Việc thiết lập lại mềm là an toàn mặc dù, cũng như các giải pháp cuối cùng trong câu trả lời này.
Tôi cũng muốn chỉ ra rằng, cách khác cho giải pháp khôi phục lại mềm, thay vì làm một thiết lập lại hỗn hợp đầu tiên và một thiết lập lại cứng cuối cùng, bạn thực sự có thể làm việc thiết lập lại cứng đầu tiên, như sau: git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit.
@nuton linus pauling mình, tác giả của git, chỉ trích nó vì quá phức tạp. Anh ấy nói rằng anh ấy bị "sốc" git trở nên quá nổi tiếng vì sự phức tạp của nó - boulder_ruby


Rất nhiều câu trả lời phức tạp và nguy hiểm ở đây, nhưng nó thực sự dễ dàng:

git revert --no-commit 0766c053..HEAD
git commit

Điều này sẽ hoàn nguyên mọi thứ từ HEAD trở lại băm commit, nghĩa là nó sẽ tạo lại trạng thái cam kết đó trong cây đang hoạt động như thể mọi cam kết kể từ khi được quay trở lại. Sau đó bạn có thể cam kết cây hiện tại, và nó sẽ tạo ra một cam kết hoàn toàn mới tương đương với cam kết mà bạn đã "hoàn nguyên".

(Các --no-commit cờ cho phép git hoàn nguyên tất cả các cam kết cùng một lúc- nếu không bạn sẽ được nhắc nhở cho một thông điệp cho mỗi cam kết trong phạm vi, xả rác lịch sử của bạn với các cam kết mới không cần thiết.)

Đây là một cách quay trở lại trạng thái trước và an toàn. Không có lịch sử nào bị hủy, vì vậy nó có thể được sử dụng cho các cam kết đã được công khai.


1221
2018-02-12 04:18



Nếu bạn thực sự muốn có các cam kết cá nhân (thay vì hoàn nguyên mọi thứ với một cam kết lớn), thì bạn có thể vượt qua --no-edit thay vì --no-commit, để bạn không phải chỉnh sửa thông điệp cam kết cho mỗi lần đảo ngược.
Nếu một trong các cam kết giữa 0766c053..HEAD là một hợp nhất thì sẽ có một lỗi xuất hiện (để làm với không có chỉ định -m). Điều này có thể giúp những người gặp phải điều đó: stackoverflow.com/questions/5970889/… - timhc22
Để xem các khác biệt trước khi bạn sử dụng git diff --cached. - John Erck
$ git revert --no-commit 53742ae..HEAD trả về fatal: empty commit set passed - Alex G
@AlexG đó là bởi vì bạn cần phải nhập băm một trước cái mà bạn muốn quay lại. Trong trường hợp của tôi, băm giống như: 81bcc9e HEAD{0}; e475924 HEAD{1}, ... (từ git reflog) và tôi muốn hoàn tác những gì tôi đã làm 81bcc9ethì tôi phải làm git revert e475924..HEAD - EpicPandaForce


Tùy chọn tốt nhất cho tôi và có lẽ là tùy chọn khác là tùy chọn đặt lại Git:

git reset --hard <commidId> && git clean -f

Đây là lựa chọn tốt nhất cho tôi! Nó rất đơn giản, nhanh chóng và hiệu quả!


Chú thích :  Như đã đề cập trong các bình luận không làm điều này nếu bạn đang chia sẻ chi nhánh của bạn với những người khác có bản sao của các cam kết cũ

Cũng từ các ý kiến, nếu bạn muốn có một phương pháp ít 'ballzy' bạn có thể sử dụng

git clean -i 


153
2017-10-22 11:53



Cảnh báo bắt buộc: không làm điều này nếu bạn đang chia sẻ chi nhánh của mình với những người khác có bản sao của các cam kết cũ, bởi vì việc đặt lại cứng như thế này sẽ buộc họ phải đồng bộ hóa lại công việc của họ với nhánh mới được đặt lại. Đối với một giải pháp giải thích chi tiết cách an toàn hoàn nguyên các cam kết mà không làm việc với thiết lập lại cứng, xem câu trả lời này.
Tôi thứ hai @ Cupcake cảnh báo ... rất ý thức về hậu quả. Tuy nhiên, lưu ý rằng nếu nhu cầu của bạn thực sự là làm cho những cam kết đó biến mất khỏi lịch sử mãi mãi, phương pháp này sẽ làm sạch và bạn sẽ cần lực lượng đẩy các nhánh đã sửa đổi của bạn trở lại bất kỳ và tất cả các điều khiển từ xa. - ashnazg
hãy nhớ, làm sạch sẽ loại bỏ các tập tin / thư mục như .idea (phpstorm) hoặc .vagrant (lang thang) có thể được sử dụng bởi thiết lập của bạn / IDE! - timhc22
git clean -f NGUY HIỂM NGUY HIỂM - Tisch
@Pogrindis - rất nhiều câu trả lời hay ở đây mà không xóa các tập tin không được theo dõi. - Tisch


Nếu bạn muốn "bỏ ghi chú", xóa thông báo cam kết cuối cùng và đặt các tệp đã sửa đổi trở lại trong dàn dựng, bạn sẽ sử dụng lệnh:

git reset --soft HEAD~1
  • --soft cho biết rằng các tệp không được cam kết sẽ được giữ lại dưới dạng tệp hoạt động trái ngược với --hard sẽ loại bỏ chúng.
  • HEAD~1 là cam kết cuối cùng. Nếu bạn muốn khôi phục 3 cam kết, bạn có thể sử dụng HEAD~3. Nếu bạn muốn khôi phục một số phiên bản cụ thể, bạn cũng có thể làm điều đó bằng cách sử dụng hàm băm SHA của nó.

Đây là một lệnh vô cùng hữu ích trong các tình huống mà bạn đã phạm sai lầm và bạn muốn hoàn tác cam kết cuối cùng đó.

Nguồn: http://nakkaya.com/2009/09/24/git-delete-last-commit/


103
2018-03-04 17:25



Điều này là mềm mại và nhẹ nhàng: rủi ro miễn phí nếu bạn không đẩy công việc của mình - nilsM


Trước khi trả lời, hãy thêm một số thông tin cơ bản, giải thích điều này HEAD Là.

First of all what is HEAD?

HEAD chỉ đơ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ể là một HEAD tại bất kỳ thời điểm nào (không bao gồm git 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 có cam kết mới nhất - nghĩa là HEAD đang trỏ đến cam kết trước đây trong lịch sử được gọi là detached HEAD.

Enter image description here

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

Enter image description here


Một vài tùy chọn về cách khôi phục từ HEAD tách rời:


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 trỏ đến cam kết mong muốn. Lệnh này sẽ trả về một cam kết đã cho.

Tại thời điểm này, bạn có thể tạo một chi nhánh và bắt đầu làm việc từ thời điểm này trên:

# 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 reflog cũng. git reflog sẽ hiển thị bất kỳ thay đổi nào đã cập nhật HEAD và kiểm tra mục nhập reflog bạn muốn sẽ đặt HEAD trở lại cam kết này.

Mỗi lần HEAD được sửa đổi 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

Enter image description here


git reset HEAD --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.
  • Chú thích: (Kể từ Git 2.7) bạn cũng có thể sử dụng git rebase --no-autostash cũng.

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

Enter image description here


102
2018-02-05 21:56



Gợi ý tuyệt vời cho git reflog, đó là chính xác những gì tôi cần - smac89
Ouch! Tất cả điều này có vẻ phức tạp khủng khiếp ... không có một lệnh đơn giản mà chỉ đưa bạn một bước trở lại trong quá trình này? Giống như đi từ phiên bản 1.1 trong dự án của bạn trở lại phiên bản 1.0? Tôi mong đợi một cái gì đó như: git stepback_one_commit hoặc một cái gì đó .... - Kokodoko
có: git reset HEAD^ --hard` - CodeWizard
@Kokodoko Vâng, nó phức tạp khủng khiếp ... và một ví dụ hoàn hảo về cách các chuyên gia xem xét ít có cho những người mới bắt đầu. Xin vui lòng tham khảo câu trả lời của tôi ở đây, và cũng để cuốn sách tôi đề nghị trong đó. Git KHÔNG phải là thứ bạn chỉ có thể nhận trực giác. Và tôi có thể hoàn toàn chắc chắn CodeWizard đã không làm như vậy. - mike rodent


Tôi đã thử rất nhiều cách để hoàn nguyên các thay đổi cục bộ trong Git, và có vẻ như điều này hoạt động tốt nhất nếu bạn chỉ muốn hoàn nguyên về trạng thái cam kết mới nhất.

git add . && git checkout master -f

Mô tả ngắn:

  • Nó sẽ KHÔNG tạo ra bất kỳ cam kết nào git revert làm.
  • Nó sẽ KHÔNG tách HEAD của bạn như git checkout <commithashcode> làm.
  • Nó S over ghi đè tất cả các thay đổi cục bộ của bạn và XÓA tất cả các tệp được thêm kể từ lần commit cuối cùng trong nhánh.
  • Nó chỉ hoạt động với các tên nhánh, vì vậy bạn chỉ có thể hoàn nguyên về cam kết mới nhất trong nhánh này theo cách này.

Tôi đã tìm thấy một cách thuận tiện và đơn giản hơn để đạt được kết quả trên:

git add . && git reset --hard HEAD

trong đó HEAD trỏ đến cam kết mới nhất tại nhánh hiện tại của bạn.

Đó là mã giống như boulder_ruby được đề xuất, nhưng tôi đã thêm git add . trước git reset --hard HEAD để xóa tất cả các tệp mới được tạo từ lần commit cuối cùng vì đây là điều mà hầu hết mọi người mong đợi tôi tin khi hoàn nguyên về cam kết mới nhất.


96
2017-07-29 11:01





Bạn có thể thực hiện điều này bằng hai lệnh sau:

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

Nó sẽ loại bỏ cam kết Git trước đó của bạn.

Nếu bạn muốn giữ các thay đổi, bạn cũng có thể sử dụng:

git reset --soft [previous Commit SHA id here]

Sau đó, nó sẽ lưu các thay đổi của bạn.


76
2017-12-12 06:52



Tôi đã thử 1/2 một chục câu trả lời trong bài đăng này cho đến khi tôi nhận được điều này .. tất cả những người khác, cấu hình git của tôi giữ cho tôi một lỗi khi cố gắng để đẩy. Câu trả lời này đã hiệu quả. Cảm ơn! - gnB
Một chi tiết cho tôi là tôi đã mất đi sự khác biệt .. mà tôi muốn tiếp tục xem những gì tôi đã làm trong cam kết không hiệu quả. Vì vậy, lần sau tôi sẽ lưu dữ liệu đó trước khi phát hành lệnh đặt lại này - gnB
Đây là cách duy nhất để tôi hoàn tác một hợp nhất xấu, hoàn nguyên không hoạt động trong trường hợp đó. Cảm ơn! - Dave Cole


Giả sử bạn có các cam kết sau trong tệp văn bản có tên ~/commits-to-revert.txt (Tôi đã sử dụng git log --pretty=oneline để có được chúng)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

Tạo một Bash shell script để hoàn nguyên mỗi tập lệnh:

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

Việc này sẽ chuyển mọi thứ về trạng thái trước đó, bao gồm các tập tin và thư mục sáng tạo, và xóa, cam kết nó vào nhánh của bạn và bạn giữ lại lịch sử, nhưng bạn đã hoàn nguyên về cấu trúc tệp tương tự. Tại sao Git không có git revert --to <hash> vượt ra ngoài tôi.


51
2017-10-13 21:51



Bạn có thể làm một git revert HEAD~3 để xóa 3 cam kết cuối cùng - Rod
@Rod - Không, điều đó không đúng. Lệnh đó sẽ hoàn nguyên cam kết là ông bà thứ ba của HEAD (không phải là ba lần commit cuối cùng). - kflorence
@Rod - Điều đó nghe có vẻ đúng, chắc chắn là một cú pháp xấu xí dù phải không? Tôi đã luôn luôn tìm thấy kiểm tra các cam kết tôi muốn "hoàn nguyên" và sau đó cam kết trực quan hơn. - kflorence
@Lance Tôi đồng ý với bạn về git revert --to - điều này có vẻ giống như một cách không thể tin được phức tạp để đạt được một điều khá đơn giản! - Mike Vella
Có một dễ dàng hơn nhiều cách để làm điều này bây giờ hơn với một kịch bản như thế này, chỉ cần sử dụng git revert --no-commit <start>..<end>, bởi vì git revert chấp nhận phạm vi cam kết trong các phiên bản mới (hoặc tất cả?) của Git. Lưu ý rằng bắt đầu phạm vi không được bao gồm trong hoàn nguyên.


Giải pháp thay thế cho giải pháp của Jefromi

Giải pháp của Jefromi chắc chắn là những cái tốt nhất, và bạn chắc chắn nên sử dụng chúng. Tuy nhiên, vì lợi ích của sự hoàn chỉnh, tôi cũng muốn hiển thị các giải pháp thay thế khác này cũng có thể được sử dụng để hoàn nguyên một cam kết (theo nghĩa là bạn tạo một cam kết mới để hoàn tác các thay đổi trong lần commit trước, giống như những gì git revert làm).

Để rõ ràng, các lựa chọn thay thế này không phải là cách tốt nhất để hoàn nguyên các cam kết, Các giải pháp của Jefromi là, nhưng tôi chỉ muốn chỉ ra rằng bạn cũng có thể sử dụng các phương pháp khác để đạt được điều tương tự như git revert.

Phương án 1: Đặt lại cứng và mềm

Đây là một phiên bản được sửa đổi rất ít về giải pháp của Charles Bailey Hoàn nguyên về cam kết bằng hàm băm SHA trong Git?:

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"

Điều này về cơ bản hoạt động bằng cách sử dụng thực tế là các resets mềm sẽ rời khỏi trạng thái của commit trước đó được tổ chức trong index / staging-area, sau đó bạn có thể commit.

Phương án 2: Xóa cây hiện tại và thay thế bằng cây mới

Giải pháp này đến từ giải pháp của svick Thanh toán cũ cam kết và làm cho nó một cam kết mới:

git rm -r .
git checkout <commit> .
git commit

Tương tự như phương án số 1, điều này tái tạo trạng thái <commit> trong bản sao làm việc hiện tại. Nó là cần thiết để làm git rm đầu tiên vì git checkout sẽ không xóa các tệp đã được thêm từ <commit>.


48
2018-02-29 08:40



Về Phương án 1, một câu hỏi nhanh: Bằng cách làm như vậy, chúng ta không bỏ qua giữa các cam kết phải không? - Bogac
trong Phương án 2, các dấu chấm phù hợp với những gì trong các lệnh đó? - Bogac
@Bogac - các dấu chấm cho biết đường dẫn tệp, trong trường hợp này là thư mục hiện tại, do đó, giả sử bạn đang chạy nó từ thư mục gốc của bản sao làm việc của bạn. - Tom