저는 최신 개정판에 약 3500 개의 커밋과 30,000 개의 별개의 파일이있는 자식 저장소가 있습니다. 여러 사람으로부터 약 3 년 동안의 작업을 대표하며 우리는 오픈 소스로 만들 수있는 권한을 받았습니다. 나는 최신 버전 대신에 전체 역사를 발표하기 위해 열심히 노력하고있다. 이렇게하려면 "시간에 맞추기"에 관심이 있으며 파일을 만들 때 파일 맨 위에 라이센스 헤더를 삽입하는 것이 좋습니다. 실제로이 작업이 있지만 3 일 정도의 RAM 디스크에서 완전히 실행되며 수동 작업이 약간 필요합니다. 나는 그것이 훨씬 더 빨라질 수 있다는 것을 안다. 그러나 나의 git-fu는 그 일에 아주 달려 있지 않다.효율적으로 많은 역사를 재 작성 (rebase -i)
질문 : 동일한 작업을 훨씬 빨리 수행하려면 어떻게해야합니까? 나는 현재 (스크립트에서 자동화 된, 그러나 저 참아주세요 ...) 무엇을
:
확인 새 파일이 저장소에 추가 된 커밋의 모든 (단지 수줍음이 있습니다 이들 중 500 FWIW)의 :
git whatchanged --diff-filter=A --format=oneline
파일의 첫 번째 줄에
edit
단 하나의 시간pick
를 대체 내 자신의 스크립트로 환경 변수 GIT_EDITOR 정의 (당신이) 왜 곧 볼 수 있습니다.git rebase -i decafbad001badc0da0000~1
다음 해당 파일을 추가 투입 직전부터 대화식 REBASE 호출 상기 git whatchanged
의 출력으로부터 각 커밋 들어
perl -pi -e 's/pick/edit/ if $. == 1' $1
: 이는 동작의 핵심 내 커스텀 GIT_EDITOR (그 perl one-liner)는 pick
에서 edit
으로 바뀌며 우리는 새로운 파일을 변경하기 위해 쉘로 버려진 다. 또 다른 간단한 header-inserter
스크립트는 내가 삽입하려고하는 헤더의 알려진 고유 한 패턴을 찾습니다 (알려진 파일 유형 (*. [chS] 만 가능)). 없으면 삽입하고 git add
이 파일입니다. 이 순진 기술은 현재 커밋 중에 어떤 파일이 실제로 추가되었는지에 대한 지식이 없지만, 옳은 일을하고 멱등하고 (동일한 파일에 대해 여러 번 실행하는 것이 안전합니다.),이 전체 프로세스가 병목 현상이 발생한 부분이 아닙니다 . 이 시점에서
git commit --amend
git rebase --continue
rebase --continue
이 비싼 부분입니다. whatchanged
의 출력에서 모든 수정본에 대해 git rebase -i
을 한 번 호출하므로 리베이스가 많이 필요합니다. 이 스크립트가 실행되는 거의 모든 시간 동안 "Rebasing (2345/2733)"카운터 증가분을 보게됩니다.
또한 느린 것이 아닙니다. 해결해야 할 주기적으로 충돌이 있습니다. 이러한 경우는 최소한 다음과 같은 경우에 발생할 수 있습니다. (1) '새로운'파일이 실제로는 기존 파일의 사본 인 경우 (예 : #include
). 이것은 진정한 충돌이지만 대부분의 경우 자동으로 해결 될 수 있습니다 (예, 해당 스크립트를 처리하십시오). (2) 파일이 삭제 될 때. 이것은 우리가 git rm
으로 삭제하기를 원한다는 것을 확인함으로써 쉽게 해결할 수 있습니다. (3) diff
과 같이 보이는 부분이있을뿐입니다. 예를 들어 변경 사항이 빈 줄만 추가하는 경우입니다.다른보다 합법적 인 충돌은 수동 개입이 필요하지만 전체적으로 가장 큰 병목 현상은 아닙니다. 가장 큰 병목은 "Rebasing (xxxx/yyyy)"를 쳐다 보는 것입니다.
지금은 최신 커밋에서 이전 커밋, 즉 git whatchanged
의 출력 맨 위에서 시작하여 개별 리베이스가 시작됩니다. 즉, 첫 번째 rebase가 어제의 커밋에 영향을 미침으로써 결국 3 년 전부터 커밋을 리베이스하게됩니다. "최신"에서 "이전"으로가는 것은 반 직관적 인 것처럼 보이지만, 지금까지는 rebase를 호출 할 때 을 edit
으로 변경하지 않으면 문제가 있다는 것을 확신하지 못했습니다. 나는 갈등이 일어나기 때문에 두려워하며, 한 번에 모든 것을 rebase하려고 노력하는 것에서 충돌 파문의 해일을 다루기를 원하지 않는다. 누군가 그것을 피할 방법을 알고 있을까요? 나는 하나를 생각해 낼 수 없었다.
나는 자식 객체의 내부 동작을 살펴보기 시작했습니다 1! 객체 그래프를 걷고 내가 원하는 변경을하는 훨씬 더 효율적인 방법이있는 것처럼 보입니다.
이 저장소는 태그 또는 분기를 사용하지 않은 SVN 저장소에서 왔습니다 (나는 이미 git filter-branch
를 편집했기 때문에). 우리는 직선 역사의 편리함을 가지고 있습니다. git branch 나 merges는 없다.
중요한 정보는 빠뜨린 것이 확실하지만이 게시물은 이미 지나치게 길어 보입니다. 요청에 따라 더 많은 정보를 제공하기 위해 최선을 다할 것입니다. 결국에는 다양한 스크립트를 게시해야 할 수도 있습니다. 이는 가능성입니다. git 저장소에서 히스토리를 어떻게 재 작성하는지 알아내는 것이 나의 목표이다. 다른 실행 가능한 라이센스 및 코드 릴리스 방법을 논하는 것이 아닙니다.
감사합니다.
업데이트 2012-06-17 : Blog post 모든 세부 사항이 있습니다.
, 나는 거대한 역사의 재 작성을 할 필요가 없다,하지만 난 결코 올바른 도구는 ['git filter-branch'] (http://www.kernel.org/pub/software/scm/git/docs/v1.7.3/git-filter-branch.html)입니다. . 미안하지만 더 도움이되지 않을 것 같습니다. – KurzedMetal
@KurzedMetal :이 릴리스와 관련이없는 (파일 시스템) 경로를 제거하기 위해이 모든 리베이스를 시작하기 전에'filter-branch'를 사용했습니다. (이 git 저장소가 생성 된 SVN 저장소는 더 크고 다루기 힘들다.) 그러나,이 모든 리베이스 작업을 수행하는 것보다'filter-branch '스크립트 변경 사항이 더 효율적일 수 있다는 지적이있을 수 있습니다. 나는 조사 할 것이다. – jonny0x5
'여러 사람으로부터 약 3 년 동안의 작업을 대표하며 공개 소스로 만들 수있는 권한을 받았습니다. 주제는 알고 있지만 궁금합니다. P, 프로젝트 이름/홈페이지는 무엇입니까? – KurzedMetal