이를 달성하기위한 2 단계가 있습니다.
- 새로운 빈 커밋 만들기
- 이 빈 커밋에서 시작하도록 기록을 다시 작성하십시오.
새로운 빈 커밋을 임시 브랜치에 넣습니다. newroot
편의를 위해 .
1. 새로운 빈 커밋 생성
이를 수행 할 수있는 여러 가지 방법이 있습니다.
배관 만 사용
가장 깨끗한 방법은 Git의 배관을 사용하여 커밋을 직접 생성하여 작업 복사본이나 인덱스를 건드리지 않거나 지점을 체크 아웃하지 않는 것입니다.
빈 디렉토리에 대한 트리 객체를 만듭니다.
tree=`git hash-object -wt tree --stdin < /dev/null`
커밋을 감싸십시오.
commit=`git commit-tree -m 'root commit' $tree`
그것에 대한 참조를 작성하십시오.
git branch newroot $commit
쉘을 충분히 알고 있다면 전체 절차를 하나의 라이너로 재 배열 할 수 있습니다.
배관없이
정기적 인 도자기 명령을 사용하면 newroot
아무 이유 없이 분기 를 체크 아웃 하고 인덱스 및 작업 복사본을 반복적으로 업데이트 하지 않고 빈 커밋을 만들 수 없습니다 . 그러나 일부 사람들은 이것을 이해하기가 더 쉽다는 것을 알게 될 것입니다.
git checkout --orphan newroot
git rm -rf .
git clean -fd
git commit --allow-empty -m 'root commit'
로 --orphan
전환 할 수없는 매우 오래된 Git 버전 checkout
에서는 첫 번째 줄을 다음과 같이 바꿔야합니다.
git symbolic-ref HEAD refs/heads/newroot
2.이 빈 커밋에서 시작하도록 히스토리를 다시 작성하십시오.
여기에는 rebasing 또는 clean history rewrite의 두 가지 옵션이 있습니다.
리베이스
git rebase --onto newroot --root master
이것은 단순성의 장점이 있습니다. 그러나 분기에서 마지막 커밋마다 커미터 이름과 날짜도 업데이트합니다.
또한 일부 사례 기록을 사용하면 아무것도 포함하지 않은 커밋에 기반하고 있음에도 불구하고 병합 충돌로 인해 실패 할 수도 있습니다.
역사 재 작성
보다 깔끔한 접근 방식은 분기를 다시 작성하는 것입니다. with와 달리 git rebase
, 분기가 시작하는 커밋을 찾아야합니다.
git replace <currentroot> --graft newroot
git filter-branch master
재 작성은 분명히 두 번째 단계에서 발생합니다. 설명이 필요한 첫 번째 단계입니다. 뭐git replace
않는 것은 당신이 교체하려는 개체에 대한 참조를 볼 때마다, 힘내 대신 그 객체의 교체 보는 것이 힘내을 알 수있다.
--graft
스위치를 사용하면 평소와 약간 다른 것을 알려줍니다. 대체 객체가 아직 없다고 말하고 있지만 교체 의 상위 커밋이 나열된 것 (즉, 커밋 )이 <currentroot>
아닌 것을 제외하고 는 커밋 객체를 정확한 사본으로 교체 newroot
하려고합니다. ). 그런 다음 git replace
이 커밋을 생성 한 다음 해당 커밋을 원래 커밋의 대체로 선언합니다.
이제를 수행 git log
하면 원하는대로 항목이 이미 표시됩니다 newroot
. 분기는에서 시작합니다 .
그러나 git replace
실제로 히스토리를 수정하지는 않으며 저장소에서 전파되지도 않습니다. 단지 한 객체에서 다른 객체로 리포지토리에 로컬 리디렉션을 추가하기 만합니다. 이것이 의미하는 바는 아무도이 교체의 효과를 볼 수 없다는 것입니다.
그것이 filter-branch
단계가 필요한 이유 입니다. 로 git replace
루트에 대한 조정 부모 커밋과 정확한 복사본을 만들 커밋 git filter-branch
그런 다음 모든 커밋에 대해서도이 프로세스를 반복합니다. 그것은 당신이 그것을 공유 할 수 있도록 실제로 역사가 다시 쓰여지는 곳입니다.