2011-09-07 37 views
11

Tôi đang trong quá trình chia nhỏ bộ ứng dụng cũ mà ban đầu cư trú trong một kho lưu trữ Subversion duy nhất.Cách xóa tất cả các tệp trong kho lưu trữ Git không nằm trong thư mục làm việc?

Tôi đã chuyển đổi nó sang kho lưu trữ Git và xóa những gì tôi không muốn, nhưng tôi muốn giảm bớt kho lưu trữ bằng cách loại bỏ dữ liệu lịch sử liên kết với các tệp đã xóa (kho gốc được duy trì cho mục đích tham khảo vì vậy nó không cần thiết trong cái mới). Lý tưởng nhất mà tôi muốn làm là đi qua toàn bộ kho lưu trữ và xóa bất kỳ tệp hoặc thư mục nào không có trong thư mục làm việc, cùng với bất kỳ lịch sử nào được liên kết với chúng. Điều này sẽ để lại cho tôi nội dung của HEAD và lịch sử cam kết ảnh hưởng đến các tệp đó. Tuy nhiên, tôi đã không đi qua một cách để làm điều này (mồ côi HEAD không giúp đỡ vì nó không bảo tồn lịch sử).

Điều này có khả thi không? Tôi biết cách xóa một tệp hoặc thư mục duy nhất khỏi toàn bộ lịch sử qua git-filter-branch, nhưng có quá nhiều tệp và thư mục để trở thành phương pháp thực tế ... trừ khi có cách lọc trên tất cả các tệp không có trong HEAD ?

+0

gì về các tập tin đó đã đổi tên trong quá khứ? Lịch sử dải khi việc đổi tên xảy ra hoặc giữ lại tên (và theo dõi tên tập tin khác trước khi đổi tên) – knittl

+0

Điểm tốt. Tôi muốn giữ lịch sử trước khi đổi tên, do đó, cần phải có một vài tập tin phụ trong đó là tốt. –

Trả lời

3

Tôi đã thực hiện việc này một vài lần - trích xuất các cam kết cho một tệp và tạo kho lưu trữ mới từ chúng. Nó có phần như thế này:

$ c=10; for commit in $(git log --format=%h -- path/to/file|tac); do 
     c=$((c+1)) 
     git format-patch -1 --stdout $commit > $c.patch 
    done 

Điều này tạo ra các tệp vá 11.patch, 12.patch và cứ như vậy. Sau đó, tôi chỉnh sửa các bản vá này (sử dụng vim hoặc perl cho dù có vẻ tốt nhất cho công việc), xóa toàn bộ khối cho các tệp mà tôi không quan tâm và có thể sửa tên cũng như trong trường hợp đổi tên trong tiêu đề phân đoạn khác.

Tôi muốn sử dụng git am trên các bản vá trên kho lưu trữ git mới. Nếu một cái gì đó không đi lên ngay sau đó tôi nuke kho git mới và chỉnh sửa các bản vá lỗi một lần nữa và lặp lại git am.

Lý do tôi bắt đầu đếm từ 10 là vì tôi lười biếng để thêm vào trước 0 dẫn đến trình tự vá và cam kết hơn 99 Tôi chỉ bắt đầu từ 99.

+0

bạn có thể sử dụng '$ (printf"% 02d "$ c) .patch' để thêm một số không đứng đầu. – jfs

+0

Cảm ơn bạn đã đề cập đến điều đó. Tôi phải bắt đầu sử dụng printf thường xuyên hơn từ bây giờ. – holygeek

+0

Cảm ơn ... nhưng điều này không hoạt động trên một tệp theo cơ sở tệp? Như tôi đã nói trong câu hỏi của mình, tôi biết cách thực hiện nó trên cơ sở từng tệp, nhưng có quá nhiều tệp để thực tế. Hoặc có lẽ tôi hiểu lầm những gì đang xảy ra ở đây? –

6

Đây là cách bạn có thể sử dụng git Filter- nhánh để loại bỏ tất cả các tệp mà bạn không muốn:

  1. Lấy danh sách tên tệp mà bạn không muốn xuất hiện trong lịch sử cả tên cũ và tên mới trong trường hợp đổi tên . Ví dụ đặt chúng trong một tập tin gọi toberemoved.txt

  2. Run git filter-branch như thế này:

    $ git filter-branch --tree-filter "rm -f `cat toberemoved.txt`" branch1 branch2 ... 
    

Dưới đây là các trang người đàn ông có liên quan từ git filter-branch:

--tree-filter <command> 
     This is the filter for rewriting the tree and its contents. The 
     argument is evaluated in shell with the working directory set to 
     the root of the checked out tree. The new tree is then used as-is 
     (new files are auto-added, disappeared files are auto-removed - 
     neither .gitignore files nor any other ignore rules HAVE ANY 
     EFFECT!). 

Vì vậy, chỉ cần đảm bảo rằng danh sách các tệp bạn muốn xóa tất cả đều liên quan đến gốc của cây đã kiểm tra.

Cập nhật:

Để có được danh sách các tập tin mà đã có mặt trong quá khứ nhưng không có trong thư mục làm việc hiện tại bạn có thể chạy sau.Lưu ý rằng bạn sẽ phải làm nỗ lực hơn nữa để giữ cho "lịch sử trước khi đổi tên" các tập tin đổi tên:

$ git log --raw |awk '/^:/ { if (! printed[$6]) { print $6; printed[$6] = 1 }}'|while read f;do if [ ! -f $f ]; then echo Deleted: $f;fi;done 

Đó $ 6 là tên của tập tin đó đã bị ảnh hưởng trong một trong cam kết thể hiện trong --raw chế độ đăng nhập.

Xem tùy chọn --diff-filter để git log nếu bạn muốn biết điều gì đã xảy ra ([D] eleted, [R] enamed, [M] odified, v.v.) cho mỗi tệp cho mọi cam kết.

Có thể người khác có thể kêu gọi cách tìm tên trước của tệp được theo dõi trong trường hợp đổi tên.

+0

Cảm ơn câu trả lời mới. Đến gần hơn tôi nghĩ, tôi đã không nghĩ đến việc sử dụng 'cat' với bộ lọc-chi nhánh. Tuy nhiên, bit mà tôi vẫn chưa nhận được là cách tạo danh sách các tệp, vì tôi chỉ quan tâm đến việc xóa các tệp * không * trong thư mục làm việc (và do đó không sẵn có để liệt kê). Còn ý tưởng nào nữa không? –

+0

Tôi đã cập nhật câu trả lời để bao gồm lệnh để nhận danh sách các tệp đã xóa. – holygeek

+0

Câu trả lời hay. Tôi đã xóa 'Đã xóa:' khỏi trình duyệt trên để nhận danh sách. Nhưng khi sử dụng danh sách đó, vì lý do nào đó cú pháp bash trong lệnh git filter-branch không hoạt động. Vì vậy, thay vào đó, tôi đã sử dụng 'git filter-branch --tree-filter 'cat $ HOME/toberemoved.txt | xargs -I {} rm -f {}" '(Lưu ý rằng' toberemoved.txt' cần phải nằm ngoài thư mục Có thể điều này gây ra vấn đề với cú pháp '' cat 'toberemoved.txt'" 'nhưng tôi chưa kiểm tra.) – jaimedash

1

Giúp câu trả lời thứ hai: "Có thể người khác có thể kêu gọi cách tìm tên trước của tệp được theo dõi trong trường hợp đổi tên."

Thao tác này sẽ trả về các tệp trong dự án của bạn và các tệp mà từ đó chúng được đổi tên.

for file in `git ls-files`; do git log --follow --name-only --pretty=format: $file | sort -n -b | uniq | sed '/^\s*$/d'; done

Bạn có thể sử dụng chúng để loại trừ khỏi danh sách.

Toàn bộ giải pháp là:

for file in `git ls-files`; do git log --follow --name-only --pretty=format: $file | sort -n -b | uniq | sed '/^\s*$/d'; done > current.txt

git log --raw |awk '/^:/ { if (! printed[$6]) { print $6; printed[$6] = 1 }}'|while read f;do if [ ! -f $f ]; then echo $f;fi;done | sort > hist.txt

diff --new-line-format="" --unchanged-line-format="" hist.txt current.txt > for_remove.txt

Các vấn đề liên quan