Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Serviços de DevOps do Azure | Azure DevOps Server | Azure DevOps Server 2022
Git é um repositório popular de código-fonte distribuído (repositório) que permite aos utilizadores trabalhar com o repositório completo enquanto estão num estado desconectado. Os benefícios do Git estão bem documentados, mas o que acontece se precisares de "reverter o tempo" no repositório principal? Fazer isso não é intuitivo e requer permissões elevadas. Este requisito é esperado para algo que afeta todos os utilizadores do repositório.
Como pode reverter o repositório central para um estado anterior de modo seguro?
Cenário problemático
Imagine que realiza o commit de um ficheiro grande, como um vídeo, no seu servidor Git. Em um sistema de código-fonte tradicional, é conveniente armazenar tudo em um só lugar e, em seguida, puxar para baixo o que você precisa. Com o Git, todo o repositório é clonado para o computador local de cada utilizador. Com um ficheiro grande, todos os utilizadores do projeto têm também de descarregar os ficheiros grandes.
À medida que cada ficheiro grande é enviado para o servidor, o problema só aumenta. O repositório torna-se demasiado grande para ser eficiente para os seus utilizadores. Mesmo que removas o ficheiro grande do teu repositório local e voltes a enviar, o ficheiro ainda existe no histórico do repositório. Como resultado, o ficheiro continua a ser descarregado no computador local de todos como parte do histórico de downloads.
Adicione um ficheiro grande ao repositório local.
Depois de realizar um commit a partir do repositório local, o servidor também possui o ficheiro grande.
Congelar o repositório
Para resolver o problema de um repositório grande, tens de começar pela origem. Neste cenário, a fonte é o repositório do servidor. Pede à equipa para parar de enviar para o repositório. Se ocorrerem mais envios durante este processo, deve tê-los em consideração para não perder os dados.
Importante
Os passos seguintes removem o vídeo do histórico de ramos, mas o ficheiro permanece no histórico dos repositórios quando clonas o repositório do Azure. Remover os ficheiros do histórico da sua filial impede que os ficheiros sejam removidos de ser atualizados, o que leva à criação de outra versão do ficheiro grande no seu repositório.
Saiba mais sobre como gerir ficheiros grandes no Git. Para uma explicação e solução alternativa para este comportamento quando utiliza repositórios do Azure Repos Git, veja Porque é que a clonagem a partir dos Serviços de Equipa do Visual Studio devolve objetos antigos não referenciados?
Rebase e forçar o push
Se mais ninguém da equipa fizer alterações ao repositório, que normalmente acontecem através de um push, podes optar pelo caminho mais fácil. Basicamente, fazes com que o teu repositório local pareça como queres (ou seja, sem o ficheiro grande). Depois aplicas as suas alterações ao servidor.
Pode ser necessário clonar ou corrigir o repositório local antes de começar este trabalho. Este processo pode resultar em perda de trabalho ou alterações, por isso proceda com cautela.
Por defeito, podes modificar ficheiros de projeto locais e enviar alterações ao servidor, mas não podes realizar operações ao nível do servidor como eliminar ou rebasear. Para avançar, necessitas de Force push (preferido) ou permissões de administrador no repositório. Contacta o administrador do teu projeto para pedir essas permissões, ou pede ajuda a alguém que já as tenha. Para obter mais informações, consulte Definir permissões do repositório Git.
De seguida, precisas de rebasear o repositório.
Use
git logpara encontrar os valores de hash SHA (Secure Hash Algorithm) dos commits mais recentes. Precisa desta informação num momento porque precisa de saber qual é o compromisso mais recente. Pode obter essa informação abrindo um prompt de comandos Git e introduzindo:git logAlternativamente, podes obter o hash SHA ao visualizar o histórico do branch no Visual Studio Team Explorer.
Abre um prompt de comandos Git.
Encontre o número de hash SHA de interesse.
Precisas do SHA que inicia
25b4.Lembre-se de que o Git usa ponteiros para determinar onde no repositório está localizado o cabeçalho ou ramo atual. O estado do repositório no qual estás interessado está localizado num ponto anterior do passado.
Para voltar atrás no tempo e tornar o estado anterior no novo estado atual, use o
git rebasecomando:git rebase -i <SHA hash of desired new current branch>
O
-iinterruptor oferece segurança extra porque mostra o histórico num editor. (Este artigo utiliza uma implementação do Git que abre o editor clássico vi na linha de comandos do Windows. Talvez te lembres se trabalhaste com um sistema baseado em Unix.)Para este exemplo, introduzes:
git rebase -i 25b4Depois de o editor abrir, remova todas as linhas
pickexceto a ramificação que deseja manter como nova cabeça. Quando tudo parecer correto, no vi, entra:w\<enter\>para guardar ou entra!q\<enter\>para sair sem guardar.
Muda as frases que já não queres.
Muda
pickparadropconforme mostrado. Depois entra:w(no vi) para guardar, e entra:q!para iniciar a rebase.Agora entra
git lognovamente. O ramo infrator deve estar ausente do registo. Se assim for, está preparado para a etapa final, que requer permissões de administrador do projeto.git log
O commit para o vídeo grande desapareceu agora do repositório local.
Digite o seguinte comando:
git push --force
Este comando obriga o teu repositório a sobrescrever o repositório no servidor.
Use este comando com cautela porque pode facilmente perder dados no servidor.
Tens de autenticar-te no servidor para que esta ação funcione.
Se estiveres a usar repositórios do Azure, talvez precises de configurar uma credencial alternativa que não use caracteres especiais. Um exemplo é o símbolo at (@) num endereço de email. Para realizar esta tarefa, siga as instruções em Autenticação com repositórios Azure.
Agora o ramo desapareceu permanentemente do servidor. Clones e sincronizações subsequentes feitas pelos membros da equipa do projeto não descarregam os ficheiros grandes que estavas a tentar remover. Os utilizadores precisam de descer do servidor para garantir que estão sincronizados com o estado do novo repositório do servidor.
Se os utilizadores tiverem commits mais recentes
Se outros utilizadores enviaram commits para o repositório do servidor, tem outro ponto a considerar. Queres remover o ramo que contém os ficheiros grandes, mas não queres perder as alterações que a equipa fez. Para resolver esta situação, quando abrir o editor como parte do rebasamento, examine atentamente os commits. Certifica-te de que os commits que queres manter estão listados nas pick linhas. Apaga os que queres remover, como quando um ficheiro grande foi adicionado.
Depois de fazer rebase, os outros utilizadores da equipa também precisam de fazer rebase para que todos tenham uma cópia consistente do repositório do servidor. Este trabalho é aborrecido para todos, e queres evitá-lo. Se precisares de remover um push, tens de coordenar com a equipa. Para mais informações sobre rebase, veja Git branching - Rebasing.
O segredo é garantir que conheces os commits que queres e os que não queres. Estuda o git log ou a história no teu ambiente de desenvolvimento integrado (como o Visual Studio). Tome nota meticulosa dos hashes SHA a manter e dos hashes a remover.
Em cenários em que o ficheiro grande é antigo e houve ramificações e fusões subsequentes, podes conseguir remover o ficheiro usando o git filter-branch switch. Para mais informações, consulte Remoção de dados sensíveis de um repositório.
Considerações sobre boas práticas
Certifica-te de que os ficheiros grandes ficam fora do repositório principal para evitar que os membros da equipa tenham trabalho extra. Aqui estão algumas práticas de bom senso para a equipa ter em conta.
Coisas para fazer
- Faz as alterações com frequência. Sempre podes corrigi-los mais tarde com um squash ou rebase.
- Usa ramificações para isolar as tuas alterações. As filiais são baratas e privadas, e a fusão é simples. Você também pode fazer backup de alterações em uma ramificação enviando-a para o servidor.
- Use uma convenção de nomes quando publicar ramificações de tópicos. Nomeie o ramo
users/<alias>/<branchname>. Este nome ajuda a agrupar os seus ramos e facilita que outros identifiquem o proprietário. - Lembra-te de empurrar as tuas mudanças. Usar
Commit != Checkine(Commit + Push) == Checkin. - Considera usar
.gitignorepara binários grandes para que não sejam adicionados ao repositório. Para mais informações, consulte Ignorar ficheiros. - Considere usar o controlo de versões do NuGet ou do Team Foundation Server para armazenar os seus binários grandes.
Coisas a evitar
- Não faça rebase depois de ter feito push. Rebasear os commits push no Git pode ser mau porque obriga toda a gente no repositório a rebasear as alterações locais. Os membros da equipa podem não ficar satisfeitos se precisarem de fazer esta tarefa. Reanalisar commits enviados no teu próprio ramo pessoal, mesmo após envio, não é um problema a menos que outras pessoas estejam a extrair esses commits.
- Não carregue binários no seu repositório. O Git não comprime ficheiros binários da mesma forma que o Controlo de Versões da Team Foundation. Como todos os repositórios contêm todo o histórico, adicionar ficheiros binários significa um aumento permanente de tamanho.
Resumo
Por vezes, elementos indesejáveis, como ficheiros grandes, são adicionados a um repositório e têm de ser removidos para manter o repositório limpo e leve. Pode fazer esta tarefa organizando o seu repositório local. Usa o git rebase comando e depois usa o git push --force comando para sobrescrever o repositório do servidor com o teu repositório local.