Migrando repositorio Git

bernardo

Luiz Bernardo

Posted on March 22, 2023

Migrando repositorio Git

Com as constantes aquisições de empresas no mercado de TI é bem comum ter que migrar o repositório de código que estava em um repositório remoto para outro, às vezes em produtos diferentes.

Pensando no cenário de migração de repositório remoto de soluções diferentes, do GitHub para o Azure Devops, por exemplo, a migração pode se tornar um pouco mais complexa. Veja, você precisa migrar o histórico do projeto por completo com branchs, tags e notes.

Primeiro, crie o repositório de destino para nossa migração, vamos utilizar ele no script.

Para isso criei um pequeno script bash na qual vou explicar aqui linha a linha antes de mostrar por completo, vejamos:

set -eufo pipefail
Enter fullscreen mode Exit fullscreen mode

O comando "set -eufo pipefail" é um conjunto de opções que pode ser usado em scripts de shell, como o Bash, para modificar o comportamento padrão do ambiente do shell.

Uma explicação mais detalhada de cada uma das opções incluídas no comando:

  • "set -e": Encerra o script imediatamente caso um comando falhe ou retorne um status diferente de zero. Isso ajuda a evitar que erros passem despercebidos e ajuda a garantir que o script pare em caso de falha.
  • "set -u": Faz com que o shell gere um erro caso uma variável não definida seja referenciada. Isso pode ajudar a evitar erros que possam ocorrer quando uma variável é usada sem ter sido previamente inicializada.
  • "set -f": Desativa a expansão de nomes de arquivos com caracteres curinga (como * e ?), o que pode ser útil em scripts que lidam com arquivos com nomes não convencionais ou que podem conter espaços ou outros caracteres especiais.
  • "set -o pipefail": Faz com que um pipeline (comando composto por vários comandos conectados com o operador |) retorne o status de saída do último comando que falhou, em vez de retornar o status de saída do último comando executado com sucesso. Isso pode ser útil em pipelines complexos, onde é importante detectar falhas em qualquer ponto do pipeline.

O comando "set -eufo pipefail" ajuda a garantir que o script seja executado de forma confiável e consistente, evitando erros comuns que podem levar a falhas ou a comportamentos inesperados. Ele é especialmente útil em scripts que executam tarefas críticas ou lidam com dados sensíveis, onde a confiabilidade é essencial.

SOURCE_URL=https://repositorio_git_origem.git
TARGET_URL=https://repositorio_git_alvo.git
Enter fullscreen mode Exit fullscreen mode

SOURCE_URL será a URL Git do repositório que queremos copiar
TARGET_URL será a URL Git do repositório alvo que queremos que fique igual ao repositório da SOURCE_URL

WORKDIR=./repos
Enter fullscreen mode Exit fullscreen mode

Apenas para organização criei um diretório de trabalho local.

echo "Cloning from ${SOURCE_URL} into ${WORKDIR}..."
git init --bare "${WORKDIR}"
cd "${WORKDIR}"
Enter fullscreen mode Exit fullscreen mode

O –bare cria um repositório vazio. Se GIT_DIRo ambiente não estiver definido, ele será definido no diretório de trabalho atual. Ao incializar um repositório como bare não será permitido editar arquivos (git add) e commitar mudanças (git commit), já que o mesmo não possui uma working tree.

Utilizo o –bare para garantir que não tenha nenhuma mudança no meio do processo de migração.

git config remote.origin.url "${SOURCE_URL}"
Enter fullscreen mode Exit fullscreen mode

Esse comando é utilizado para definir a URL de um repositório Git remoto

git config --add remote.origin.fetch '+refs/heads/*:refs/heads/*'
Enter fullscreen mode Exit fullscreen mode

O comando git config --add remote.origin.fetch adicionam uma nova configuração no git para o repositório atual.

O parâmetro --add diz ao git para adicionar essa configuração em vez de substituir configurações existentes.

remote.origin.fetch define o nome da configuração que está sendo adicionada. Essa configuração especifica como o Git deve buscar as alterações dos ramos do repositório remoto (chamado de "origin").

O valor '+refs/heads/:refs/heads/' é uma expressão que especifica que o git deve buscar todas as branches (ramificações) do repositório remoto. O primeiro * representa todas as branches no repositório remoto, e o segundo * representa todas as branches locais no repositório local. O sinal de + antes de refs/heads/* indica que, além de buscar os branches existentes, também deve-se adicionar novos branches que possam ser criados no repositório remoto.

Essa configuração diz ao git para buscar todas as branches do repositório remoto chamado "origin" e adicioná-las ao repositório local.

git config --add remote.origin.fetch '+refs/tags/*:refs/tags/*'
Enter fullscreen mode Exit fullscreen mode

O sinal de + antes de refs/tags/* indica que, além de buscar as tags existentes, também deve-se adicionar novas tags que possam ser criadas no repositório remoto.

Essa configuração diz ao git para buscar todas as tags do repositório remoto chamado "origin" e adicioná-las ao repositório local.

git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*'
Enter fullscreen mode Exit fullscreen mode

O sinal de + antes de refs/notes/* indica que, além de buscar as notas existentes, também deve-se adicionar novas notas que possam ser criadas no repositório remoto.

Essa configuração diz ao git para buscar todas as notas do repositório remoto chamado "origin" e adicioná-las ao repositório local.

git config remote.origin.mirror true
Enter fullscreen mode Exit fullscreen mode

A opção mirror é usada para especificar se o repositório local deve espelhar todos os dados do repositório remoto. Quando essa opção é definida como true, isso indica que todas as alterações feitas no repositório remoto devem ser automaticamente sincronizadas com o repositório local.

Quando essa opção está ativada, todas as operações de push, fetch e pull serão direcionadas ao repositório remoto origin, e o repositório local será atualizado automaticamente para refletir todas as alterações no repositório remoto, ou seja, define que o repositório remoto origin deve ser espelhado no repositório local e que todas as alterações no repositório remoto devem ser automaticamente sincronizadas com o repositório local.

git fetch --all
Enter fullscreen mode Exit fullscreen mode

Este comando é usado para atualizar todas as referências de um repositório local com as alterações mais recentes do repositório remoto.

O parâmetro --all indica que o comando deve buscar atualizações para todas as branches (ramificações), tags e notas no repositório remoto.

Quando executado, o comando git fetch --all irá buscar todas as alterações no repositório remoto, mas não as mesclar automaticamente com a branch atual. Em vez disso, ele atualizará as referências locais para refletir as alterações mais recentes no repositório remoto.

Isso é útil quando você deseja verificar o estado atual do repositório remoto sem mesclar as alterações com seu repositório local.

echo ""
echo "Cloned to ${WORKDIR}; pushing to ${TARGET_URL}"
Enter fullscreen mode Exit fullscreen mode

Apenas um print para deixar tudo mais visual

git push --mirror "${TARGET_URL}"
Enter fullscreen mode Exit fullscreen mode

Ao executar o comando git push --mirror "${TARGET_URL}", o Git irá enviar todas as alterações do repositório local para o repositório remoto especificado, sobrescrevendo quaisquer alterações existentes e excluindo referências que não existem mais no repositório local.

echo ""
echo "Cleaning up temporary directory ${WORKDIR}..."
Enter fullscreen mode Exit fullscreen mode

Mais anotações para deixar visível a conclusão da execução.

rm -rf "${WORKDIR}"
Enter fullscreen mode Exit fullscreen mode

Remoção do diretorio de trabalho.

Com isso passamos por todos os comandos do script e seu repositório foi migrado na íntegra =D

Abaixo o script completo.

echo "Done."

bla bla bla
#!/bin/sh

set -eufo pipefail

SOURCE_URL=https://repositorio_git_origem.git
TARGET_URL=https://repositorio_git_alvo.git
WORKDIR=./repos

echo "Cloning from ${SOURCE_URL} into ${WORKDIR}..."

git init --bare "${WORKDIR}"
cd "${WORKDIR}"

git config remote.origin.url "${SOURCE_URL}"
git config --add remote.origin.fetch '+refs/heads/*:refs/heads/*'
git config --add remote.origin.fetch '+refs/tags/*:refs/tags/*'
git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*'
git config remote.origin.mirror true
git fetch --all

echo ""
echo "Cloned to ${WORKDIR}; pushing to ${TARGET_URL}"

git push --mirror "${TARGET_URL}"

echo ""
echo "Cleaning up temporary directory ${WORKDIR}..."

rm -rf "${WORKDIR}"

echo "Done."
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
bernardo
Luiz Bernardo

Posted on March 22, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Migrando repositorio Git
git Migrando repositorio Git

March 22, 2023