2011-07-09 33 views
8

Tôi có một kho lưu trữ và tôi muốn tách một trong các thư mục của nó thành một repo mới. This là một nơi hoàn hảo để bắt đầu, tuy nhiên, có một thông báo trước: thư mục mà tôi muốn tách được đổi tên tại một số điểm. Và nếu tôi làm theo các giải pháp từ bài viết đó với tên mới của thư mục thì có vẻ như tôi mất lịch sử trước khi đổi tên. Bất kỳ ý tưởng của một tinh chỉnh để làm cho nó hoạt động trong tình huống này?Tách thư mục con (đã được đổi tên thành!) Thành một repo mới

Trả lời

9

git filter-branch có thể hoạt động trên phạm vi cam kết; vì vậy những gì chúng ta có thể làm là lọc các 'trước' và 'sau khi' riêng biệt, và sử dụng ghép để tack chúng lại với nhau:

git branch rename $COMMIT_ID_OF_RENAME 
git branch pre-rename rename~ 
## First filter all commits up to rename, but not rename itself 
git filter-branch --subdirectory-filter $OLDNAME pre-rename 
## Add a graft, so our rename rev comes after the processed pre-rename revs 
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts 
## The first filter-branch left a refs backup directory. Move it away so the 
## next filter-branch doesn't complain 
mv .git/refs/original .git/refs/original0 
## Now filter the rest 
git filter-branch --subdirectory-filter $NEWNAME master ^pre-rename 
## The graft is now baked into the branch, so we don't need it anymore 
rm .git/info/grafts 

Đây là nhẹ phức tạp hơn nếu bạn cần phải lọc nhiều chi nhánh hoặc thẻ; các nhánh trước khi đổi tên có thể được đưa vào nhánh lọc đầu tiên, trong khi các nhánh sau phải được bao gồm trước số ^rename trong nhánh lọc thứ hai.

Tùy chọn khác sẽ là thêm bộ lọc chỉ mục (hoặc bộ lọc cây) thay vào đó kiểm tra cả thư mục, cũ và mới và giữ tùy chọn nào có mặt.

Vì bạn chưa cung cấp kho kiểm tra, đây là một kịch bản sự tỉnh táo kiểm tra nhanh cho kịch bản này:

#!/bin/bash 

set -u 
set -e 
set -x 

rm -rf .git x y foo 

git init 
mkdir x 
echo initial > x/foo 
git add x/foo 
git commit -m 'test commit 1' 

echo tc2 >> x/foo 
git commit -a -m 'test commit 2' 

mv x y 
git rm x/foo 
git add y/foo 
git commit -a -m 'test rename' 

git branch rename HEAD 

echo post rename >> y/foo 
git commit -a -m 'test post rename' 

git branch pre-rename rename~ 

git filter-branch --subdirectory-filter x pre-rename 
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts 

mv .git/refs/original .git/refs/original0 

git filter-branch --subdirectory-filter y master ^pre-rename 

rm .git/info/grafts 

git log -u 

Nếu thủ tục này không làm việc cho bạn, sau đó có khả năng là một cái gì đó khác lạ về lịch sử kho lưu trữ mà bạn chưa mô tả, chẳng hạn như ẩn tên đổi tên khác trong lịch sử.

+0

Hmm, tôi đã thử phương pháp của bạn với ghép (mà tôi không biết gì về) và nó đã không làm việc cho tôi. Sau khi xử lý một trong các cam kết "trước" bị trống, các tệp khác của một người đã được chuyển vào thư mục gốc của repo; Tôi không thể hiểu được nó. Tôi đã suy nghĩ trước khi sử dụng một bộ lọc cây nhưng không có bất kỳ kinh nghiệm với điều đó; bạn sẽ quan tâm để xây dựng cho tôi một số gợi ý? – akoprowski

+0

Bạn có chắc chắn cam kết trước đó đã sử dụng đúng subdir không? Bạn có thể đăng git repo của bạn ở đâu đó? – bdonlan

+0

Yup, đổi tên là trên cam kết đã làm đổi tên và đổi tên trước ngay trước nó. Các repo là rất lớn và một phần tư nhân vì vậy tôi không thể thực sự xuất bản nó bất cứ nơi nào: | – akoprowski

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