Có hai cách để xử lý việc này. Cái nào dễ hơn phụ thuộc vào hoàn cảnh của bạn
Cài lại
Nếu cam kết bạn muốn loại bỏ là cam kết cuối cùng và bạn chưa thực hiện bất kỳ công việc bổ sung nào, bạn chỉ có thể sử dụng git-reset
git reset HEAD^
Đưa chi nhánh của bạn trở lại cam kết ngay trước TRƯỚC hiện tại của bạn. Tuy nhiên, nó không thực sự thay đổi các tệp trong cây làm việc của bạn. Kết quả là, những thay đổi trong cam kết đó hiển thị dưới dạng đã sửa đổi - nó giống như một lệnh 'không phổ biến'. Trong thực tế, tôi có một bí danh để làm điều đó.
git config --global alias.uncommit 'reset HEAD^'
Sau đó, bạn chỉ có thể sử dụng git uncommit
trong tương lai để sao lưu một cam kết.
Bóp
Bóp một cam kết có nghĩa là kết hợp hai hoặc nhiều cam kết thành một. Tôi làm điều này khá thường xuyên. Trong trường hợp của bạn, bạn đã hoàn thành một nửa tính năng, và sau đó bạn sẽ hoàn thành nó và cam kết lại với thông điệp cam kết phù hợp, vĩnh viễn.
git rebase -i <ref>
Tôi nói ở trên bởi vì tôi muốn làm rõ rằng đây có thể là bất kỳ số lượng cam kết nào. Chạy git log
và tìm cam kết mà bạn muốn loại bỏ, sao chép SHA1 của nó và sử dụng nó thay thế <ref>
. Git sẽ đưa bạn vào chế độ rebase tương tác. Nó sẽ hiển thị tất cả các cam kết giữa trạng thái hiện tại của bạn và bất cứ điều gì bạn đặt vào vị trí <ref>
. Vì vậy, nếu <ref>
là 10 lần xác nhận trước, nó sẽ hiển thị cho bạn tất cả 10 lần xác nhận.
Trước mỗi cam kết, nó sẽ có từ pick
. Tìm cam kết bạn muốn thoát khỏi và thay đổi nó từ pick
thành fixup
hoặc squash
. Sử dụng fixup
chỉ cần loại bỏ cam kết thông báo và hợp nhất các thay đổi vào tiền thân trực tiếp của nó trong danh sách. Các squash
từ khóa làm điều tương tự, nhưng cho phép bạn chỉnh sửa các cam kết thông báo của mới kết hợp cam kết.
Lưu ý rằng các cam kết sẽ được cam kết lại theo thứ tự chúng hiển thị trên danh sách khi bạn thoát khỏi trình chỉnh sửa. Vì vậy, nếu bạn đã thực hiện một cam kết tạm thời, sau đó thực hiện các công việc khác trên cùng một nhánh và hoàn thành tính năng trong một cam kết sau đó, thì việc sử dụng rebase sẽ cho phép bạn sắp xếp lại các cam kết và xóa chúng.
CẢNH BÁO:
Rebasing sửa đổi lịch sử - KHÔNG làm điều này với bất kỳ cam kết nào bạn đã chia sẻ với các nhà phát triển khác.
Đâm
Trong tương lai, để tránh vấn đề này, hãy cân nhắc sử dụng git stash
để tạm thời lưu trữ công việc không được cam kết.
git stash save 'some message'
Điều này sẽ lưu trữ các thay đổi hiện tại của bạn sang một bên trong danh sách stash của bạn. Trên đây là phiên bản rõ ràng nhất của lệnh stash, cho phép nhận xét để mô tả những gì bạn đang lưu trữ. Bạn cũng có thể chỉ cần chạy git stash
và không có gì khác, nhưng sẽ không có tin nhắn nào được lưu trữ.
Bạn có thể duyệt danh sách stash của bạn với ...
git stash list
Điều này sẽ cho bạn thấy tất cả các stash của bạn, chúng đã được thực hiện trên các nhánh nào, và thông báo và ở đầu mỗi dòng, và định danh cho stash đó trông giống như thế này trong stash@{#}
đó # là vị trí của nó trong mảng stash .
Để khôi phục stash (có thể được thực hiện trên bất kỳ nhánh nào, bất kể nơi nào stash ban đầu được tạo), bạn chỉ cần chạy ...
git stash apply stash@{#}
Một lần nữa, có # là vị trí trong mảng stash. Nếu stash bạn muốn khôi phục nằm ở 0
vị trí - nghĩa là, nếu đó là stash gần đây nhất. Sau đó, bạn chỉ có thể chạy lệnh mà không chỉ định vị trí stash, git sẽ cho rằng bạn có nghĩa là người cuối cùng : git stash apply
.
Vì vậy, ví dụ, nếu tôi thấy mình làm việc sai nhánh - tôi có thể chạy chuỗi lệnh sau.
git stash
git checkout <correct_branch>
git stash apply
Trong trường hợp của bạn, bạn di chuyển xung quanh các chi nhánh nhiều hơn một chút, nhưng ý tưởng tương tự vẫn được áp dụng.
Hi vọng điêu nay co ich.
git stash