Nếu tôi chạy git branch -d XYZ
, có cách nào để phục hồi chi nhánh không? Có cách nào để quay lại như thể tôi không chạy lệnh xóa nhánh không?
Nếu tôi chạy git branch -d XYZ
, có cách nào để phục hồi chi nhánh không? Có cách nào để quay lại như thể tôi không chạy lệnh xóa nhánh không?
Câu trả lời:
Có, bạn sẽ có thể làm git reflog
và tìm SHA1 cho cam kết ở đầu chi nhánh bị xóa của bạn, sau đó chỉ git checkout [sha]
. Và một khi bạn đã ở đó, bạn có thể git checkout -b [branchname]
tạo lại chi nhánh từ đó.
Tín dụng cho @Cascabel cho phiên bản cô đọng / một lớp này.
Bạn có thể làm điều đó trong một bước:
git checkout -b <branch> <sha>
git checkout -b <branch> <sha>
.
<sha>
. Ví dụ như đã đề cập ở trên -git checkout -b <branch> <sha>
CMD+K
)
git reflog --no-abbrev
để xem đầy đủ <sha>
được viết tắt theo mặc định.
git checkout remotes/origin/deleted_branch
.
Hầu hết thời gian cam kết không thể truy cập được trong reflog. Vì vậy, điều đầu tiên cần thử là xem xét reflog bằng lệnh git reflog
(hiển thị reflog cho HEAD
).
Có lẽ một cái gì đó dễ dàng hơn nếu cam kết là một phần của một nhánh cụ thể vẫn còn tồn tại là sử dụng lệnh git reflog name-of-my-branch
. Nó cũng hoạt động với một điều khiển từ xa, ví dụ nếu bạn buộc phải đẩy (lời khuyên bổ sung: luôn luôn thích git push --force-with-lease
thay vào đó để ngăn ngừa sai lầm tốt hơn và có thể phục hồi nhiều hơn).
Nếu các cam kết của bạn không nằm trong reflog của bạn (có lẽ do bị xóa bởi công cụ của bên thứ 3 không ghi trong reflog), tôi đã phục hồi thành công một nhánh bằng cách đặt lại nhánh của mình thành sha của cam kết được tìm thấy bằng lệnh như vậy (nó tạo một tập tin với tất cả các cam kết lơ lửng):
git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt
Nếu bạn nên sử dụng nó nhiều lần (hoặc muốn lưu nó ở đâu đó), bạn cũng có thể tạo bí danh bằng lệnh đó ...
git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'
và sử dụng nó với git rescue
Để điều tra các xác nhận được tìm thấy, bạn có thể hiển thị từng cam kết bằng cách sử dụng một số lệnh để xem xét chúng.
Để hiển thị siêu dữ liệu cam kết (tác giả, ngày tạo và thông báo cam kết):
git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
Để xem thêm các khác biệt:
git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
Khi bạn tìm thấy cam kết của mình, sau đó tạo một nhánh trên cam kết này với:
git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560
Đối với những người dùng Windows và thích GUI, bạn có thể dễ dàng khôi phục các cam kết (và cả các tệp được phân loại không được cam kết) với GitExtensions bằng cách sử dụng tính năng Repository
=> Git maintenance
=>Recover lost objects...
Một lệnh tương tự để dễ dàng khôi phục các tập tin được phân đoạn đã bị xóa: https://stackoverflow.com/a/58853981/717372
Nếu bạn muốn sử dụng GUI, bạn có thể thực hiện toàn bộ thao tác với gitk.
gitk --reflog
Điều này sẽ cho phép bạn xem lịch sử cam kết của chi nhánh như thể chi nhánh chưa bị xóa. Bây giờ chỉ cần nhấp chuột phải vào cam kết gần đây nhất với chi nhánh và chọn tùy chọn menu Create new branch
.
Giải pháp được bình chọn hàng đầu thực sự nhiều hơn yêu cầu:
git checkout <sha>
git checkout -b <branch>
hoặc là
git checkout -b <branch> <sha>
chuyển bạn đến chi nhánh mới cùng với tất cả các thay đổi gần đây mà bạn có thể đã quên cam kết. Đây có thể không phải là ý định của bạn, đặc biệt là khi ở "chế độ hoảng loạn" sau khi mất chi nhánh.
Một giải pháp sạch hơn (và đơn giản hơn) dường như là một lớp lót (sau khi bạn tìm thấy <sha>
với git reflog
):
git branch <branch> <sha>
Bây giờ, cả chi nhánh hiện tại và các thay đổi không được cam kết của bạn đều bị ảnh hưởng. Thay vào đó, chỉ có một nhánh mới sẽ được tạo ra cho đến <sha>
.
Nếu đó không phải là tiền boa, nó vẫn hoạt động và bạn có được một nhánh ngắn hơn, sau đó bạn có thể thử lại với <sha>
tên chi nhánh mới và mới cho đến khi bạn hiểu đúng.
Cuối cùng, bạn có thể đổi tên nhánh được khôi phục thành công thành tên được đặt tên hoặc bất cứ thứ gì khác:
git branch -m <restored branch> <final branch>
Không cần phải nói, chìa khóa để thành công là tìm đúng cam kết <sha>
, vì vậy hãy đặt tên cho cam kết của bạn một cách khôn ngoan :)
Thêm vào câu trả lời tfe : cũng có tập lệnh git-resurrect.sh trong contrib/
khu vực của nguồn Git (trong kho git.git), có thể giúp bạn.
git-resurrect <name>
cố gắng tìm dấu vết của một nhánh nhánh được gọi<name>
và cố gắng phục hồi nó. Hiện tại, reflog được tìm kiếm cho các tin nhắn thanh toán và-r
cũng có các tin nhắn hợp nhất. Với-m
và-t
, lịch sử của tất cả các ref được quét choMerge <name> into other
/Merge <other> into <name>
(tương ứng) các chủ đề cam kết, khá chậm nhưng cho phép bạn hồi sinh các nhánh chủ đề của người khác.
Tôi đã sử dụng các lệnh sau để tìm và lấy chi nhánh đã xóa của mình. Các bước đầu tiên là từ mô tả của gcb.
$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\ -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline
Bây giờ hãy tìm id git commit (GIT-SHA) dựa trên các nhận xét cam kết và sử dụng nó trong lệnh bên dưới. Kiểm tra một chi nhánh mới có tên MỚI-CHI NHÁNH với GIT-SHA được tìm thấy trước đó:
$ git checkout -b NEW-BRANCH GIT-SHA
Nếu bạn không có reflog, vd. bởi vì bạn đang làm việc trong một kho lưu trữ trống không bật reflog và cam kết bạn muốn khôi phục đã được tạo gần đây, một tùy chọn khác là tìm các đối tượng cam kết được tạo gần đây và xem qua chúng.
Từ trong .git/objects
thư mục chạy:
find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit
Điều này tìm thấy tất cả các đối tượng (cam kết, tệp, thẻ, v.v.) được tạo trong 12 giờ qua và lọc chúng để chỉ hiển thị các xác nhận. Kiểm tra những điều này sau đó là một quá trình nhanh chóng.
Trước tiên, tôi sẽ thử tập lệnh git-ressurect.sh được đề cập trong câu trả lời của Jakub .
man find
: "-ctime n - Trạng thái của tệp đã được thay đổi lần cuối n * 24 giờ trước." Vì vậy, chúng ta cũng nên thay đổi 12 thành 0,5 để có hành vi dự kiến trong 12 giờ qua.
Đối với người dùng GitHub không cài đặt Git:
Nếu bạn muốn khôi phục nó từ trang web GitHub , bạn có thể sử dụng API của họ để nhận danh sách các sự kiện liên quan đến repo:
Đầu tiên
tìm những SHA (cam kết băm):
curl -i https://api.github.com/repos/PublicUser/PublicRepo/events
... hoặc cho các repos riêng:
curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events
(sẽ được nhắc nhập mật khẩu GitHub)
Kế tiếp
• Đi đến chi nhánh và xóa cái đó.
• Trên cùng một trang, không tải lại , hãy mở DevTools, bảng điều khiển Mạng. Giờ hãy chuẩn bị ...
• Nhấp vào khôi phục. Bạn sẽ nhận thấy một "dòng" mới. Nhấp chuột phải vào nó và chọn "Sao chép dưới dạng cURL" và lưu văn bản này trong một số trình chỉnh sửa.
• Nối vào cuối dòng mã đã sao chép, mã này : -H "Cookie="
.
Bây giờ bạn sẽ nhận được một cái gì đó như:
curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed
Bước cuối cùng
PS
Tôi nhận ra đây có thể không phải là "giải pháp đơn giản nhất" hay giải pháp "đúng", nhưng nó được cung cấp trong trường hợp ai đó thấy nó hữu ích.
git reflog
và do đó rất hữu ích, ví dụ như khi đã xóa một nhánh từ xa và mất quyền truy cập vào máy tính được thực hiện từ đó không có gì lạnh hữu ích reflog
. Lưu ý khi sử dụng OAuth hoặc xác thực hai yếu tố trên Github , curl
lệnh sẽ trở thành dạng: curl -u username:token https://api.github.com/user
hoặccurl -H "Authorization: token TOKEN" https://api.github.com/repos/USER_OR_ORG_NAME/REPO_NAME/events
Theo hiểu biết của tôi nếu nhánh khác có thể bị xóa bởi nhánh khác, bạn có thể xóa nó một cách an toàn bằng cách sử dụng
git branch -d [branch]
và công việc của bạn không bị mất. Hãy nhớ rằng một nhánh không phải là một ảnh chụp nhanh, mà là một con trỏ đến một. Vì vậy, khi bạn xóa một nhánh bạn xóa một con trỏ.
Bạn thậm chí sẽ không mất việc nếu bạn xóa một chi nhánh mà một chi nhánh khác không thể liên lạc được. Tất nhiên sẽ không dễ như kiểm tra hàm băm cam kết, nhưng bạn vẫn có thể làm được. Đó là lý do tại sao Git không thể xóa một nhánh không thể đạt được bằng cách sử dụng -d
. Thay vào đó bạn phải sử dụng
git branch -D [branch]
Đây là một phần của video phải xem từ Scott Chacon về Git. Kiểm tra phút 58:00 khi anh ấy nói về các chi nhánh và cách xóa chúng.
reflog
chỉ là quá mức cần thiết.
Đảm bảo thực hiện tất cả điều này cục bộ và xác nhận repo của bạn ở trạng thái bạn muốn trước khi đẩy lên Bitbucket Cloud. Nó cũng có thể là một ý tưởng tốt để sao chép repo hiện tại của bạn và thử nghiệm các giải pháp này trước.
Deleted branch <your-branch> (was <sha>)
2.Để khôi phục chi nhánh, sử dụng:
git checkout -b <branch> <sha>
Nếu bạn không biết 'sha' trên đỉnh đầu, bạn có thể:
git reflog
git checkout -b <branch> <sha>
Nếu cam kết của bạn không nằm trong reflog của bạn:
git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt
2. Sau đó, bạn có thể hiển thị từng cam kết bằng một trong những điều sau:
git log -p <commit>
git cat-file -p <commit>
Tôi đã từ chối một chi nhánh từ xa để cố gắng xóa một vài cam kết mà tôi không muốn và sẽ chọn anh đào đúng những gì tôi muốn. Tất nhiên tôi đã viết SHA sai ...
Đây là cách tôi tìm thấy chúng (chủ yếu là giao diện / tương tác dễ dàng hơn từ những điều trong câu trả lời ở đây):
Đầu tiên, tạo một danh sách các cam kết lỏng lẻo trong nhật ký của bạn. Làm điều này càng sớm càng tốt và ngừng hoạt động, vì những thứ đó có thể bị đổ bởi người thu gom rác.
git fsck --full --no-reflogs --unreachable --lost-found > lost
Điều này tạo ra một lost
tập tin với tất cả các cam kết bạn sẽ phải xem xét. Để đơn giản hóa cuộc sống của chúng ta, chúng ta chỉ cắt SHA khỏi nó:
cat lost | cut -d\ -f3 > commits
Bây giờ bạn có một commits
tệp với tất cả các cam kết bạn phải xem.
Giả sử bạn đang sử dụng Bash, bước cuối cùng:
for c in `cat commits`; do git show $c; read; done
Điều này sẽ cho bạn thấy thông tin khác biệt và cam kết cho từng người trong số họ. Và chờ bạn nhấn Enter. Bây giờ hãy viết ra tất cả những gì bạn muốn, và sau đó chọn chúng vào. Sau khi bạn hoàn thành, chỉ cần Ctrl-C nó.
CÓ LỚN
nếu bạn đang sử dụng GIT, hãy làm theo các bước đơn giản sau https://confluence.atlassian.com/bbkb/how-to-restore-a-delatted-branch-765757540.html
nếu bạn đang sử dụng smartgit và đã đẩy chi nhánh đó về nguồn gốc, hãy tìm chi nhánh đó và nhấp chuột phải rồi thanh toán
Đầu tiên, hãy chuyển git batch di chuyển đến dự án của bạn như sau:
cd android studio project
cd Myproject
then type :
git reflog
Tất cả các bạn đều có một danh sách các thay đổi và số tham chiếu lấy số ref sau đó kiểm tra
từ studio android hoặc từ git betcha. một giải pháp khác lấy số ref và vào android studio bấm vào git cành xuống sau đó nhấp vào thẻ thanh toán hoặc sửa đổi qua số tham chiếu sau đó lol bạn có các nhánh.
Thêm vào câu trả lời của tfe, bạn có thể khôi phục với quy trình này được đề cập, trừ khi cam kết không phải là rác được thu thập. Nhánh Git đơn giản là một con trỏ tới một xác nhận cụ thể trong cây cam kết. Nhưng nếu bạn xóa con trỏ và các xác nhận trên nhánh đó không được hợp nhất vào nhánh khác hiện có, thì git coi nó như các cam kết lơ lửng và loại bỏ chúng trong quá trình thu gom rác, nó có thể tự động chạy theo định kỳ.
Nếu chi nhánh của bạn không được hợp nhất với một chi nhánh hiện có và nếu đó là rác được thu thập, thì bạn sẽ mất tất cả các cam kết cho đến khi điểm mà chi nhánh được rẽ nhánh từ một chi nhánh hiện có.
Một vấn đề liên quan: Tôi đã đến trang này sau khi tìm kiếm "làm thế nào để biết những chi nhánh bị xóa".
Trong khi xóa nhiều nhánh cũ, tôi cảm thấy đã xóa nhầm một trong những nhánh mới hơn, nhưng không biết tên để khôi phục nó.
Để biết những chi nhánh nào bị xóa gần đây, hãy làm như sau:
Nếu bạn truy cập URL Git của mình, nó sẽ trông giống như thế này:
https://your-website-name/orgs/your-org-name/dashboard
Sau đó, bạn có thể thấy nguồn cấp dữ liệu, về những gì đã bị xóa, bởi ai, trong quá khứ gần đây.
Tôi đã làm điều này trên máy tính mà tôi xóa chi nhánh:
git reflog
phản ứng:
74b2383 (develope) HEAD@{1}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: checkout: moving from develope to master
74b2383 (develope) HEAD@{3}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{4}: reset: moving to HEAD
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git
và tôi lấy chi nhánh bằng lệnh này:
git checkout -b newBranchName 74b2383
Chỉ sử dụng git reflog
đã không trả lại sha
cho tôi. Chỉ có commit id
(dài 8 ký tự và một sha dài hơn)
Vì vậy, tôi đã sử dụng
git reflog --no-abbrev
Và sau đó làm tương tự như đã đề cập ở trên:
git checkout -b <branch> <sha>
Lưu ý rằng xóa chi nhánh git chỉ xóa bản sao cục bộ, không xóa bản sao trên máy chủ. Đầu tiên, trong bảng Git (biểu tượng git trên thanh công cụ bên trái), xem qua các nhánh và xem nhánh của bạn có còn ở đó trong "origin / your_branch_name" không. Nếu vậy, chỉ cần chọn điều đó và bạn sẽ lấy lại mã của mình (đề nghị bạn ngay lập tức sao chép / dán / lưu mã cục bộ ở một nơi khác).
Nếu bạn không thấy "origin / your_branch_name", hãy cài đặt tiện ích mở rộng GitLens. Điều này cho phép bạn trực quan chọc vào kho lưu trữ của máy chủ và định vị bản sao bạn đã đồng bộ hóa với máy chủ. Nếu bạn có nhiều kho lưu trữ, lưu ý rằng có thể cần phải có ít nhất một tệp được mở từ kho lưu trữ mong muốn để làm cho kho lưu trữ xuất hiện trong GitLens. Sau đó:
Mở bảng GitLens
Mở rộng kho lưu trữ
Bạn sẽ thấy một danh sách các danh mục: Chi nhánh / Cộng tác viên / Từ xa / Stash / vv
Bạn nên tìm YourLostTreasure trong "Chi nhánh" hoặc có thể trong "Điều khiển từ xa -> Nguồn gốc". Hy vọng rằng, bạn sẽ thấy một nhánh có tên mong muốn - nếu bạn mở rộng nó, bạn sẽ thấy các tệp bạn đã thay đổi trong nhánh đó. Bấm đúp vào tên tệp để mở chúng và ngay lập tức sao lưu mã đó.
Nếu bạn không thấy ngay chi nhánh bị mất của mình, hãy chọc ngoáy và nếu bạn thấy điều gì đó hứa hẹn, hãy lập tức mở nó và lấy mã. Tôi đã phải tìm kiếm một chút cho đến khi tôi tìm thấy TheGoldenBranch, và thậm chí sau đó mã bị thiếu một hoặc hai lần lưu cuối cùng (có thể do tôi không đồng bộ hóa với máy chủ trước khi thử-a-Branch-Merge-but-vô tình-nhấp chuột- Chi nhánh-Xóa). Việc tìm kiếm của tôi bị kéo dài một cách không cần thiết bởi vì khi tôi lần đầu tiên tìm thấy chi nhánh, tôi không hoàn toàn chắc chắn rằng tên đó là chính xác nên đã tiếp tục tìm kiếm và phải mất một thời gian để tìm lại chi nhánh đầu tiên đó. (Vì vậy, Carpe Carpum và sau đó tiếp tục tìm kiếm.)