Solução simples: remova a ramificação 'trabalho' após a mesclagem
Resposta curta: Você pode usar o git da maneira que desejar (veja abaixo um fluxo de trabalho simples), incluindo mesclagem. Apenas certifique-se de seguir cada ' trabalho de mesclagem do git ' com ' git branch -d work ' para excluir o ramo de trabalho temporário.
Explicação em segundo plano:
O problema de mesclagem / dcommit é que, sempre que você 'git svn dcommit' uma ramificação, o histórico de mesclagem dessa ramificação é 'achatado': o git esquece todas as operações de mesclagem que entraram nessa ramificação: apenas o conteúdo do arquivo é preservado, mas o fato de que esse conteúdo (parcialmente) veio de um outro ramo específico está perdido. Veja: Por que o git svn dcommit perde o histórico de confirmações de mesclagem para ramificações locais?
(Nota: Não há muito o que o git-svn possa fazer a respeito: o svn simplesmente não entende as combinações muito mais poderosas do git. Portanto, dentro do repositório svn, essas informações de mesclagem não podem ser representadas de forma alguma.)
Mas este é o problema todo . Se você excluir o ramo 'work' depois que ele foi mesclado no 'master branch', seu repositório git estará 100% limpo e se parecerá exatamente com o seu repositório svn.
Meu fluxo de trabalho:
Claro, primeiro clonei o repositório svn remoto em um repositório git local (isso pode levar algum tempo):
$> git svn clone <svn-repository-url> <local-directory>
Todo o trabalho acontece dentro do "diretório local". Sempre que preciso obter atualizações do servidor (como 'svn update'), eu faço:
$> git checkout master
$> git svn rebase
Eu faço todo o meu trabalho de desenvolvimento em uma ramificação separada 'work', criada assim:
$> git checkout -b work
Obviamente, você pode criar quantas ramificações para o seu trabalho quiser e mesclar e refazer entre elas quantas quiser (basta excluí-las quando terminar com elas - como discutido abaixo). No meu trabalho normal, comprometo-me com muita frequência:
$> git commit -am '-- finished a little piece of work'
O próximo passo (git rebase -i) é opcional --- está apenas limpando a história antes de arquivá-la no svn: Quando atingi uma milha estável que quero compartilhar com outras pessoas, reescrevi a história desse 'trabalho' ramifique e limpe as mensagens de confirmação (outros desenvolvedores não precisam ver todos os pequenos passos e erros que cometi no caminho - apenas o resultado). Para isso, eu faço
$> git log
e copie o hash sha-1 do último commit que está ativo no repositório svn (como indicado por um git-svn-id). Então eu ligo
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
Basta colar o sha-1 hash do nosso último svn commit ao invés do meu. Você pode ler a documentação com 'git help rebase' para obter detalhes. Resumindo: este comando primeiro abre um editor apresentando suas confirmações ---- basta alterar 'pick' para 'squash' para todas as confirmações que você deseja esmagar com as confirmações anteriores. Obviamente, a primeira linha deve permanecer como uma 'escolha'. Dessa forma, você pode condensar seus muitos pequenos commits em uma ou mais unidades significativas. Salve e saia do editor. Você receberá outro editor solicitando que você reescreva as mensagens de log de confirmação.
Resumindo: depois de terminar o 'hacker de código', massageio minha ramificação 'trabalho' até que pareça como quero apresentá-lo aos outros programadores (ou como quero ver o trabalho em algumas semanas quando navego pelo histórico) .
Para enviar as alterações ao repositório svn, eu faço:
$> git checkout master
$> git svn rebase
Agora estamos de volta ao antigo ramo 'mestre' atualizado com todas as alterações que ocorreram nesse período no repositório svn (suas novas alterações estão ocultas no ramo 'trabalho').
Se houver alterações que possam colidir com as novas alterações de 'trabalho', você precisará resolvê-las localmente antes de poder enviar seu novo trabalho (veja detalhes mais abaixo). Em seguida, podemos enviar nossas alterações para 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
Nota 1: O comando 'git branch -d work' é bastante seguro: permite excluir apenas os ramos que você não precisa mais (porque eles já estão mesclados no seu ramo atual). Se você executar este comando por engano antes de mesclar seu trabalho com a ramificação 'master', você receberá uma mensagem de erro.
Nota 2: Certifique-se de excluir sua ramificação com 'git branch -d work' entre mesclagem e dcommit: Se você tentar excluir a ramificação após dcommit, você receberá uma mensagem de erro: Ao fazer 'git svn dcommit', o git esquece que sua filial foi mesclada com 'master'. Você deve removê-lo com 'git branch -D work', que não faz a verificação de segurança.
Agora, crio imediatamente um novo ramo 'trabalho' para evitar hackers acidentalmente no ramo 'mestre':
$> git checkout -b work
$> git branch # show my branches:
master
* work
Integrando seu 'trabalho' com alterações no svn:
Aqui está o que eu faço quando o 'git svn rebase' revela que outras pessoas mudaram o repositório svn enquanto eu trabalhava no meu ramo 'trabalho':
$> 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
Existem soluções mais poderosas:
O fluxo de trabalho apresentado é simplista: ele usa os poderes do git apenas dentro de cada rodada de 'update / hack / dcommit' --- mas deixa o histórico do projeto a longo prazo tão linear quanto o repositório svn. Tudo bem se você deseja apenas começar a usar o git mesclado em pequenos primeiros passos em um projeto svn legado.
Quando você se familiarizar com a fusão do git, sinta-se à vontade para explorar outros fluxos de trabalho: se você sabe o que está fazendo, pode misturar o git merges com o svn merges ( Usando o git-svn (ou similar) apenas para ajudar no svn merge? )