간단한 해결책 : 병합 후 '작업'분기 제거
짧은 대답 : 병합을 포함하여 원하는대로 git을 사용할 수 있습니다 (간단한 워크 플로우는 아래 참조). 임시 작업 분기를 삭제 하려면 각 ' git merge work '와 ' git branch -d work '를 따르십시오 .
배경 설명 :
병합 / dcommit 문제는 분기를 'git svn dcommit'할 때마다 해당 분기의 병합 기록이 '평평하게'됩니다 .git은 분기에 들어간 모든 병합 작업을 잊어 버립니다. 파일 내용 만 보존됩니다. 그러나이 내용이 (부분적으로) 특정 다른 지점에서 나온 사실은 손실됩니다. 참조 : 왜 git svn dcommit이 로컬 브랜치에 대한 병합 커밋 기록을 잃습니까?
(참고 : git-svn이 할 수있는 일은 많지 않습니다 : svn은 훨씬 더 강력한 git merge를 이해하지 못합니다. 따라서 svn 저장소 내 에서이 병합 정보는 어떤 식으로도 나타낼 수 없습니다.)
그러나 이것은 전체입니다 문제입니다. '작업'브랜치를 '마스터 브랜치'에 병합 한 후 '작업'브랜치를 삭제하면 git 저장소가 100 % 깨끗하며 svn 저장소와 똑같이 보입니다.
내 워크 플로우 :
물론 원격 svn 저장소를 로컬 자식 저장소에 복제했습니다 (시간이 걸릴 수 있음).
$> git svn clone <svn-repository-url> <local-directory>
그런 다음 모든 작업은 "local-directory"내부에서 발생합니다. 서버에서 'svn update'와 같은 업데이트를 받아야 할 때마다 다음을 수행합니다.
$> git checkout master
$> git svn rebase
나는 모든 개발 작업을 다음과 같이 생성되는 별도의 분기 '작업'에서 수행합니다.
$> git checkout -b work
물론 원하는만큼 작업에 대해 많은 브랜치를 생성하고 원하는대로 병합 및 리베이스 할 수 있습니다 (아래에서 논의한 것처럼 작업을 마치면 삭제). 정상적인 작업에서 나는 매우 자주 커밋합니다.
$> git commit -am '-- finished a little piece of work'
다음 단계 (git rebase -i)는 선택 사항입니다 --- svn에 보관하기 전에 역사를 정리하고 있습니다. 커밋 메시지를 분기하고 정리하십시오 (다른 개발자는 내가 겪은 작은 단계와 실수를 모두 볼 필요가 없습니다-결과 만). 이를 위해 나는
$> git log
svn 저장소에있는 마지막 커밋의 sha-1 해시를 복사하십시오 (git-svn-id로 표시). 그런 다음 전화
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
내 대신 마지막 svn 커밋의 sha-1 해시를 붙여 넣으십시오. 자세한 내용은 'git help rebase'와 함께 설명서를 읽으십시오. 한마디로 :이 명령은 먼저 커밋을 표시하는 편집기를 엽니 다 ---- 이전 커밋으로 스쿼시하려는 모든 커밋에 대해 'pick'을 'squash'로 변경하십시오. 물론 첫 번째 줄은 '픽'으로 유지해야합니다. 이런 식으로 많은 작은 커밋을 하나 이상의 의미있는 단위로 압축 할 수 있습니다. 편집기를 저장하고 종료하십시오. 커밋 로그 메시지를 다시 작성하도록 요청하는 다른 편집기가 표시됩니다.
간단히 말해서 : '코드 해킹'을 마친 후 다른 프로그래머에게 제시하고 싶을 때까지 (또는 역사를 탐색 할 때 몇 주 안에 작업을보고 싶을 때까지) '작업'분기를 마사지합니다. .
svn 저장소에 변경 사항을 푸시하기 위해 다음을 수행합니다.
$> git checkout master
$> git svn rebase
이제 우리는 svn 저장소에서 그 동안 발생한 모든 변경 사항으로 업데이트 된 이전 '마스터'분기로 돌아 왔습니다 (새로운 변경 사항은 '작업'분기에 숨겨져 있습니다).
새로운 '작업'변경 사항과 충돌 할 수있는 변경 사항이있는 경우 새 작업을 푸시하기 전에 로컬로 변경해야합니다 (자세한 내용은 아래 참조). 그런 다음 변경 사항을 svn으로 푸시 할 수 있습니다.
$> git checkout master
$> git merge work # (1) merge your 'work' into 'master'
$> git branch -d work # (2) remove the work branch immediately after merging
$> git svn dcommit # (3) push your changes to the svn repository
참고 1 : 'git branch -d work'명령은 매우 안전합니다. 더 이상 필요하지 않은 브랜치를 삭제할 수 있습니다 (이미 현재 브랜치에 병합되어 있기 때문에). 'master'분기와 작업을 병합하기 전에 실수로이 명령을 실행하면 오류 메시지가 표시됩니다.
참고 2 : 병합과 dcommit 사이에 'git branch -d work' 를 사용하여 분기를 삭제하십시오. dcommit 후 분기를 삭제하려고하면 오류 메시지가 표시됩니다. 'git svn dcommit'을 수행하면 git은 지점이 '마스터'와 병합되었습니다. 안전 검사를 수행하지 않는 'git branch -D work'로 제거해야합니다.
이제 '마스터'브랜치를 실수로 해킹하는 것을 피하기 위해 새로운 '워크'브랜치를 즉시 만듭니다.
$> git checkout -b work
$> git branch # show my branches:
master
* work
SVN의 변경으로 '작업'을 통합 :
다음은 내 '일'지점에 근무하는 동안 그 다른 사람이 SVN 저장소를 변경할 때 '자식 svn의 REBASE'알 내가 할 것입니다 :
$> git checkout master
$> git svn rebase # 'svn pull' changes
$> git checkout work # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed
$> git checkout master # try again to push my changes
$> git svn rebase # hopefully no further changes to merge
$> git merge integration # (1) merge your work with theirs
$> git branch -d work # (2) remove branches that are merged
$> git branch -d integration # (2) remove branches that are merged
$> git svn dcommit # (3) push your changes to the svn repository
더 강력한 솔루션이 존재합니다 :
제시된 워크 플로우는 단순합니다. 'update / hack / dcommit'의 각 라운드 내에서만 git의 기능을 사용하지만 장기 프로젝트 히스토리는 svn 저장소와 마찬가지로 선형입니다. 레거시 svn 프로젝트에서 작은 첫 단계로 git merge 사용을 시작하려는 경우에도 괜찮습니다.
git merging에 익숙해지면 다른 워크 플로우를 자유롭게 탐색하십시오.하고있는 것을 알고 있다면 svn merge와 git merge를 혼합 할 수 있습니다 ( git-svn (또는 비슷한 것을 사용하여 svn merge)? )