Đây là lệnh git-filter-branch có thể chạy trong nhà cung cấp dịch vụ lưu trữ miễn phí OnWorks bằng cách sử dụng một trong nhiều máy trạm trực tuyến miễn phí của chúng tôi như Ubuntu Online, Fedora Online, trình giả lập trực tuyến Windows hoặc trình mô phỏng trực tuyến MAC OS
CHƯƠNG TRÌNH:
TÊN
git-filter-branch - Viết lại các nhánh
SYNOPSIS
git chi nhánh lọc [--env-filter ] [--tree-filter ]
[--index-filter ] [--parent-filter ]
[--msg-filter ] [--commit-filter ]
[--tag-name-filter ] [- subdirectory-filter ]
[--prune-rỗng]
[--nguyên bản ] [-NS ] [-f | --lực lượng]
[-] [ ...]
MÔ TẢ
Cho phép bạn viết lại lịch sử sửa đổi Git bằng cách viết lại các nhánh được đề cập trong
tùy chọn>, áp dụng các bộ lọc tùy chỉnh trên mỗi bản sửa đổi. Những bộ lọc đó có thể sửa đổi từng cây
(ví dụ: xóa một tệp hoặc chạy viết lại perl trên tất cả các tệp) hoặc thông tin về mỗi
làm. Nếu không, tất cả thông tin (bao gồm cả thời gian cam kết ban đầu hoặc thông tin hợp nhất)
sẽ được giữ nguyên.
Lệnh sẽ chỉ viết lại tích cực ref được đề cập trong dòng lệnh (ví dụ: nếu bạn
vượt qua a..b, chỉ có b sẽ được viết lại). Nếu bạn chỉ định không có bộ lọc, các cam kết sẽ là
gửi lại mà không có bất kỳ thay đổi nào, điều này thường sẽ không có hiệu lực. Tuy nhiên, điều này
có thể hữu ích trong tương lai để bù đắp cho một số lỗi Git hoặc tương tự, do đó
được phép sử dụng.
LƯU Ý: Lệnh này tôn vinh tệp .git / info / grafts và các tham chiếu trong không gian refs / Replace / names.
Nếu bạn đã xác định bất kỳ điểm ghép hoặc giới thiệu thay thế nào, việc chạy lệnh này sẽ làm cho chúng
dài hạn.
CẢNH BÁO! Lịch sử được viết lại sẽ có các tên đối tượng khác nhau cho tất cả các đối tượng và
sẽ không hội tụ với nhánh ban đầu. Bạn sẽ không thể dễ dàng đẩy và
phân phối nhánh viết lại trên đầu nhánh gốc. Vui lòng không sử dụng cái này
lệnh nếu bạn không biết đầy đủ hàm ý và tránh sử dụng nó, nếu đơn giản
cam kết duy nhất sẽ đủ để khắc phục sự cố của bạn. (Xem phần "PHỤC HỒI TỪ UPSTREAM
REBASE "phần trong git-rebase(1) để biết thêm thông tin về việc viết lại đã xuất bản
Môn lịch sử.)
Luôn xác minh rằng phiên bản viết lại là chính xác: Bản tham chiếu ban đầu, nếu khác với
những cái được viết lại, sẽ được lưu trữ trong không gian tên refs / gốc /.
Lưu ý rằng vì thao tác nhập / xuất này rất tốn kém, nên chuyển hướng có thể là một ý tưởng hay
thư mục tạm thời ngoài đĩa với -d tùy chọn, ví dụ: trên tmpfs. Báo cáo tốc độ
là rất đáng chú ý.
Bộ Lọc
Các bộ lọc được áp dụng theo thứ tự như được liệt kê bên dưới. Các đối số luôn luôn
được đánh giá trong ngữ cảnh shell bằng cách sử dụng đánh giá lệnh (với ngoại lệ đáng chú ý của
bộ lọc cam kết, vì lý do kỹ thuật). Trước đó, biến môi trường $ GIT_COMMIT
sẽ được đặt để chứa id của cam kết được viết lại. Ngoài ra, GIT_AUTHOR_NAME,
GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL và
GIT_COMMITTER_DATE được lấy từ cam kết hiện tại và xuất sang môi trường, trong
để ảnh hưởng đến danh tính tác giả và người cam kết của cam kết thay thế được tạo bởi
git-cam-cây(1) sau khi bộ lọc đã chạy.
Nếu bất kỳ đánh giá nào về trả về trạng thái thoát khác XNUMX, toàn bộ hoạt động sẽ
bị hủy bỏ.
A bản đồ có sẵn hàm nhận đối số "id sha1 gốc" và xuất ra
"id sha1 được viết lại" nếu cam kết đã được viết lại và "id sha1 ban đầu"
nếu không thì; NS bản đồ hàm có thể trả về một số id trên các dòng riêng biệt nếu bộ lọc cam kết của bạn
phát ra nhiều cam kết.
LỰA CHỌN
--env-filter
Bộ lọc này có thể được sử dụng nếu bạn chỉ cần sửa đổi môi trường trong đó cam kết
sẽ được thực hiện. Cụ thể, bạn có thể muốn viết lại tác giả / người cam kết
biến môi trường tên / email / thời gian (xem git-cam-cây(1) để biết chi tiết). Đừng
quên xuất lại các biến.
- bộ lọc ba
Đây là bộ lọc để viết lại cây và nội dung của nó. Đối số được đánh giá
trong shell với thư mục làm việc được đặt thành gốc của cây đã kiểm tra. Cái mới
cây sau đó được sử dụng nguyên trạng (các tệp mới được tự động thêm vào, các tệp đã biến mất sẽ tự động bị xóa
- không phải tệp .gitignore hoặc bất kỳ quy tắc nào khác bỏ qua CÓ BẤT CỨ HIỆU ỨNG!).
--index-filter
Đây là bộ lọc để viết lại chỉ mục. Nó tương tự như bộ lọc cây nhưng không
không kiểm tra cây, điều này làm cho nó nhanh hơn nhiều. Thường được sử dụng với git rm
--cached --ignore-unatch ..., xem VÍ DỤ bên dưới. Đối với trường hợp nhiều lông, hãy xem cập nhật git-
chỉ số(1).
--parent-filter
Đây là bộ lọc để viết lại danh sách cha của cam kết. Nó sẽ nhận được cha mẹ
chuỗi trên stdin và sẽ xuất ra chuỗi mẹ mới trên stdout. Chuỗi mẹ là
theo định dạng được mô tả trong git-cam-cây(1): trống cho lần cam kết đầu tiên, "-p
cha "cho một cam kết bình thường và" -p parent1 -p parent2 -p parent3 ... "cho một hợp nhất
cam kết.
--msg-filter
Đây là bộ lọc để viết lại các thông báo cam kết. Đối số được đánh giá trong
shell với thông điệp cam kết ban đầu trên đầu vào tiêu chuẩn; đầu ra tiêu chuẩn của nó được sử dụng
như thông báo cam kết mới.
--commit-filter
Đây là bộ lọc để thực hiện cam kết. Nếu bộ lọc này được chỉ định, nó sẽ
được gọi thay vì git cây cam kết lệnh, với các đối số có dạng "
[(-P ) ...] "và thông báo nhật ký trên stdin. Id cam kết được mong đợi
trên stdout.
Là một phần mở rộng đặc biệt, bộ lọc cam kết có thể tạo ra nhiều id cam kết; trong trường hợp đó,
những đứa trẻ được viết lại của cam kết ban đầu sẽ có tất cả chúng là cha mẹ.
Bạn có thể sử dụng bản đồ chức năng tiện lợi trong bộ lọc này và tiện lợi khác
các chức năng, quá. Ví dụ, gọi bỏ qua "$ @" sẽ bỏ qua hiện tại
cam kết (nhưng không phải các thay đổi của nó! Nếu bạn muốn điều đó, hãy sử dụng git nổi loạn thay thế).
Bạn cũng có thể sử dụng git_commit_non_empty_tree "$ @" thay vì git commit-tree "$ @" nếu
bạn không muốn giữ cam kết với cha mẹ đơn thân và điều đó không làm thay đổi
cây.
--tag-name-filter
Đây là bộ lọc để viết lại tên thẻ. Khi được thông qua, nó sẽ được gọi cho mọi
thẻ ref trỏ đến một đối tượng được viết lại (hoặc đến một đối tượng thẻ trỏ đến một
đối tượng viết lại). Tên thẻ ban đầu được chuyển qua đầu vào chuẩn và thẻ mới
tên được mong đợi trên đầu ra tiêu chuẩn.
Các thẻ gốc không bị xóa, nhưng có thể được ghi đè; sử dụng "--tag-name-filter cat"
để chỉ cần cập nhật các thẻ. Trong trường hợp này, hãy hết sức cẩn thận và đảm bảo rằng bạn có
các thẻ cũ đã được sao lưu trong trường hợp quá trình chuyển đổi đã xảy ra.
Việc viết lại các đối tượng thẻ gần như phù hợp được hỗ trợ. Nếu thẻ có thông báo
được đính kèm, một đối tượng thẻ mới sẽ được tạo với cùng một thông báo, tác giả và
dấu thời gian. Nếu thẻ có chữ ký đính kèm, chữ ký đó sẽ bị tước bỏ. Nó là
theo định nghĩa không thể bảo tồn chữ ký. Lý do điều này "gần" đúng,
là vì lý tưởng nhất là nếu thẻ không thay đổi (trỏ đến cùng một đối tượng, có cùng
tên, v.v.) nó nên giữ lại bất kỳ chữ ký nào. Đó không phải là trường hợp, chữ ký sẽ
luôn luôn bị loại bỏ, người mua hãy cẩn thận. Cũng không có hỗ trợ cho việc thay đổi tác giả hoặc
dấu thời gian (hoặc thông báo thẻ cho vấn đề đó). Các thẻ trỏ đến các thẻ khác sẽ là
được viết lại để trỏ đến cam kết cơ bản.
- bộ lọc thư mục con
Chỉ xem lịch sử liên quan đến thư mục con đã cho. Kết quả sẽ chứa
thư mục đó (và chỉ thư mục đó) làm thư mục gốc của dự án. Ngụ ý phần được gọi là “Bản đồ lại
với tổ tiên ”.
--prune-rỗng
Một số loại bộ lọc sẽ tạo ra các cam kết trống, khiến cây không bị ảnh hưởng. Cái này
switch cho phép git-filter-branch bỏ qua các cam kết như vậy. Tuy nhiên, công tắc này chỉ
áp dụng cho các cam kết có một và chỉ một phụ huynh, do đó nó sẽ tiếp tục hợp nhất
điểm. Ngoài ra, tùy chọn này không tương thích với việc sử dụng --commit-bộ lọc. Tuy nhiên
bạn chỉ cần sử dụng chức năng git_commit_non_empty_tree "$ @" thay vì git
Thành ngữ commit-tree "$ @" trong bộ lọc cam kết của bạn để biến điều đó thành hiện thực.
--nguyên bản
Sử dụng tùy chọn này để đặt không gian tên nơi các cam kết ban đầu sẽ được lưu trữ. Các
giá trị mặc định là refs / bản gốc.
-NS
Sử dụng tùy chọn này để đặt đường dẫn đến thư mục tạm thời được sử dụng để viết lại. Khi nào
áp dụng bộ lọc cây, lệnh cần tạm thời kiểm tra cây đối với một số
thư mục, có thể tiêu tốn không gian đáng kể trong trường hợp các dự án lớn. Theo mặc định
nó làm điều này trong .git-rewrite / nhưng bạn có thể ghi đè lựa chọn đó bằng cách này
tham số.
-f, - lực lượng
git chi nhánh lọc từ chối bắt đầu với một thư mục tạm thời hiện có hoặc khi ở đó
đã được giới thiệu bắt đầu bằng refs / gốc /, trừ khi bị ép buộc.
...
Lập luận cho git danh sách sửa đổi. Tất cả các giới thiệu tích cực được bao gồm bởi các tùy chọn này đều được viết lại.
Bạn cũng có thể chỉ định các tùy chọn như --tất cả các, nhưng bạn phải sử dụng -- để tách chúng ra khỏi
các git chi nhánh lọc tùy chọn. Ngụ ý phần được gọi là "Bản đồ lại với tổ tiên".
Bản đồ lại đến tổ tiên
Bằng cách sử dụng danh sách sửa đổi(1) các đối số, ví dụ, giới hạn đường dẫn, bạn có thể giới hạn tập hợp các bản sửa đổi
được viết lại. Tuy nhiên, các tham chiếu tích cực trên dòng lệnh được phân biệt: chúng tôi
đừng để chúng bị loại trừ bởi những giới hạn như vậy. Vì mục đích này, thay vào đó, chúng được viết lại
để chỉ vào tổ tiên gần nhất mà không bị loại trừ.
VÍ DỤ
Giả sử bạn muốn xóa một tệp (chứa thông tin bí mật hoặc bản quyền
vi phạm) từ tất cả các cam kết:
git filter-branch --tree-filter 'rm filename' HEAD
Tuy nhiên, nếu tệp không có trong cây của một số cam kết, tên tệp rm đơn giản sẽ
fail cho cây đó và cam kết. Vì vậy, thay vào đó, bạn có thể muốn sử dụng tên tệp rm -f làm
kịch bản.
Sử dụng --index-filter với git rm mang lại một phiên bản nhanh hơn đáng kể. Thích với việc sử dụng rm
tên tệp, git rm - tên tệp được đệm ẩn sẽ không thành công nếu tệp không có trong cây
làm. Nếu bạn muốn "hoàn toàn quên" một tệp, nó không thành vấn đề khi nó được nhập
lịch sử, vì vậy chúng tôi cũng thêm --ignore-unatch:
git filter-branch --index-filter 'git rm --cached --ignore-unatch filename' HEAD
Bây giờ, bạn sẽ nhận được lịch sử viết lại được lưu trong HEAD.
Để viết lại kho lưu trữ để trông như thể foodir / đã là gốc dự án của nó và loại bỏ tất cả
lịch sử khác:
git filter-branch - subdirectory-filter foodir - - tất cả
Vì vậy, bạn có thể, ví dụ, biến một thư mục con của thư viện thành một kho lưu trữ của riêng nó. Lưu ý -
ngăn cách chi nhánh lọc các tùy chọn từ các tùy chọn sửa đổi và - tất cả để viết lại tất cả
các nhánh và thẻ.
Đặt một cam kết (thường nằm ở phần đầu của lịch sử khác) trở thành cấp độ gốc của
cam kết ban đầu hiện tại, để dán lịch sử khác vào sau lịch sử hiện tại:
git filter-branch --parent-filter 'sed "s / ^ \ $ / - p /"' CÁI ĐẦU
(nếu chuỗi cha trống - điều này xảy ra khi chúng ta xử lý cam kết ban đầu
- thêm graftcommit làm cha mẹ). Lưu ý rằng điều này giả định lịch sử với một gốc duy nhất (rằng
là, không có sự hợp nhất nào mà không có tổ tiên chung xảy ra). Nếu đây không phải là trường hợp, hãy sử dụng:
git filter-branch --parent-filter \
'test $ GIT_COMMIT = && echo "-p "|| cat 'HEAD
hoặc thậm chí đơn giản hơn:
echo "$ commit-id $ graft-id" >> .git / info / grafts
git filter-branch $ graft-id..HEAD
Để xóa các cam kết do "Darl McBribe" tạo ra khỏi lịch sử:
git filter-branch --commit-filter '
if ["$ GIT_AUTHOR_NAME" = "Darl McBribe"];
sau đó
bỏ qua_commit "$ @";
khác
git commit-tree "$ @";
fi 'HEAD
Các chức năng bỏ qua được định nghĩa như sau:
bỏ qua_commit ()
{
sự thay đổi;
while [-n "$ 1"];
do
sự thay đổi;
bản đồ "$ 1";
sự thay đổi;
xong;
}
Đầu tiên ma thuật shift sẽ loại bỏ id cây và sau đó là các tham số -p. Lưu ý rằng điều này
xử lý hợp nhất đúng cách! Trong trường hợp Darl đã cam kết hợp nhất giữa P1 và P2, nó sẽ
được truyền đúng cách và tất cả các con của hợp nhất sẽ trở thành cam kết hợp nhất với P1, P2 như
cha mẹ của họ thay vì cam kết hợp nhất.
LƯU Ý những thay đổi được giới thiệu bởi các cam kết và những thay đổi này sẽ không được hoàn nguyên sau
cam kết, sẽ vẫn ở trong nhánh được viết lại. Nếu bạn muốn ném ra ngoài thay đổi bên nhau
với các cam kết, bạn nên sử dụng chế độ tương tác của git nổi loạn.
Bạn có thể viết lại các thông báo nhật ký cam kết bằng cách sử dụng --msg-filter. Ví dụ, git svn-id
chuỗi trong kho lưu trữ được tạo bởi git svn có thể được loại bỏ theo cách này:
git filter-branch --msg-filter '
sed -e "/ ^ git-svn-id: / d"
'
Nếu bạn cần thêm Theo dõi các dòng, chẳng hạn, 10 cam kết cuối cùng (không có cam kết nào trong số đó là hợp nhất),
sử dụng lệnh này:
git filter-branch --msg-filter '
con mèo &&
echo "Được hỗ trợ bởi: Bugs Bunny[email được bảo vệ]>"
'ĐẦU ~ 10..HẾT
Tùy chọn --env-filter có thể được sử dụng để sửa đổi người xác nhận và / hoặc danh tính tác giả. Vì
ví dụ, nếu bạn phát hiện ra rằng các cam kết của bạn có danh tính sai do bị định cấu hình sai
user.email, bạn có thể sửa trước khi xuất bản dự án, như sau:
git filter-branch --env-filter '
nếu kiểm tra "$ GIT_AUTHOR_EMAIL" = "root @ localhost"
sau đó
GIT_AUTHOR_EMAIL =[email được bảo vệ]
xuất GIT_AUTHOR_EMAIL
fi
nếu kiểm tra "$ GIT_COMMITTER_EMAIL" = "root @ localhost"
sau đó
GIT_COMMITTER_EMAIL =[email được bảo vệ]
xuất GIT_COMMITTER_EMAIL
fi
' -- --tất cả các
Để hạn chế chỉ viết lại một phần của lịch sử, hãy chỉ định một phạm vi sửa đổi ngoài
tên chi nhánh mới. Tên nhánh mới sẽ trỏ đến bản sửa đổi cao nhất mà git
danh sách sửa đổi trong phạm vi này sẽ in.
Hãy xem xét lịch sử này:
D - E - F - G - H
/ /
A - B ----- C
Để chỉ viết lại các commit D, E, F, G, H, nhưng để nguyên A, B và C, hãy sử dụng:
nhánh lọc git ... C..H
Để viết lại các cam kết E, F, G, H, hãy sử dụng một trong những điều sau:
git filter-branch ... C..H - not D
git filter-branch ... D..H - not C
Để di chuyển toàn bộ cây vào một thư mục con hoặc xóa nó khỏi đó:
nhánh lọc git --index-filter \
'git ls-files -s | sed "s- \ t \" * - & newsubdir / - "|
GIT_INDEX_FILE=$GIT_INDEX_FILE.mới \
git update-index --index-info &&
mv "$ GIT_INDEX_FILE.new" "$ GIT_INDEX_FILE" 'HEAD
DANH MỤC CHO TỎA SÁNG A KHO
git-filter-branch có thể được sử dụng để loại bỏ một tập hợp con của các tệp, thường là với một số
sự kết hợp của --index-filter và - subdirectory-filter. Mọi người mong đợi kết quả
kho lưu trữ nhỏ hơn ban đầu, nhưng bạn cần thêm một vài bước để thực sự
nó nhỏ hơn, vì Git rất cố gắng để không làm mất các đối tượng của bạn cho đến khi bạn yêu cầu nó. Ngày thứ nhất
đảm bảo rằng:
· Bạn thực sự đã loại bỏ tất cả các biến thể của tên tệp, nếu một đốm màu đã bị di chuyển trong suốt thời gian tồn tại của nó.
git log --name-only --follow --all - filename có thể giúp bạn tìm đổi tên.
· Bạn đã thực sự lọc tất cả các refs: sử dụng --tag-name-filter cat - --all khi gọi
git-filter-nhánh.
Sau đó, có hai cách để có được một kho lưu trữ nhỏ hơn. Một cách an toàn hơn là sao chép, điều đó giữ
ban đầu của bạn còn nguyên vẹn.
· Sao chép nó bằng tệp git clone: /// path / to / repo. Bản sao sẽ không bị loại bỏ
các đối tượng. Nhìn thấy bản sao git(1). (Lưu ý rằng sao chép với một đường dẫn đơn giản chỉ là các liên kết cứng
mọi điều!)
Nếu bạn thực sự không muốn sao chép nó, vì bất kỳ lý do gì, hãy kiểm tra những điểm sau
thay vào đó (theo thứ tự này). Đây là một cách tiếp cận rất phá hoại, vì vậy làm cho a sao lưu hoặc quay trở lại
để nhân bản nó. Bạn đã được cảnh báo.
· Xóa các tham chiếu ban đầu được sao lưu bởi git-filter-branch: say git for-each-ref
--format = "% (refname)" refs / original / | xargs -n 1 git update-ref -d.
· Hết hạn tất cả các nhật ký với git reflog expire --expire = now --all.
· Garbage thu thập tất cả các đối tượng không được tham chiếu với git gc --prune = now (hoặc nếu git-gc của bạn là
không đủ mới để hỗ trợ các đối số đối với --prune, hãy sử dụng git repack -ad; git mận
thay thế).
GHI CHÚ
git-filter-branch cho phép bạn viết lại lịch sử Git phức tạp theo kịch bản shell,
nhưng bạn có thể không cần sự linh hoạt này nếu bạn chỉ đơn giản là loại bỏ không mong muốn dữ liệu Lượt thích
tệp hoặc mật khẩu lớn. Đối với những hoạt động đó, bạn có thể muốn xem xét BFG
Repo-Cleaner[1], một giải pháp thay thế dựa trên JVM cho git-filter-branch, thường ít nhất 10-50x
nhanh hơn cho các trường hợp sử dụng đó và với các đặc điểm khá khác nhau:
· Bất kỳ phiên bản cụ thể nào của tệp đều được làm sạch chính xác hàng loạt. BFG, không giống như
git-filter-branch, không cho bạn cơ hội để xử lý một tệp theo cách khác
dựa trên vị trí hoặc thời điểm nó được cam kết trong lịch sử của bạn. Ràng buộc này cung cấp cho
lợi ích hiệu suất cốt lõi của The BFG, và rất phù hợp với nhiệm vụ làm sạch
dữ liệu - bạn không quan tâm Ở đâu dữ liệu xấu là, bạn chỉ muốn nó đi.
· Theo mặc định, BFG tận dụng tối đa các máy đa lõi, cam kết làm sạch
cây tệp song song. git-filter-branch Cleaning cam kết tuần tự (tức là trong một
cách thức đơn luồng), mặc dù nó is có thể viết các bộ lọc bao gồm
song song, trong các tập lệnh được thực thi đối với mỗi cam kết.
· Các lệnh lựa chọn[2] hạn chế hơn nhiều so với nhánh git-filter và chuyên dụng
chỉ để thực hiện các nhiệm vụ xóa dữ liệu không mong muốn- ví dụ: --strip-blobs-lớn hơn 1 triệu.
GIT
Một phần của git(1) bộ
GHI CHÚ
1. BFG Repo-Cleaner
http://rtyley.github.io/bfg-repo-cleaner/
2. tùy chọn lệnh
http://rtyley.github.io/bfg-repo-cleaner/#ví dụ
Sử dụng git-filter-branch trực tuyến bằng các dịch vụ onworks.net