Tôi biết đó là viết lại lịch sử đó là xấu yada yada.
Nhưng làm thế nào để loại bỏ vĩnh viễn vài cam kết từ chi nhánh từ xa?
Tôi biết đó là viết lại lịch sử đó là xấu yada yada.
Nhưng làm thế nào để loại bỏ vĩnh viễn vài cam kết từ chi nhánh từ xa?
Câu trả lời:
Bạn git reset --hard
chi nhánh địa phương của bạn để loại bỏ các thay đổi từ cây và chỉ mục làm việc, và bạn git push --force
chi nhánh địa phương sửa đổi của bạn vào điều khiển từ xa. ( giải pháp khác ở đây , liên quan đến việc xóa chi nhánh từ xa và đẩy lại nó)
Câu trả lời SO này minh họa sự nguy hiểm của một lệnh như vậy, đặc biệt nếu mọi người phụ thuộc vào lịch sử từ xa cho các repos địa phương của riêng họ.
Bạn cần chuẩn bị để chỉ ra mọi người vào phần THU HỒI TỪ UPSTREAM REBASE của git rebase
trang man
Với Git 2.23 (tháng 8 năm 2019, chín năm sau), bạn sẽ sử dụng lệnh mới git switch
.
Đó là:
(thay thế bằng số lần xác nhận cần xóa)git switch -C mybranch origin/mybranch~n
n
Điều đó sẽ khôi phục chỉ mục và cây làm việc, giống như một git reset --hard
.
push --force
đi
git gc
không phải lúc nào cũng chạy đủ thường xuyên ở phía xa. Ví dụ: trên GitHub: twitter.com/githubhelp/status/387926738161774592?lang=es
Chỉ cần lưu ý để sử dụng last_working_commit_id
, khi hoàn nguyên một cam kết không hoạt động
git reset --hard <last_working_commit_id>
Vì vậy, chúng tôi không được thiết lập lại commit_id
mà chúng tôi không muốn.
Sau đó, chắc chắn, chúng ta phải đẩy đến chi nhánh từ xa:
git push --force
git reset --hard
phải làm.
Có ba tùy chọn hiển thị trong hướng dẫn này . Trong trường hợp liên kết bị phá vỡ, tôi sẽ để lại các bước chính ở đây.
1 Hoàn nguyên cam kết đầy đủ
git revert dd61ab23
2 Xóa cam kết cuối cùng
git push <<remote>> +dd61ab23^:<<BRANCH_NAME_HERE>>
hoặc, nếu chi nhánh có sẵn tại địa phương
git reset HEAD^ --hard
git push <<remote>> -f
trong đó + dd61 ... là hàm băm cam kết và git của bạn diễn giải x ^ với tư cách là cha mẹ của x và + là một lực đẩy không nhanh chóng bắt buộc.
3 Xóa cam kết khỏi danh sách
git rebase -i dd61ab23^
Điều này sẽ mở và biên tập hiển thị một danh sách của tất cả các cam kết. Xóa cái bạn muốn thoát khỏi. Kết thúc cuộc nổi loạn và đẩy lực lượng để repo.
git rebase --continue
git push <remote_repo> <remote_branch> -f
Nếu bạn muốn xóa ví dụ các lần xác nhận cuối cùng 3
, hãy chạy lệnh sau để xóa các thay đổi khỏi hệ thống tệp (cây làm việc) và lịch sử cam kết (chỉ mục) trên nhánh cục bộ của bạn:
git reset --hard HEAD~3
Sau đó chạy lệnh sau (trên máy cục bộ của bạn) để buộc nhánh từ xa viết lại lịch sử của nó:
git push --force
Xin chúc mừng! Tất cả đã được làm xong!
Một số lưu ý:
Bạn có thể truy xuất id xác nhận mong muốn bằng cách chạy
git log
Sau đó, bạn có thể thay thế HEAD~N
bằng <desired-commit-id>
như thế này:
git reset --hard <desired-commit-id>
Nếu bạn muốn giữ các thay đổi trên hệ thống tệp và chỉ sửa đổi chỉ mục (lịch sử cam kết), hãy sử dụng --soft
cờ như thế nào git reset --soft HEAD~3
. Sau đó, bạn có cơ hội kiểm tra các thay đổi mới nhất của mình và giữ hoặc bỏ tất cả hoặc một phần của chúng. Trong trường hợp sau, runnig git status
hiển thị các tệp đã thay đổi kể từ đó <desired-commit-id>
. Nếu bạn sử dụng --hard
tùy chọn, git status
sẽ cho bạn biết rằng chi nhánh địa phương của bạn giống hệt như chi nhánh từ xa. Nếu bạn không sử dụng --hard
cũng không --soft
, chế độ mặc định được sử dụng --mixed
. Trong chế độ này, git help reset
nói:
Đặt lại chỉ mục nhưng không phải cây làm việc (nghĩa là các tệp đã thay đổi được giữ nguyên nhưng không được đánh dấu cho cam kết) và báo cáo những gì chưa được cập nhật.
Điều này có thể là quá ít quá muộn nhưng điều giúp tôi là tùy chọn 'hạt nhân' nghe hay. Về cơ bản bằng cách sử dụng lệnh, filter-branch
bạn có thể xóa tệp hoặc thay đổi một số lượng lớn tệp trong toàn bộ lịch sử git của mình.
Nó được giải thích tốt nhất ở đây .
Đơn giản hóa từ câu trả lời của pctroll, tương tự dựa trên bài đăng trên blog này .
# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git revert 42480f3
# a text editor will open, close it with ctrl+x (editor dependent)
git push origin your_branch
# or replace origin with your remote
Đôi khi cách dễ nhất để khắc phục vấn đề này là tạo một chi nhánh mới từ nơi bạn biết mã là tốt. Sau đó, bạn có thể để lại lịch sử chi nhánh sai lầm trong trường hợp bạn cần chọn các cam kết khác từ nó sau này. Điều này cũng đảm bảo bạn không mất bất kỳ lịch sử cam kết nào.
Từ chi nhánh sai lầm địa phương của bạn:
git log
sao chép hàm băm cam kết mà bạn muốn chi nhánh ở và thoát khỏi nhật ký git
git checkout theHashYouJustCopied
git checkout -b your_new_awesome_branch
Bây giờ bạn có một chi nhánh mới theo cách bạn muốn.
Nếu bạn cũng cần giữ một cam kết cụ thể từ nhánh sai lầm không có trên nhánh mới của mình, bạn có thể chọn cherry mà bạn cần:
git checkout the_errant_branch
git log
Sao chép hàm băm cam kết của một cam kết bạn cần để kéo vào nhánh tốt và thoát khỏi nhật ký git.
git checkout your_new_awesome_branch
git cherry-pick theHashYouJustCopied
Hãy vỗ nhẹ vào lưng.