O que é o GIT
A escrita tem sido uma forma de comunicação presente na vida humana desde tempos imemoriais. As primeiras formas de escrita surgiram em torno de 4000 a.C., e desde então a humanidade evoluiu as técnicas desta forma de comunicação. As primeiras formas de escrita foram em tábuas de argila e papiro, respectivamente. Os pergaminhos criados pelos antigos egípcios por volta do século III a.C. foram amplamente utilizados até a invenção do papel pelos chineses no século II a.C. Posteriormente, outras invenções importantes surgiram, como a impressora, o telégrafo e o computador. Recentemente, a internet e a tecnologia digital têm sido as grandes inovações que revolucionaram a comunicação escrita, permitindo a criação de novas formas de comunicação, como o e-mail, as redes sociais, os aplicativos de mensagens e outros meios de comunicação em tempo real. Essas inovações tornaram a comunicação mais rápida, acessível e globalizada do que nunca antes.
Com o progresso da tecnologia, tornou-se necessário criar novas linguagens artificiais para simplificar a comunicação entre humanos e máquinas. Isso resultou em um aumento no desenvolvimento de código para atender a essa demanda e, consequentemente, a qualidade do código passou a ser cada vez mais exigida. A necessidade de controle e entrega também se tornou evidente, o que levou ao surgimento da ideia de versionar o código. Foi então que surgiu o Git, uma plataforma que possibilita o controle de versionamento de códigos.
O Git é um software que funciona como um sistema de gerenciamento de versões distribuído. Foi criado por Linus Torvalds com o objetivo inicial de solucionar os problemas de versionamento de código no desenvolvimento do kernel Linux, permitindo o registro do histórico de edições de diferentes tipos de arquivos. O sucesso do software foi tão grande que ele se tornou amplamente utilizado por muitos outros projetos ao longo do tempo.
Porque usar o GIT
Há várias razões pelas quais o Git é amplamente adotado como um sistema de controle de versão de código. Alguns dos principais motivos incluem:
Sistema de controle de versão distribuído: Ao contrário de outros sistemas de controle de versão centralizados, o Git é distribuído, o que significa que cada desenvolvedor tem uma cópia completa do repositório. Isso torna o processo de colaboração mais fácil e flexível, permitindo que os desenvolvedores trabalhem em diferentes ramos do projeto simultaneamente.
Histórico completo de alterações: O Git mantém um registro de todas as alterações feitas no código-fonte, permitindo que os desenvolvedores acessem o histórico completo de alterações. Isso ajuda a evitar a perda de código e facilita a resolução de problemas.
Ferramentas de colaboração: O Git oferece várias ferramentas para facilitar a colaboração entre desenvolvedores, incluindo a capacidade de revisar e mesclar o código-fonte de diferentes desenvolvedores.
Gerenciamento de conflitos: O Git possui recursos para ajudar a gerenciar conflitos quando duas ou mais pessoas modificam o mesmo código-fonte ao mesmo tempo.
Ramificação e fusão de código: O Git permite que os desenvolvedores criem diferentes ramificações do projeto, o que é útil para testar novos recursos ou corrigir problemas sem afetar o código-fonte principal. Em seguida, é possível mesclar as alterações de volta à ramificação principal de forma organizada e controlada.
Popularidade e suporte: O Git é amplamente utilizado em todo o mundo e possui uma grande comunidade de usuários e desenvolvedores, o que significa que existem muitos recursos, tutoriais e fóruns disponíveis para ajudar a resolver problemas ou aprender a usar o sistema.
Databricks
Como uma possível forma de melhor utilizar o Git no Databricks, é recomendado seguir algumas boas práticas. É importante utilizar pelo menos três branches: a branch pessoal, a branch de desenvolvimento e a branch de produção. Na branch pessoal, somente um desenvolvedor deve acessar e desenvolver o código. Na branch de desenvolvimento, o desenvolvedor deve fazer um merge do notebook quando acreditar que o código está maduro, compartilhando desta forma com outros desenvolvedores. Já a branch de produção é para elevar somente notebooks finalizados, testados e homologados. Entre a branch de desenvolvimento e produção podem ser implantadas outras branches como a de homologação por exemplo.
Ao criar a branch pessoal, é recomendado fazer o pull da branch de desenvolvimento, considerando-a como a branch centralizadora, pois esta branch é a menos regulamentada e a mais adequada para receber as alterações feitas pelos desenvolvedores. É importante que todos da equipe estejam cientes deste procedimento. Dessa forma, garante-se que o recurso baixado está correto e sem falhas, já que iniciar uma edição a partir de um arquivo com falhas ou que esteja sendo editado em outra frente pode gerar conflitos. No entanto, algumas equipes podem optar por fazer o pull diretamente da branch de produção em vez da branch de desenvolvimento.
Quem ainda não conhece sobre GIT está se perguntando o que é “Pull Request” ou simplesmente “pull”. Responder a esta pergunta envolve o entendimento de duas palavrinhas que vão acompanhar os entusiastas para sempre: “pull” e “push”. Estas duas podem causar certa confusão se não forem bem entendidas.
O contrário de "pull" no Git é "push". Enquanto "pull" é usado para trazer as alterações feitas por outros colaboradores em um repositório remoto para o repositório local, "push" é usado para enviar as alterações feitas no repositório local para um repositório remoto. O comando "git push" é usado para enviar as alterações para um repositório remoto específico, como o GitHub, GitLab ou Bitbucket. Isso pode ficar um pouco confuso para quem usa Databricks, pois o comando “push” não existe neste Software, aqui existe apenas o comando “pull”. Isto quer dizer que só é possível “puxar, ou, trazer” os arquivos de código para a branch, e não empurrá-los para o repositório central. Então como podemos “empurrar” uma branch de códigos atualizados para o repositório de destino? Usando o comando commit. No Git, um commit é uma gravação de uma alteração em um ou mais arquivos do seu repositório, contendo um conjunto de mudanças e uma mensagem descritiva. Cada commit é um registro único que representa uma versão do seu projeto, com um identificador único chamado hash do commit. Ao executar o comando commit no Databricks uma versão é gravada no gerenciador de código-fonte (Bitbucket ou Github por exemplo), a partir daí é possível fazer o “Pull Resquest” da Branch de desenvolvimento para a branch de produção por exemplo.
Até agora não falamos sobre “push”. No entanto, embora a função “push” não esteja disponível para desenvolvedores do Databricks usarem diretamente, é importante ter em mente seu uso, pois em outras ocasiões o comando será útil. É importante saber que o “pull” atende às necessidades da área de data analytics. Após a finalização de todos os commits no Databricks e a abertura do site gerenciador de código-fonte (Bitbucket ou Github), é necessário fazer um “pull” da branch “pessoal” para a branch de desenvolvimento (para atualizar) ou desta para a branch de produção, a fim de efetuar a atualização da branch de destino. Por outro lado, é importante estar ciente de que não é possível “empurrar” os arquivos atualizados no gerenciador de código-fonte para o Databricks. Portanto, é necessário fazer sempre um “pull” do repositório central (gerenciador de código-fonte) para o repositório local (Databricks) quando se inicia um novo desenvolvimento no Databricks. Isso deve ser seguido como um hábito.
As branches são criadas no repositório central (gerenciador de código-fonte, por exemplo) e, em seguida, copiadas para o Databricks. Isso garante que os códigos do repositório possam ser recuperados em casos de catástrofes. No entanto, em alguns casos, essa regra pode não ser tão rigorosa em termos de segurança, permitindo que um arquivo seja editado simultaneamente localmente e na branch de produção. A falta de atenção nesta questão é um perigo.
Cuidados
Entender e utilizar os comandos "commit", "pull", aprovar e merge é fundamental para o desenvolvimento de projetos em equipe ou individual. É importante lembrar que fazer uma alteração na branch de produção, por menor que seja, mesmo que seja para "verificar um comportamento", é inadmissível, pois pode causar problemas graves sejam técnicos ou comerciais. Portanto, é crucial criar uma branch para fazer as alterações necessárias e, em seguida, deletá-la. Isso pode parecer um trabalho insignificante, mas é essencial para garantir a integridade do código.
Não há necessidade de ter medo de deletar uma branch pessoal criada para uso temporário, pois ela não será mais utilizada. É recomendado deletá-la ao final do desenvolvimento, pois manter branches pessoais em desuso no repositório pode poluir o ambiente. Ao seguir essas práticas, é possível garantir um ambiente de desenvolvimento mais organizado e seguro para toda a equipe.
Ao trabalhar com branches no Databricks é importante conhecer as opções de resolver conflitos de merge. Mas o que são conflitos de merge? Sabemos que ao desenvolver um código fazemos diversos commits dentro de uma branch e ao finalizar o desenvolvimento criamos um “pull”. Pull request é uma forma de solicitar a revisão e aprovação do código por outros membros da equipe, e que essa é uma prática comum em projetos colaborativos. Para garantir a alta qualidade do código, o “pull request” precisa ser aprovado, isto é, neste momento a qualidade do código pode ser avaliada, e se aprovado, deve ser feito um merge. Um "merge" é o processo de combinar duas ou mais ramificações (branches) de forma a integrar alterações feitas em diferentes branches do mesmo repositório e manter um histórico único e ordenado de todas as alterações de um repositório Git em uma única ramificação, isto é, o merge unifica os arquivos recém elevados, e até então instáveis, da branch de origem com os arquivos estáveis da branch de destino. Antes de seguir na leitura volte ao paragrafo anterior e observe a importância de não fazer alteração diretamente na branch de produção. É importante usar as branches de desenvolvimento, e não fazer alterações diretas na branch de produção, pois isso pode gerar conflitos e dificultar o trabalho da equipe.
E os conflitos? Os conflitos ocorrem ao clicar no comando “merge”. A explicação é que toda branch inicia de uma ramificação principal. Ao desenvolver uma nova funcionalidade em uma ramificação chamada "feature" por exemplo, o desenvolvedor pode querer mesclar essa funcionalidade de volta na ramificação principal do repositório (geralmente chamada de "master" ou "main"). Dependendo do caso, o Git pode realizar a operação automaticamente, ou pode precisar que o desenvolvedor resolva conflitos manualmente, caso haja alterações conflitantes nas duas ramificações. Conflito de merge é um problema que pode ocorrer ao mesclar (ou "fundir") duas versões diferentes de um mesmo arquivo ou conjunto de arquivos em um sistema de controle de versão, como o Git. Isso pode acontecer quando duas pessoas estão trabalhando no mesmo arquivo ao mesmo tempo e fazem alterações diferentes em áreas próximas ou na mesma linha do código. Ao tentar mesclar essas alterações, o sistema pode não saber como combiná-las, resultando em um conflito que precisa ser resolvido manualmente pelos usuários envolvidos. A resolução de conflitos de merge é uma parte crítica do trabalho em equipe em projetos de desenvolvimento de software e requer comunicação e colaboração para garantir que as mudanças sejam mescladas de forma eficiente e sem erros.
Resolver conflitos de merge pode ser considerado como o arroz com feijão do desenvolvedor do Databricks, pois acontece com bastante frequencia, mas não é para se desesperar. Com pouco de tempo se ganha experiencia para que a resolução dos conflitos deixe de ser uma preocupação e flua suavemente. Para resolver conflitos é importante conhecer as opções que o Git oferece e as opções que o gerenciador de código-fonte (Bitbucket ou Github por exemplo) oferecem.
Há algumas boas práticas para nomear branches em repositórios de código que podem ajudar a manter a organização e a clareza. É importante usar nomes descritivos que deixem claro o que está sendo trabalhado, como "feature/login" para uma nova funcionalidade de login. Letras minúsculas e hífens são frequentemente usados para separar palavras em nomes de branches, tornando-os mais legíveis e menos propensos a erros. É fundamental manter a mesma convenção de nomenclatura em todo o projeto, por exemplo, usando o prefixo "feature/" para todas as branches de novas funcionalidades.
O nome do branch deve ser o mais curto possível, mas ainda assim descritivo. É recomendado evitar caracteres especiais que possam causar problemas em alguns sistemas de controle de versão. Se trabalhando em um projeto em equipe, incluir o número do ticket correspondente pode ser útil, como em "feature/login-123". Vale lembrar que a nomenclatura do branch é uma questão de preferência pessoal e convenções da equipe, mas é importante manter uma convenção clara e consistente para facilitar a compreensão e a organização do repositório de código.
Existem vários prefixos comuns que podem ser usados para ajudar a identificar o tipo de branch em um repositório de código. Alguns exemplos incluem: "feature/" ou "feat/", usado para branches que contêm novas funcionalidades que estão sendo desenvolvidas; "bugfix/" ou "fix/": usado para branches que contêm correções de bugs; "hotfix/" ou "hf/", usado para branches que contêm correções urgentes que precisam ser implantadas rapidamente; "release/" ou "rel/", usado para branches que contêm código que está pronto para ser implantado em produção; "develop/" ou "dev/", usado para a branch principal de desenvolvimento, onde todo o trabalho está integrado antes de ser mesclado em um branch de release ou main/master; "main/", "master/", ou "trunk/, usado para a branch principal de desenvolvimento, que contém o código estável e pronto para produção.
É essencial ter em mente que a escolha do prefixo para a nomenclatura do branch é uma decisão que depende da preferência pessoal e da convenção adotada pela equipe. Contudo, é crucial manter a consistência na forma como os nomes dos branches são definidos em todo o repositório de código, a fim de facilitar a compreensão e organização do projeto.
Resumo
O uso do Git como ferramenta de versionamento traz muitos benefícios para qualquer tipo de projeto, inclusive no Databricks, garantindo a qualidade do código. A curva de aprendizado para começar a usar o Git como ferramenta de versionamento é relativamente baixa diante dos benefícios. É necessário ter a mente aberta quanto às nomenclaturas e padrões, pois cada equipe pode adaptá-los conforme a necessidade de adequação ao projeto, mas é importante não fugir das boas práticas citadas nos livros sobre Git e nas recomendações internacionais.
Além de entender como o commit funciona em relação à branch pessoal e como esta se relaciona com as outras branches, é fundamental entender a hierarquia das branches e os comandos "pull", "push", "approve" e merge. E, sobretudo, é importante ter em mente que nunca se deve alterar o código diretamente na branch master.
Da mesma forma, que entender os comandos principais, é preciso conhecer as formas que o Git e as ferramentas de gerenciamento de código-fonte disponibilizam para resolver problemas de conflito de merge.
Assimilando o básico do Git, é possível aumentar a confiabilidade dos códigos entregues, ter mais eficiência e qualidade no trabalho.