Muốn thay đổi chủ của tôi thành cam kết cũ hơn, tôi có thể thực hiện việc này như thế nào?


91

Tôi muốn khôi phục lại cam kết trước đó, sau đó xuất bản mã đó, sau đó quay lại cam kết mới nhất.

tức là vì vậy chủ nhân của tôi đang trỏ đến một phiên bản cam kết cũ hơn để tôi có thể điều chỉnh phiên bản đó, sau đó tôi muốn quay lại phiên bản cam kết mới nhất mà tôi đã sử dụng lúc đầu.

Tôi có thể làm cái này như thế nào?

Câu trả lời:


99

Nếu bạn muốn thực hiện việc này và hoàn nguyên bản gốc về cam kết trước đó:

git checkout master~1            # Checkout previous commit on master
git checkout -b new_master       # Create branch for new master
git branch -D master             # Delete old master
git branch -mv new_master master # Make new_master master

Ngoài ra:

git reset --hard master~1        # Reset current branch to one commit ago on master

1
Vì vậy, một năm sau, tôi đang nhìn vào điều này và nghĩ rằng đây là một cách tồi tệ để làm điều đó. Ồ, ít nhất thì nó cũng dễ hiểu.
Tyler Brock

1
vâng đây là lý do tại sao tôi ủng hộ, dễ hiểu, có lẽ bạn nên trình bày một liên kết đến một cách tốt hơn?
Andrew Atkinson

1
Tôi đã phải làm điều tương tự bằng cách sử dụng SourceTree. Quá trình tương tự. 1) tạo nhánh mới cho trạng thái chính hiện tại, vì vậy bạn sẽ không mất bất cứ thứ gì. 2) xóa thạc sĩ 3) tạo ra chi nhánh chủ mới, chọn mong muốn cam kết
Danilo Gomes

Điều gì xảy ra với cam kết mà chúng tôi đã "xóa" khỏi trang chủ sau điều này?
Arthur Colombini Gusmão

1
Điều này nên tránh nếu bạn có repo từ xa. Nó gây ra một số lỗi nếu bạn làm vậy, vì địa chỉ của trang cái đầu tiên khác với cái chính mới mà bạn đã tạo gần đây.
MAChitgarha

59

Câu hỏi của bạn không rõ ràng. Tôi nghĩ những gì bạn đang yêu cầu là:

git push -f origin $old_commit_id:master

Điều này sẽ làm gì? Nó sẽ đẩy $old_commit_idcam kết originlà người đứng đầu mới của origin's masterchi nhánh.

Nếu đó là những gì bạn muốn, bạn không cần phải chạm vào masterchi nhánh địa phương của mình .


Điều này đã gây ra một master (non-fast-forward)thất bại cho tôi. Giải pháp @jtdubs đã hoạt động.
Bobby Norton

3
Chỉ cần vượt qua -fđể buộc nó - mặc dù repo từ xa có thể được định cấu hình để cấm điều đó. Tôi đã cập nhật câu trả lời.
Aristotle Pagaltzis

không phù hợp với tôi, câu trả lời được chấp nhận thì có
MobileMon

Bạn đã không nói chính xác những gì bạn muốn hoặc tại sao nó không hoạt động nên tôi không thể cho bạn biết tại sao nó không hoạt động và nó có thể được tạo ra như thế nào (nếu có thể).
Aristotle Pagaltzis

Bạn dường như mất lịch sử quá khứ trên điều khiển từ xa với cách tiếp cận này, tôi thấy ổn. Chỉ gọi nó ra.
Shawn

43

sử dụng git reset --hard <old commit number>

nó sẽ đặt lại HEAD về cam kết cũ này.

Ngoài ra, bạn cũng cần sử dụng git push -f originđể thay đổi repo từ xa.


34

Nếu bạn muốn tránh bị ép buộc, đây là cách hoàn nguyên repo của bạn về một cam kết cũ hơn và duy trì tất cả các công việc can thiệp:

git checkout 307a5cd        # check out the commit that you want to reset to 
git checkout -b fixy        # create a branch named fixy to do the work
git merge -s ours master    # merge master's history without changing any files
git checkout master         # switch back to master
git merge fixy              # and merge in the fixed branch
git push                    # done, no need to force push!

Làm xong! Thay thế 307a5cd bằng bất kỳ cam kết nào bạn muốn trong repo của mình.

(Tôi biết hai dòng đầu tiên có thể được kết hợp, nhưng tôi nghĩ điều đó làm cho nó không rõ ràng hơn những gì đang xảy ra)

Đây là đồ thị:

c1 -- c2 -- c3 -- c4 -- c2' -- c5 ...
        \              /
         '------------'

Bạn loại bỏ c3 và c4 một cách hiệu quả và đặt dự án của bạn trở lại c2. Tuy nhiên, c3 và c4 vẫn có sẵn trong lịch sử dự án của bạn nếu bạn muốn xem lại chúng.


1
Điều này hoạt động mà không gặp trở ngại! Nếu bạn đã đến đây và đang đọc nó - đây có vẻ là cách sạch sẽ nhất để hoàn nguyên chủ để cam kết sâu hơn.
ddisqq

Tôi không thể tìm thấy từ ngữ nào để giải thích rằng tôi yêu bạn nhiều như thế nào vì điều này, tôi rất tuyệt vời không thể nói thành lời vì đã sửa chữa một cái gì đó đã khiến tôi bị nghe trộm suốt 6 giờ và khiến tôi rất đau đầu. Cảm ơn ngài!!!!!!!
Kostas Tsakalidis

Điều này vừa cứu mạng tôi! cảm ơn bạn
Brad

9

Giả sử một biểu đồ cam kết như vậy:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                              (master)

Trước tiên, bạn muốn thanh toán mastervà tạo một nhánh trỏ đến vị trí masterhiện tại:

git checkout master
git branch pointer master

Bây giờ sẽ trông như thế này:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                       (HEAD, master, pointer)

Bây giờ bạn đã ở trên master, chúng tôi sẽ yêu cầu masterchi nhánh lùi lại một cam kết:

git reset master~1

Bây giờ, mastersẽ được di chuyển trở lại một khoảng trống, nhưng pointernhánh vẫn ở trong cam kết gần đây nhất:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|           (HEAD, master)    (pointer)

Tại thời điểm này, bạn có thể đẩy masterđến một điều khiển từ xa hoặc bất cứ nơi nào, sau đó tiến nhanh hợp nhất nó trở lại pointerchi nhánh. Bạn có thể giết pointernhánh tại thời điểm đó:

git push origin master
git merge --ff-only pointer
git branch -D pointer

Sau cùng :

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|         [ origin/master ]    (HEAD, master)

1
Nếu origin / master ở C, git push origin mastersẽ không thành công với phần chóp của nhánh hiện tại của bạn nằm sau đối tác từ xa của nó . Bạn cũng nên vượt qua cờ -f.
sassospicco

8

Bạn chỉ có thể git checkout <commit-id>làm bất cứ điều gì bạn cần làm, sau đó git checkout masterquay lại mã mới.

Nếu bạn thực sự cần sửa đổi mã cũ để giải phóng nó, thì bạn có thể nên:

git checkout -b my_release <commit-id>
... prepare code for release ...
... release code ...
git checkout master
git merge my_release

Ngoài ra, tôi không thể giới thiệu dòng git đủ. Nó làm cho tất cả những điều này khá dễ dàng.


1

Để chuyển sang phiên bản trước:

git checkout <version hash>

làm công việc của bạn ở đây và cam kết nó với

git commit --amend

Để quay lại trang chủ :

git checkout master


1
Điều đó sẽ không hoạt động. git reset --hardchỉ nhánh chủ của mình trở lại cam kết cũ, vì vậy git checkout mastersẽ không làm gì cả.
jtdubs

Đúng, cảm ơn vì đã sửa. 1 đối với bạn, sẽ loại bỏ câu trả lời của tôi quá nhưng tôi nghĩ rằng các commit --amendbước là đủ hữu ích
Pablo Fernandez

Là gì --amend?
Shafizadeh
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.