Xóa refs / gốc / Heads / master khỏi git repo sau bộ lọc nhánh --tree-filter?


180

Tôi đã có cùng một câu hỏi như được hỏi ở đây: Kho git mới trong thư mục gốc để lấy một kho lưu trữ tồn tại trong một thư mục con

Tôi đã làm theo câu trả lời này ở đây: Kho git mới trong thư mục gốc để lưu trữ một kho lưu trữ tồn tại trong một thư mục con

Bây giờ, gitk --allcho thấy hai lịch sử: một đỉnh cao trong hiện tại mastervà một lịch sử được đặt tên original/refs/heads/master.

Tôi không biết lịch sử thứ hai này là gì hoặc làm thế nào để xóa nó khỏi repo. Tôi không cần hai lịch sử trong kho lưu trữ của tôi.

Làm sao để tôi bỏ nó đi?

Để tái sản xuất chính mình:

mkdir -p project-root/path/to/module
cd project-root/path/to/module
mkdir dir1 dir2 dir3 
for dir in * ; do touch $dir/source-file-$dir.py ; done
git init
git add .
git commit -m 'Initial commit'

Bây giờ chúng tôi có vấn đề của người gửi ban đầu. Hãy chuyển gốc của git repo sang gốc dự án bằng câu trả lời được liên kết ở trên:

git filter-branch --tree-filter 'mkdir -p path/to/module ; git mv dir1 dir2 dir3 path/to/module' HEAD
rm -rf path
cd ../../../ # Now PWD is project-root
mv path/to/module/.git .
git reset --hard

Bây giờ, hãy xem vấn đề hiện tại của tôi:

gitk --all &
git show-ref

Làm thế nào để tôi thoát khỏi refs/original/heads/mastervà tất cả lịch sử liên quan?


Câu trả lời:


321

refs/original/*có một bản sao lưu, trong trường hợp bạn làm rối nhánh lọc của mình. Hãy tin tôi, đó là một ý tưởng thực sự tốt.

Khi bạn đã kiểm tra kết quả và bạn rất tự tin rằng bạn có những gì bạn muốn, bạn có thể xóa tham chiếu đã sao lưu:

git update-ref -d refs/original/refs/heads/master

hoặc nếu bạn đã làm điều này với nhiều người giới thiệu và bạn muốn xóa sạch tất cả:

git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

(Điều đó được lấy trực tiếp từ trang quản lý chi nhánh bộ lọc.)

Điều này không áp dụng cho bạn, nhưng với những người khác có thể tìm thấy điều này: Nếu bạn thực hiện một nhánh bộ lọc loại bỏ nội dung chiếm dung lượng đĩa đáng kể, bạn cũng có thể muốn chạy git reflog expire --expire=now --allgit gc --prune=nowhết hạn các bản cập nhật và xóa các đối tượng hiện không sử dụng . (Cảnh báo: hoàn toàn, hoàn toàn không thể đảo ngược. Hãy chắc chắn trước khi bạn làm điều đó.)


Sau khi thực hiện update-ref, reflog hết hạn và gc, cả hai tập tin vẫn còn tham chiếu ref gốc: .git / info / refs và .git / đóng gói-refs trông giống như có lẽ đó nên nói điều này thay vì:git update-ref -d refs/original/refs/heads/master
lhunath

1
Tôi đoán bạn đã vô tình trộn lẫn các từ: Nếu tôi đúng, nó sẽ là git update-ref -d original/refs/heads/mastergì? Tuy nhiên, chỉ có lệnh thứ hai của bạn làm việc cho tôi.
JJD

4
Đó là git update-ref -d refs/original/refs/heads/masterbtw. Bạn có thể xem tên đầy đủ bằng cách sử dụng git show-ref.
chọc

4
Còn cái ngắn hơn git show-ref refs/original/* --hash | xargs -n 1 git update-ref -dthì sao?
CharlesB

11

Và nếu bạn đang ở trong Windows PowerShell:

git for-each-ref --format="%(refname)" refs/original/ | foreach-object -process { git update-ref -d $_ }

7

filter-branchgiữ các bản sao lưu để kho lưu trữ cần phải dọn sạch các bản cập nhật và thu gom rác. Đảm bảo rằng không có nhu cầu trong bản sao lưu này trước khi xóa:

rm -Rf .git/refs/original
git gc --aggressive --prune=now
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.