A foto de cima é do Yancy Min, do Unplash
Olá! Esse post é a minha estreia aqui e eu vou tentar deixar um pouco mais claro os conceitos de Git, o porquê que é bom de usar, as boas práticas que eu adoto no meu dia-a-dia e também alguns macetes pra você não ter problemas lá na frente - ou ter menos problemas, pelo menos. Eu to assumindo que você trabalha com Ciência de Dados, mas só pra tentar trazer alguns exemplos pra nossa realidade. Se você não é um DS, ainda acho que tem bastante coisa aqui pra aproveitar. Bora? 😄
O que é Git?
Pra colocar em uma frase: Git é uma ferramenta gratuita e de código aberto para controle de versão de código-fonte. O troço é tão relevante, que foi criado pelo Linus Torvalds, criador do Linux, justamente pra controlar as versões do kernel. Doido, né?
O básico
O que isso significa é que ele vai gerenciar pra você cada modificação que você fizer no seu modelo, alguma variável nova que você está calculando, enfim, tudo o que for modificado vai ser controlado por ele, através de cópias e chaves. Se quiser ler as documentações mais a fundo depois, dá uma olhada no site oficial.
Então imagina que você hoje tenha essa estrutura em uma pasta:
notebooks/ ├── meu_modelo_v1.ipynb ├── meu_modelo_v2.ipynb ├── meu_modelo_v2_27062021.ipynb ├── meu_modelo_final.ipynb ├── meu_modelo_final2.ipynb
E você vai passar a ter uma estrutura assim, quando começar a usar Git:
notebooks/ ├── meu_modelo.ipynb
Ué, mas que bruxaria é essa? 🧙
Versões através de chaves
Com esse desenho lindo aqui em baixo (risos) eu tentei mostrar como fica o seu código ao longo do tempo, da direita pra esquerda. O que acontece é que cada versão do seu código vai ser copiada pelo Git e atribuída a uma chave identificadora única. Isso acontece toda vez que você salvar o seu trabalho, ou, quando você der um commit - eu vou explicar esse jargão um pouco mais pra frente.
Qual a diferença entre Git e Github?
Se a gente controlar as versões do nosso trabalho localmente, isso já dá uma aliviada muito grande. Mas se a gente pensa em trabalhar em equipe ou até mesmo em não depender do nosso computador funcionando sempre, é muito importante que isso vá pra algum lugar na nuvem, em um servidor remoto, para que a gente possa acessar depois. O Github é esse lugar.
Além de armazenar nosso código e arquivos, ele também possibilita a gente controlar algumas coisas através da sua interface gráfica, facilitando bastante o trabalho no dia-a-dia. Além do Github, existem outros servidores remotos de Git, como Gitlab e Bitbucket. Escolhi falar sobre o Github porque é gratuito, o mais popular e, na minha opinião, muito completo.
Trabalhando com Git no dia-a-dia
Dando um salto para o fluxo de trabalho, vamos falar um pouco agora sobre como a gente trabalha com Git no dia-a-dia. Essa é a parte mais densa dessa postagem, mas vamo junto que isso vai ser muito útil para você!
NOTA: Estou aqui partindo do pressuposto que você já baixou o Git na sua máquina e também tem uma conta no Github. Caso contrário, pesquise sobre como fazer e volte aqui depois!
Estrutura do Git e comandos principais
Um pouco mais abaixo eu resolvi deixar mais uma obra de arte para tentar visualmente caminhar pelos comandos mais importantes - não todos - e até entender como e porque a gente usa eles.
O primeiro e talvez mais frequente comando que você vai utilizar é o
$ git status
Com ele, você consegue saber o que tá acontecendo na sua pasta. Quais arquivos você tá e não tá controlando, se a sua versão do código está atualizada de acordo com o seu repositório e assim por diante. Sempre que você quiser conferir se deu certo o que você fez, mande um git status
.
Quando você fizer as modificações no seu código, você vai mandá-lo pra uma área de staging, que vai basicamente indicar pro Git que esse código é um arquivo que você quer controlar a versão. Você faz isso através do comando:
$ git add meu_arquivo.py
Assim, o meu_arquivo.py
irá ser indexado para que entre no seu próximo commit realizado. Se você quiser mandar para a área de indexação todos os seus arquivos de uma vez, use um wildcard, como:
$ git add .
Mas tenha cuidado! É muito fácil mandar algum arquivo ou diretório indesejado utilizando um wildcard. Então depois de adicionar os arquivos para a indexação, lembre-se de rodar um git status
para saber o que está sendo indexado para ser versionado, tá?
Uma vez indexado, seu código poderá ser salvo no repositório local através do comando commit
. Essa etapa também é super importante, pois aqui você terá a possibilidade de dar um resumo sobre quais foram as alterações feitas nessa nova versão do código, de uma forma breve e objetiva. Para isso, use o comando:
$ git commit -m "modelo com média de preços para treino"
O argumento -m
possibilita que você escreva uma frase para representar esse commit. Essa parte é tão crítica, que existem alguns posts sobre como escrever uma boa mensagem no commit.
Uma vez que seu repositório local conhece as modificações que foram indexadas para esse commit, ta na hora de "empurrar" isso pra nuvem, com o comando
$ git push
Dependendo de como você estruturou sua conexão, isso pode mandar as modificações direto para o seu repositório no Github ou te pedir o login e senha. De todo modo, tá salvo!
Os comandos checkout
, pull
e fetch
eu vou cobrir no próximo tópico.
Aproveite sua IDE!
Se você tá acostumado a trabalhar em uma IDE ou Editor de Texto, aproveite as funcionalidades que eles trazem para controle de versão de código. No PyCharm, por exemplo, as linhas que você modifica, apaga ou adiciona, criam marcadores específicos, que te indicam o que foi feito ali em relação ao código original.
Além disso, os arquivos modificados também ficam com cores diferentes. E não só você pode acompanhar visualmente as modificações, como também pode realizar add, commit e push com apenas alguns cliques. Eu gosto muito de fazer tudo em um lugar só, então vale muito a pena explorar isso. Confia! 🤞
Trabalhando em equipe
Bom, agora que você já tem uma ideia de como controlar as versões do código, chegou a hora de falar um pouco sobre como você faz pra utilizar isso na vida real, trabalhando com mais pessoas. E não ache que porque você é o único Cientista de Dados do seu projeto você está sozinho nessa.
O seu eu do futuro também é o seu colega de trabalho. Parece meio louco pensar nisso, mas se você passar alguns meses sem mexer com um projeto, vai ser muito difícil olhar pra trás e saber o que foi feito sem existir uma boa documentação e cuidado com o trabalho realizado.
Branches
Pensando em trabalhar com mais pessoas, é fundamental que exista um código principal e que sejam criadas versões espelhadas do seu projeto, para que você possa fazer quaisquer mudanças sem afetar o código principal.
Pensando nisso, criou-se o conceito de branch (em inglês, galho de árvore), que são ramificações do código principal. Para criar uma branch, você pode utilizar a interface gráfica do Github, clicando onde estiver escrito master (ou main), como mostra a figura:
Feito isso, mude para a branch criada no seu local de trabalho, utilizando os seguintes comandos:
$ git fetch
$ git checkout my_new_branch
Como vimos na figura da seção anterior, o git fetch
irá pegar as modificações do repositório remoto e trazê-las para o repositório local. Isso faz com que o Git local possa identificar que uma nova branch chamada my_new_branch
foi criada. Com o comando checkout
, você irá passar a trabalhar nela.
A partir daqui, todas as suas modificações irão ser contempladas e realizadas na sua própria branch, sem afetar o código principal. Uma vez que você estiver satisfeito com as suas modificações, você poderá abrir uma Pull Request.
Pull Requests
Se você estiver trabalhando no seu código em uma branch específica, a versão principal ficará desatualizada em relação às suas modificações, certo? Por isso, quando você julgar que essas modificações podem fazer parte do código principal, abra uma Pull Request (PR). Pra fazer isso pelo Github, basta você abrir a aba de PR's, clicar em New Pull Request e seguir as instruções.
Vale ressaltar aqui que é muito importante que alguém revise suas modificações. Para isso, indique alguém do seu time para ser um "Reviewer" do lado direito da janela principal da PR. Isso faz com que a pessoa veja com clareza as modificações realizadas no seu código, escreva mensagens específicas, aprove ou até faça a requisição de modificações.
Uma vez aprovada a PR, o código principal irá contemplar as suas alterações e você contribuiu para o projeto de uma forma controlada e responsável!
Tendo em vista que outras pessoas podem ter feito PRs e modificações na branch principal, é importante periodicamente rodar o comando git fetch
. Existe uma opção no VS Code que ele faz isso pra você!
Se você desejar que as alterações do código feitas venham diretamente para o seu local de trabalho, você também pode utilizar o comando:
$ git pull
Finalizando assim a lista de comandos que eu tinha prometido anteriormente.
Motivos para pensarmos em Gitflow
Esse tópico pode até ser considerado um pouco mais avançado, mas a filosofia dele é extremamente importante e eu estou colocando nessa postagem porque eu queria que alguém tivesse me dito isso quando eu estava começando.
Se você já trabalhou com desenvolvimento ou pelo menos foi em algum meetup, muito provavelmente você já ouviu a seguinte frase, entoada a plenos pulmões:
"NUNCA DÊ COMMIT NA MASTER"
Mas... por que?
Primeiro que, se você fizer um commit no código principal que esteja com algum pequeno bug, outras pessoas vão deixar de ter um código que funciona para trabalhar, e isso por si só já pode ser um baita problema.
Mas vamos pensar mais além, se temos uma aplicação em produção, como um modelo de Análise de Crédito, por exemplo, ele provavelmente vai estar sendo consumido por uma pipeline de Integração e Deploy contínuos (CI/CD). Isso significa que a aplicação se baseia na branch principal para funcionar. Se você der um commit diretamente nela, a aplicação vai ser automaticamente atualizada.
Se seu código possui erros, no melhor dos cenários ela para de funcionar. No pior dos cenários, ela irá entregar análises de crédito erradas e até trazer um grande prejuízo pra empresa. Chato, né? Então por isso que é muito importante sempre pensar em trabalhar em branches e realizar PR's. Essa é a mensagem.
O termo "Gitflow" é utilizado baseando-se numa metodologia que padroniza a nomenclatura de branches e também parte do princípio que o ciclo de vida de uma branch é bem curto - no máximo 3 dias. Isso faz com que o código seja constantemente revisado, que as modificações nele sejam incrementais e que exista uma política de governança bem estabelecida para o trabalho. Se quiser ler mais sobre, veja essa postagem em inglês da Atlassian.
Não versione dados com Git
"Bom, se é importante eu salvar meu trabalho e as versões dele, então fica mais fácil já colocar junto também os dados em CSV que eu tô utilizando, certo?"
E aqui vai um grande NÃO.
O Git foi feito para controlar inúmeras versões dos códigos escritos justamente porque são arquivos extremamente leves e fáceis de serem controlados. Se você trabalha com dados locais, como arquivos em CSV ou XLSX, crie um arquivo no seu repositório chamado .gitignore
. Com ele, você vai poder dizer o que o Git não deve olhar quando verificar alterações. Um template que eu uso pode ser escrito assim:
# Python secondary files
__pycache__/
*.py[cod]
*$py.class
.ipynb_checkpoints/
# VS Code config file
.vscode/
# Datasets
*.csv
*.xlsx
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Other files
.idea/
.idea/*
Existem ferramentas específicas para versionamento de dados, como o DVC, mas que fogem do escopo desse artigo.
Resumão
Nesse meu primeiro artigo, quis trazer um "curso relâmpago" de Git, com algumas especificidades de Data Science pra te ajudar a trilhar essa jornada e estabelecer conhecimentos fundamentais do Desenvolvimento de Software para o seu dia-a-dia.
Sei que se você nunca mexeu com Git essa postagem pode ter sido cheia de jargões ou conceitos que ainda estão um pouco obscuros pra você. Ao mesmo tempo em que é apaixonante, também pode ser exaustivo trabalhar com tecnologia. Não se desespere! Pesquise mais, leia mais e exercite sua curiosidade, que eu garanto que isso tudo vai se esclarecer aos poucos pra você.
Se mesmo assim tem algum conceito que eu falei aqui e que ainda não tá claro, me manda uma mensagem, comenta aqui em baixo e me ajude a tornar essa postagem ainda mais acessível.
Um abraço e boa caminhada! 🚀
Top comments (2)
Gostei bastante do texto!
Uma opção que eu gosto muito é a —ff-only quando você dá um git pull.
Com essa opção, se não for possível realizar o pull através simplesmente de um fast forward merge a operação é abortada. Acho bem legal pra evitar merges acidentais (:
Muito massa amigo. Só uma dica pros incautos: incluam no seu .gitignore toda forma possível é imaginável de formato de dados, como .csv, .xlsb, .7z, .rar e etc. Nunca se sabe o formato de dados que o time de engenharia vai te disponibilizar, hahahaha.