Use “Unpublish branch” no branch master e sinta seu coração parando por alguns segundos
Recentemente eu descobri – por acaso – um fluxo de trabalho potencialmente perigoso enquanto estava usando usando a ferramenta gráfica de Git do Visual Studio 2013 Team Explorer (conhecida como “Git Tools for Visual Studio” e que vêm nativamente no VS 2013). Dependendo da sua sequência de ações, pode levar à perda de todo o conteúdo de seu repositório Git no TFS!
TL, DR: Via de regra, nenhum usuário deveria receber a permissão de Force Push no TFS. Com ela, coisas muito ruins podem acontecer.
Recentemente, tenho desenvolvido um experimento pessoal: quero identificar que tipos de coisas ruins um desenvolvedor com uma mentalidade CVCS (Centralized Version Control Systems, como o TFS antes do Git, Subversion e outros) poderia fazer enquanto usando Git com o TFS. A ideia é ajudar nossos clientes que estão iniciando a adoção do Git como sua ferramenta de controle de versão. Bem, não precisei procurar muito… Um dos fluxos de trabalho que eu testei foi: “como eu recomeço do zero caso eu tenha ‘arruinado’ minha cópia de trabalho?” Eu sei como faze-lo no Git, mas intencionalmente estava tentando imitar o que um desenvolvedor com uma mentalidade mentalidade CVCS (naturalmente TFVC foi minha principal referência) faria enquanto estivesse usando Git dentro do VS. O que eu tentei fazer:
- Reverter todas as alterações pendentes;
- Eliminar a cópia de trabalho local;
- Baixar uma nova cópia do servidor. Para a etapa 1, um simples “botão direito do mouse + ‘Undo” ‘resolveu o problema. O segundo foi o mais engraçado (ou mais assustador – você escolhe ;-)). Qualquer usuário experiente do TFVC, tendo usado os espaços de trabalho do servidor (server workspaces) no passado, provavelmente usa o mesmo truque para limpar sua cópia de trabalho local: “Get Specific Version”, informa o changeset “1” e conclui com um “Force Get”. Dessa forma, TFS “esquece” o que já tinha sido baixado e, assim, pode-se apagar o diretório local e fazer um Get Latest. Até aqui, tudo bem. Mas agora estou utilizando o Git. Como eu digo TFS para interromper o controle do meu repo local (ou seja, “esquecer” o que eu já tinha baixado)? Ei, aquela coisa de “Unpublish branch” deve resolver. Isso provavelmente vai dizer TFS para esquecer meu branch local (“Acho que deve retirar aquela coisa de ‘URL remoto’) e então eu posso apagar minha cópia local e simplesmente clonar novamente do servidor. Então eu “despublico” o branch em que estava trabalhando (master, claro ): E com nenhum aviso de qualquer tipo, eu acabo assim: Legal! Agora vamos apagar minha pasta de trabalho e clonar o remote novamente. E depois vem aquele momento ao qual me referi no título do post: Meu código tinha ido embora! Não, não é possível. Melhor verificar o Web Access: Oops… Acabei de apagar meu repositório!!!
O que aconteceu?
O comando “Unpublish branch”, na verdade, equivale a um comando “Delete branch”. O raciocínio é o seguinte:
- Tenho um branch local;
- Eu envio (push) esse branch para o servidor;
- Mas agora não quero mais que esse branch esteja lá. Quero “desfazer” essa publicação do meu branch no repositório remoto. Logo, vou “despublicar” (excluir) o branch remoto. Só que, em circunstâncias normais, você não conseguiria fazer isso. Afinal, outras pessoas podem estar usando aquele branch. Por isso, uma operação normal de push não conseguiria excluir esse branch. O Git, como forma de garantir que você sabe o que está fazendo, exige que você faça um Force Push (tipicamente significa acrescentar o –f à linha de comando do Git). Desde que você tenha as permissões necessárias para o Force Push, você conseguiria excluir o branch remoto. E o Team Explorer (a interface gráfica de Git do Visual Studio) faz o Force Push automaticamente na hora do comando Unpublish Branch. Entretanto, isso não deveria implicar em perda de dados. Afinal, um dos grandes pontos fortes do Git é exatamente sua característica distribuída. Todo o histórico do controle de versão está clonado no meu repositório local. Mesmo após excluir o branch, bastaria um novo git push origin master e tudo estaria de volta a seus devidos lugares. O problema é que, no exemplo acima, eu apaguei meu repositório local (minha “cópia de trabalho”) e, portanto, perdi minha única chance me enviar os dados de volta. Se eu tivesse outros desenvolvedores no time, eles poderiam fazer o push e por tudo de volta no lugar. Se sou o único desenvolvedor a ter clonado aquele repositório (ou se ninguém faz um pull há muito tempo), então… Bem, então tenho um problemão nas mãos!
Como evitar?
Remova a permissão de force push de todos os seus desenvolvedores. Dê essa permissão apenas a alguns usuários administrativos, que não usem essas credenciais de administrador no dia-a-dia. Sempre que necessário, um desses usuários faria o force push, tendo a oportunidade de conferir o que está sendo feito. No TFS (e por extensão no VSO), a permissão de Force Push está na aba Version Control da página de configurações do Team Project: Por padrão, desenvolvedores (“Contributors”) não têm permissão de Force Push. Mas a pessoa que criou o repositório tem. Você provavelmente vai querer tirar as permissões dessa pessoa também…
Moral da história
Como em qualquer sistema, evite dar mais permissões do que a pessoa precisa – ainda mais quando ela não domina a ferramenta/sistema/aplicação. Muitas vezes, pode ser como dar uma metralhadora na mão de um macaco! Um abraço, Igor
06/08/2014 | Por Igor Abade V. Leite | Em Técnico | Tempo de leitura: 5 mins.