Git 버전 제어 파일에서 몇 줄을 삭제할 때 해당 줄을 삭제하는 새 커밋을 만드는 대신 원래 도입한 커밋에서 해당 줄을 제거하는 git 명령이 있습니까? 예를 들어, 다음 파일이 제공됩니다.
$ echo "Line 1" >> foo
$ echo "Line 2" >> foo
$ git commit -a -m "Add 1, 2"
[master 1005cbb] Add 1, 2
1 file changed, 2 insertions(+)
$ echo "Line 3" >> foo
$ git commit -a -m "Add 3"
[master 5036981] Add 3
1 file changed, 1 insertion(+)
$ echo "Line 4" >> foo
$ echo "Line 5" >> foo
$ git commit -a -m "Add 5, 6"
[master 41ca6ab] Add 5, 6
1 file changed, 2 insertions(+)
$ git blame -s foo
1005cbbb 1) Line 1
1005cbbb 2) Line 2
50369811 3) Line 3
41ca6ab6 4) Line 4
41ca6ab6 5) Line 5
2-4행을 삭제한다고 가정해 보겠습니다.
$ sed -i '/Line [234]/d' foo
$ git diff
diff --git a/foo b/foo
index 572d5d9..e486b1b 100644
--- a/foo
+++ b/foo
@@ -1,5 +1,2 @@
Line 1
-Line 2
-Line 3
-Line 4
Line 5
1005cbb
이제 변경 사항을 커밋하는 대신 기록에서 이러한 줄을 완전히 제거하는 작업을 실행하여 (또는 새 해시가 무엇이든) "line 1"만 추가하고 5036981
비어 있거나 사라지는 새 트리를 만들고 싶습니다 . 41ca6ab
"라인 5"가 추가됩니다 .
가능합니까? 내가 생각할 수 있는 가장 가까운 것은 rebase하기 전에 각 행을 개별적으로 삭제하는 것이지만 git commit --fixup hash-of-the-commit-that-added-that-line
, 이런 방식으로 자동화하기 전에 더 나은 기본 제공 방법이 있는지 궁금합니다.
답변1
이게 뭐야?git filter-branch
이는 기록의 모든 개정판에 대해 명령을 실행하고 변경 사항에 관계없이 결과를 다시 제출합니다. 첫 번째 수정 버전 이후 모든 커밋의 모든 해시가 변경되어 새 분기가 모든 복제본과 호환되지 않게 됩니다.
sed -i '/Line [234]/d' foo
원하는 수정을 수행하는 명령인 경우 이를 트리 필터로 적용할 수 있습니다 .
git filter-branch --tree-filter "sed -i '/Line [234]/d' foo" HEAD
일반적으로 복잡한 내용을 자신의 스크립트에 넣는 것이 더 쉽습니다. 필터 명령은 다른 디렉터리에서 실행되므로 전체 경로를 제공하십시오.
많은 필터링 모드가 있습니다. 트리 필터는 파일 자체를 수정하며 다른 필터와 결합하여 커밋 메시지나 세부 정보, 상위, 태그 등을 변경할 수 있습니다. 트리 필터는 마치 새 저장소에서 실행하는 것처럼 동작합니다 git add -f *
. 기존의 모든 파일에는 현재 콘텐츠가 추가되어 있습니다.로컬 또는 전역 무시 무시, 더 이상 존재하지 않는 모든 파일은 삭제됩니다.