Tại sao tôi có thể kiểm tra một chi nhánh đã bị xóa trên GitHub?


26

Trong kho GitHub của chúng tôi, đồng nghiệp đã xóa một nhánh có tên release. Nhưng khi tôi chạy git checkout releasecục bộ, tôi luôn lấy được nhánh bị loại bỏ release. Tương tự, ngay cả khi tôi kiểm tra một chi nhánh khác, xóa releasechi nhánh đó git branch -D releasevà chạy lại git checkout release.

Có cái gì đó để sửa trên kho GitHub, hoặc tôi sẽ sửa cái gì đó cục bộ?


1
git branch --remoteĐầu ra là gì , sau khi chạy git fetch? Bạn có thể cần phải cắt tỉa git fetch -pđể quên các nhánh từ xa bị xóa.
Stephen Kitt

2
Nếu chi nhánh đó đã từng được đẩy lên GitHub và bạn đã kéo sau đó, thì bạn cũng có một bản sao của chi nhánh. Mỗi kho git đều tự hoàn thành, trừ khi bạn sử dụng một bản sao nông hoặc một cái gì đó.
muru

@StephenKitt: Cảm ơn. git branch --remoteđầu ra origin/release. Bạn có nghĩa là chạy git fetch -pmà không cần thêm đối số, và nó sẽ cắt tỉa tất cả các nhánh từ xa đã xóa?
Tim

1
Có, git fetch -pkhông có đối số bổ sung sẽ cắt tỉa tất cả các nhánh từ xa bị xóa.
Stephen Kitt

1
Chào mừng bạn đến với thế giới của kiểm soát phiên bản phân tán!
chrylis -on đình công-

Câu trả lời:


24

Sau khi xóa một nhánh ở phía xa, bạn vẫn có thể thấy nhánh từ xa được tìm nạp trước đó cục bộ, xem:

$ git branch -a
[...]
release
remotes/origin/release
[...]

Bạn chỉ xóa "phát hành" chứ không xóa "từ xa / nguồn gốc / phát hành". Xóa nó như thế này:

$ git branch -rd origin/release

Hoặc xóa tất cả các nhánh được tìm thấy không còn tồn tại ở phía xa nữa:

$ git remote prune origin 

Cảm ơn. Trong git branch -rd origin/release, -rcó nghĩa là gì? Có -dnghĩa là giống như -D? Có git branch -rd origin/releasethể thay thế bằng git branch -d remotes/origin/release?
Tim

@Tim: Từ hướng dẫn; -r : List or delete (if used with -d) the remote-tracking branches.; -D:Shortcut for --delete --force.
looper

Cảm ơn. Có git branch -rd origin/releasethể thay thế bằng git branch -d remotes/origin/release?
Tim

@Tim không -rđề cập đến các chi nhánh từ xa , nó cần thiết. Các nhánh cục bộ và từ xa được lưu trữ trong các thư mục khác nhau, so sánh ls -l .git/refs/headsls -l .git/refs/remotes. Bạn cũng có thể có một chi nhánh địa phương được gọi là remotes/origin/releasesẽ bị xóa mà không có -r. Điều này nghe có vẻ khó hiểu nhưng bạn chỉ có thể chơi xung quanh, tạo các nhánh có tên lạ và xem nó trông như thế nào .git/.
rudimeier

15

Khi các chi nhánh bị xóa từ xa, bạn cần cắt tỉa kho lưu trữ cục bộ của mình - cách dễ nhất để thực hiện việc này là với

git fetch -p

Điều này sẽ cập nhật kho lưu trữ cục bộ của bạn với tất cả các thay đổi được thực hiện cho kho lưu trữ từ xa, nhưng không cập nhật bất kỳ chi nhánh địa phương nào của bạn. Sau khi chạy nó,

git branch --remote

sẽ không còn hiển thị các chi nhánh từ xa bị xóa.

kho git đã hoàn tất, cho dù trên hệ thống của riêng bạn hay trên máy chủ. Vì vậy, khi bạn lần đầu tiên sao chép một kho lưu trữ, bạn sẽ nhận được một bản sao hoàn chỉnh và git cục bộ của bạn biết về tất cả các chi nhánh từ xa cũng như các chi nhánh địa phương của bạn. Thông tin này không được đồng bộ hóa tự động, vì vậy khi đồng nghiệp của bạn xóa releasechi nhánh trên máy chủ, kho git cục bộ của bạn đã không mất khái niệm về một releasechi nhánh từ xa . Đồng bộ hóa với git fetchcập nhật tất cả thông tin cục bộ trên các nhánh từ xa để chúng khớp với trạng thái trên máy chủ (nói đúng, kho lưu trữ từ xa, bất cứ nơi nào), nhưng không xóa bất kỳ thông tin cục bộ nào trên các nhánh từ xa. Cắt tỉa bằng git fetch -p(hoặc git fetch --prune, hoặc git remote prune) xóa thông tin cục bộ trên các nhánh từ xa đã bị xóa.


Cảm ơn. "Cập nhật kho lưu trữ cục bộ của bạn với tất cả các thay đổi được thực hiện cho kho lưu trữ từ xa, nhưng không cập nhật bất kỳ chi nhánh địa phương nào của bạn". Bản cập nhật nào là vậy, cho rằng nó không phải là cập nhật của các chi nhánh địa phương của tôi?
Tim

Đó là tất cả các bản cập nhật từ xa. Kho git cục bộ của bạn phân biệt các nhánh cục bộ của bạn và các nhánh từ xa, nhưng các nhánh từ xa không được đồng bộ hóa một cách kỳ diệu với máy chủ - chúng cũng tồn tại cục bộ (như trong, được lưu trữ trong kho git cục bộ của bạn). Tìm nạp đồng bộ hóa kho lưu trữ cục bộ của bạn với kho lưu trữ từ xa và cập nhật trạng thái của các nhánh từ xa; theo mặc định, các nhánh từ xa bị xóa không bị xóa khỏi thông tin cục bộ trên các nhánh từ xa, -p( --prune) buộc điều đó.
Stephen Kitt

Cảm ơn. Tại sao không xóa các releasechi nhánh bằng cách git branch -D releasetrước khi git checkout releaselàm git checkout releasengừng nhận được releasechi nhánh?
Tim

1
Bởi vì git checkout releasesẽ tự động tạo lại một nhánh nếu có một nhánh từ xa có tên đó.
Stephen Kitt

Theo "nhánh từ xa", bạn có nghĩa là một nhánh trong kho lưu trữ cục bộ hoặc kho lưu trữ Github của tôi? Nếu trước đây, git branch -D releaseđã xóa releasechi nhánh trong kho lưu trữ cục bộ của tôi; Nếu sau đó, một đồng nghiệp đã xóa releasechi nhánh trên GitHub; Vì vậy, tôi vẫn không chắc chắn tại sao "sẽ tự động tạo lại một chi nhánh nếu có một chi nhánh từ xa với tên đó"?
Tim

3

Tim: Git được phân phối VCS, vì vậy khi bạn sao chép một repo từ xa đến địa phương của bạn, nó sẽ nhân bản mọi thứ (lịch sử). Vì vậy, khi bạn nhân bản repo của mình, nó có một nhánh gọi là phát hành. Vì đồng nghiệp của bạn đã xóa chi nhánh phát hành từ xa, cho đến khi bạn thực hiện cắt tỉa git fetch -phoặc xóa chi nhánh đó một cách rõ ràng thì địa phương của bạn sẽ có chi nhánh đó.


3
Làm thế nào để câu trả lời này khác với câu trả lời đã có?
Stephen Rauch

1

Có lẽ một chút tiếp tuyến nhưng quan điểm của trang web này có thể giúp hiểu được chủ đề chung về xóa chi nhánh:

http://railsware.com/blog/2014/08/11/git-housekeep-tutorial-clean-up-outdated-branches-in-local-and-remote-reposeocate/

Có sự trùng lặp với một số điều đã được thảo luận ở đây nhưng trọng tâm là việc dọn phòng: xóa các chi nhánh, từ xa và cục bộ, không còn cần thiết trong môi trường hợp tác. Cụ thể, git branch --mergedlệnh xác định các nhánh an toàn để xóa do được hợp nhất với dòng chính của bạn (hoặc bất kỳ nhánh nào bạn quan tâm). Nếu bạn đang hợp tác, một số kịch bản mini fancier như thế này sẽ trình bày mọi thứ ở định dạng dễ đọc, dễ đọc với ngày và tác giả.

for branch in `comm -12  <(git branch --merged|awk '{print($1)}') <(git branch -r --merged|awk '{print($1)}'|awk -F \/ '{print($2)}')`; do echo -e `git show --format="%ci %cr %an" $branch | head -n 1` \\t$branch; done | sort -r

(Thật không may "đẹp, dễ tiêu hóa" không áp dụng cho định dạng của các tập lệnh.)

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.