Làm thế nào tôi có thể quay lại 1 cam kết?


127

Tôi có 2 cam kết mà tôi đã không thúc đẩy:

$ git status
# On branch master
# Your branch is ahead of 'faves/master' by 2 commits.

Làm thế nào tôi có thể quay lại cái đầu tiên của tôi (cái cũ nhất), nhưng giữ cái thứ hai?

 $ git log
commit 3368e1c5b8a47135a34169c885e8dd5ba01af5bb
...

commit baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e
...

Từ đây:

http://friendfeed.com/harijay/742631ff/git-question-how-do-i-rollback-commit-just-want

Tôi chỉ cần làm:

git reset --hard baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e

Đó là?


3
Câu hỏi này dường như lạc đề vì nó là về một công cụ lập trình. Nó thuộc về Stack Overflow.
Peter Mortensen

@PeterMortensen Đồng ý. Đây là phạm vi của SuperUser
Kolob Canyon

Câu trả lời:


95

Cách an toàn nhất và có lẽ là sạch nhất để đi là rebase tương tác.

git rebase -i HEAD^^

Hoặc là,

git rebase -i baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e^

Từ đó, bạn có thể xóa các xác nhận, trong đó đặt một hoặc nhiều cam kết với nhau vào các cam kết trước đó. Để xóa hoàn toàn một cam kết khỏi lịch sử, hãy xóa dòng khỏi danh sách.

Bạn có thể hoàn nguyên một cam kết với git revertnhưng nó sẽ thêm nhiều thông điệp cam kết vào lịch sử, điều này có thể không mong muốn. Sử dụng -ntham số để báo cho Git không cam kết hoàn nguyên ngay lập tức. Bạn có thể rebase tương tác và đè bẹp những người trước đó để giữ mọi thứ sạch sẽ.

Nếu hai cam kết bạn làm việc ở đây ảnh hưởng đến cùng một tệp, bạn có thể thấy xung đột hợp nhất.

Việc thiết lập lại kho lưu trữ git reset --hardnên được thực hiện cẩn thận, vì nó không thể hoàn tác.

Viết lại lịch sử nên được thực hiện một cách cẩn thận.


Làm cách nào tôi có thể xóa một cam kết trong 'git rebase'? Chỉ có 3 lệnh: chọn, chỉnh sửa, squash. Không có xóa AFAIK.
n179911

8
xóa hoàn toàn dòng khỏi danh sách và nó xóa cam kết đó
jtimberman

Khi tôi muốn hoàn nguyên thay đổi, tôi muốn không để lại dấu vết nào. Nếu bạn cũng không muốn để lại dấu vết hoàn nguyên thì đây là cách tốt nhất để làm điều đó.
Phillip Whelan

"Cách an toàn nhất và có thể sạch nhất để đi là phản ứng tương tác" Có thể không nếu bạn không sử dụng vim. Tôi đã may mắn và tìm ra cách thoát khỏi mớ hỗn độn đó. Vẫn nâng cao vì tôi nên học vim :-)
isimmons 13/12/13

Tôi sẽ đề nghị sử dụng rebasecàng ít càng tốt. Nếu bạn làm việc với người khác thì chỉ cần thực hiện revert.
boldnik 31/12/13

52

Điều này nếu từ http://nakkaya.com/2009/09/24/git-delete-last-commit/ và nó hoạt động với tôi

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

Thỉnh thoảng vào một đêm khuya khi tôi hết cà phê, tôi cam kết những thứ mà tôi không nên có. Sau đó, tôi dành 10 - 15 phút tiếp theo để tìm cách xóa cam kết cuối cùng tôi đã thực hiện. Vì vậy, sau lần thứ ba tôi muốn lập biên bản về nó để tôi có thể tham khảo nó sau.

Nếu bạn đã phạm tội nhưng không được đẩy,

git reset --hard HEAD~1

Đầu ~ 1 là một tốc ký cho cam kết trước đầu. Ngoài ra, bạn có thể tham khảo SHA-1 của hàm băm bạn muốn đặt lại. Lưu ý rằng khi sử dụng - có bất kỳ thay đổi nào đối với các tệp được theo dõi trong cây làm việc kể từ khi cam kết trước đầu bị mất.

Nếu bạn không muốn xóa sạch công việc bạn đã thực hiện, bạn có thể sử dụng --softtùy chọn sẽ xóa cam kết nhưng nó sẽ để lại tất cả các tệp đã thay đổi của bạn "Thay đổi được cam kết", vì trạng thái git sẽ đặt nó.

Bây giờ nếu bạn đã đẩy và ai đó thường là trường hợp của tôi, bạn không thể sử dụng git reset. Tuy nhiên, bạn có thể thực hiện hoàn nguyên git,

git revert HEAD

Điều này sẽ tạo ra một cam kết mới đảo ngược mọi thứ được giới thiệu bởi cam kết tình cờ.


2
Với tùy chọn --soft, thật hoàn hảo khi bạn đổi tên tệp và vô tình "git commit -a" thay vì sử dụng "git add" trước.
Aaron Harun

8

Không. git-reset --hard sẽ đưa bạn trở lại trong lịch sử. Những gì bạn đang tìm kiếm là git Revert, sẽ hoàn tác mọi cam kết.


4
Vâng, điều này hoạt động nhưng nó cũng gây ô nhiễm bạn cam kết đăng nhập. Nếu những cam kết này không được đẩy / kéo thì tốt hơn hết là dọn sạch chúng bằng một rebase tương tác. Khả năng thay đổi lịch sử là một trong những lợi thế chính của git so với các hệ thống kiểm soát phiên bản khác.
knweiss

6

Tôi vừa mới làm điều này:

git rebase -i HEAD^^

Tôi đã làm hỏng nó lên vì vậy tôi đã làm

git rebase --abort

Sau đó đã làm lại. Sau đó tôi phải đẩy như thế này:

git push origin master -f

Và nó đã phá hủy các cam kết mới hơn so với cam kết mà tôi đã quay lại. Làm việc tuyệt vời.


4

Không, git reset --hard baf8d5esẽ xóa 3368e1ccam kết và CHÍNH sẽ ở baf8d5esau đó.

Nếu bạn muốn giữ 3368e1ccam kết và xóa bad8d5ecam kết, giải pháp đơn giản nhất là thực hiện " git rebase -i HEAD~2" (nghĩa là phản hồi tương tác của hai lần xác nhận gần nhất). Lệnh này sẽ khởi chạy trình soạn thảo thông điệp cam kết của bạn và bạn sẽ thấy một dòng cho mỗi hai cam kết cuối cùng. Ở đó bạn chỉ cần xóa bad8d5edòng cam kết và lưu. git sau đó sẽ viết lại lịch sử của bạn và cam kết thứ 2 sẽ biến mất.

Có lệnh hữu ích khác mà bạn có thể sử dụng trong trình soạn thảo thông điệp cam kết như squash, editvv rebase Interactive là RẤT mạnh mẽ!

Đừng làm điều này nếu ai đó đã thấy những cam kết này (đẩy hoặc kéo từ kho lưu trữ của bạn)!



1
git reset --hard {ref}

là cách duy nhất để hoàn tác một cam kết nếu chỉ có một cam kết khác trong repo (ví dụ: cam kết ban đầu và 1 lần nữa). Phần còn lại của các cách (hoàn nguyên, rebase) từ chối làm việc, ít nhất là từ git 1.7.5.1.

Nếu bạn làm theo git resetvới git gcthì git sẽ thực sự xóa hoàn toàn dữ liệu cam kết cũ khỏi repo.


1
git checkout <treeish> -- /path/to/dir

Điều đó sẽ mang lại thư mục từ cây Treeish được đưa ra cho / path / to / dir


0

Tôi đã làm việc này bằng cách chỉnh sửa thủ công mã băm của các lần xác nhận cuối cùng từ các tệp CHÍNH trong thư mục kho lưu trữ:

"centralRepository\refs\heads\master"
"centralRepository\refs\heads\branch2"

Trước đó, tôi không bao giờ có thể thúc đẩy để bắt đầu các hoạt động UNmerGE mà tôi đã làm tại địa phương. Nó cứ nói rằng "thất bại trong việc đẩy một số ref" vào Kho lưu trữ trung tâm.

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.