Hoàn nguyên một loạt các cam kết trong git


127

Làm thế nào tôi có thể hoàn nguyên một loạt các cam kết trong git? Từ việc xem tài liệu gitrevutions , tôi không thể thấy cách chỉ định phạm vi tôi cần. Ví dụ:

A -> B -> C -> D -> E -> HEAD

Tôi muốn làm tương đương với:

git revert B-D

kết quả sẽ là:

A -> B -> C -> D -> E -> F -> HEAD

Trong đó F chứa mặt trái của bao gồm BD.


Đến cuối trang gitrevutions (7), có một phần tiêu đề "ĐẶC BIỆT RANGES". Làm thế nào để những gì bạn muốn khác với những gì được mô tả ở đó?
Gareth McCaughan

2
Trang gitrevutions gợi ý rằng 'git hoàn nguyên A..D' sẽ làm những gì tôi muốn. Tuy nhiên, khi tôi thử rằng tôi nhận được lỗi "gây tử vong: Không thể tìm thấy 'A..D'"
Alex Spurling

Câu trả lời:


172

Phiên bản Git nào bạn đang sử dụng?

Hoàn nguyên nhiều lần xác nhận chỉ được hỗ trợ trong Git1.7.2 +: xem " Phục hồi lại một cam kết cũ bằng cách sử dụng hoàn nguyên nhiều lần. " Để biết thêm chi tiết. Trang man
hiện tại chỉ dành cho phiên bản Git hiện tại (1.7.4+).git revert


Như OP Alex Spurling báo cáo trong các ý kiến:

Nâng cấp lên 1.7.4 hoạt động tốt.
Để trả lời câu hỏi của riêng tôi, đây là cú pháp tôi đang tìm kiếm:

git revert B^..D 

B^có nghĩa là "cam kết cha mẹ đầu tiên của B": cho phép đưa Bvào hoàn nguyên.
Xem phần " git rev-parseĐẶC BIỆT CÁCH MẠNG " bao gồm cú pháp <rev>^, ví dụHEAD^ : xem thêm tại " Ký tự dấu mũ ( ^) có nghĩa là gì? ")

Lưu ý rằng mỗi cam kết hoàn nguyên được cam kết riêng.

Henrik N làm rõ trong các ý kiến :

git revert OLDER_COMMIT^..NEWER_COMMIT

Như được hiển thị bên dưới, bạn có thể hoàn nguyên mà không cần phải cam kết ngay:

git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"

1
Cảm ơn, đó là câu trả lời. Nâng cấp lên 1.7.4 hoạt động tốt. Để trả lời câu hỏi của riêng tôi, đây là cú pháp tôi đang tìm kiếm: git Revert B ^ .. D
Alex Spurling

Thiên tài. cảm ơn. Nó đã không xảy ra với tôi Tôi cần hoàn nguyên các cam kết theo thứ tự ngược lại để áp dụng các bản vá, duh. Lệnh này chỉ đường.
Tim Abell

5
Tôi thường xuyên quay lại câu trả lời này và tôi luôn mất một lúc để tìm ra thứ tự. Vì vậy, để giúp bản thân tương lai của tôi:git revert OLDER_COMMIT^..NEWER_COMMIT
Henrik N

2
^ có nghĩa là gì?
Dustin Getz

1
@DustinGetz cha mẹ đầu tiên: xem git-scm.com/docs/gitrevutions : "Hậu tố ^cho tham số sửa đổi có nghĩa là cha mẹ đầu tiên của đối tượng cam kết đó".
VonC

15

Nếu bạn muốn hoàn nguyên phạm vi cam kết B thành D (ít nhất là trong phiên bản git 2) trong một cam kết duy nhất, bạn có thể làm

 git revert -n B^..D

Điều này hoàn nguyên các thay đổi được thực hiện bằng các cam kết từ cam kết gốc của B (đã loại trừ) đối với cam kết D (bao gồm), nhưng không tạo ra bất kỳ cam kết nào với các thay đổi được hoàn nguyên. Hoàn nguyên chỉ sửa đổi cây làm việc và chỉ mục.

Đừng quên cam kết thay đổi sau

 git commit -m "revert commit range B to D"

Bạn cũng có thể hoàn nguyên nhiều cam kết không liên quan trong một lần xác nhận, sử dụng cùng một phương thức. ví dụ để hoàn nguyên B và D nhưng không phải C

 git revert -n B D
 git commit -m "Revert commits B and D"

Tham khảo: https://www.kernel.org/pub/software/scm/git/docs/git-revert.html

Cảm ơn Honza HAERING cho sửa chữa


3
git revert -n B..Dkhông hoàn nguyên cam kết B, chỉ C và D. hoàn nguyên git revert -n B^..DB là tốt.
Honza Haering

theo tài liệu git nó làm. tài liệu tham khảo trong bài
Ramast

1
Nếu bạn tham gia vào ví dụ này (mà tôi nghĩ là hơi khó hiểu) trong tài liệu tham khảo : git revert -n master~5..master~2, nó nói rằng cam kết mới thứ năm bao gồm. Nhưng master~5thực sự là thứ 6 cam kết mới nhất. Xem lựa chọn sửa đổi trong tài liệu git để biết thông tin chi tiết về ..ký hiệu :-)
Honza Haering

6

Làm git revert OLDER_COMMIT^..NEWER_COMMITkhông được cho tôi.

Tôi đã sử dụng git revert -n OLDER_COMMIT^..NEWER_COMMITvà mọi thứ đều tốt. Tôi đang sử dụng phiên bản git 1.7.9.6.


Tôi đã gặp vấn đề tương tự và khắc phục nó bằng cách sử dụng -n, nhưng bạn nên để lại ^ với OLDER_COMMIT (git Revert -n OLDER_COMMIT ^ .. NEWER_COMMIT).
Feel Good 24/12/12

@Feel Tốt tại sao bạn nên rời khỏi ^?
Orlando

Tôi đã có lịch sử A -> B -> C và mục tiêu là hoàn nguyên B và C. Khi tôi chạy 'git Revert -n B..C', chỉ C được hoàn nguyên. Khi tôi sử dụng 'git Revert -n B ^ .. C', git hoàn nguyên cả hai lần xác nhận. Có lẽ tôi đã làm điều gì đó sai.
Feelood

tuyệt, cũng phải kiểm tra nó nhưng tôi nghĩ trong trường hợp của tôi đã hoạt động tốt (trừ khi tôi hoàn nguyên một phạm vi cam kết 1) tôi sẽ sửa đổi câu trả lời để bao gồm ^. cảm ơn
Orlando

2
Các -nhoặc --no-committùy chọn sẽ trở lại tất cả các thay đổi trên phạm vi trong một cam kết duy nhất, thay vì tạo một Revert cam kết cho mỗi cam kết trong phạm vi. Kết quả cuối cùng là như nhau, như trong, những thay đổi tương tự sẽ được hoàn nguyên. Chỉ phụ thuộc vào cách bạn muốn lịch sử git của bạn trông như thế nào.
Dennis

0

Sử dụng git rebase -iđể ép các cam kết có liên quan thành một. Sau đó, bạn chỉ cần có một cam kết để hoàn nguyên.


7
Nếu sử dụng git rebase, bạn chỉ cần xóa các xác nhận. Tôi nghĩ có một lý do để không nổi loạn, như muốn giữ SHA1 của cam kết F như cũ.
Paŭlo Ebermann

5
Ngoài ra, ép các cam kết hoàn nguyên thành một.
aeosynth
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.