Tip
Guia prático e simples para usuários de R que não são da área de tecnologia, usando apenas 3 pacotes.
O GitHub é uma platafornma muito últil a diversos tipos de programadores, para o armazenamento e versionamento dos seus códigos. Para profissionais que usam a programação fortemente nas suas vidas mas não são da área de tecnologia, como biólogos (que também é o meu caso), alguns conceitos e operações sobre Git e GitHub podem ser pouco intuitívos, e até confusos. Mais ainda, operações sobre como conectar IDEs de programação, como o RStudio, ao GitHub podem se tornar desafios ainda maiores.
Desta forma, o objetivo deste guia é apresentar uma forma prática de não apenas entender como o GitHub funciona, mas como trabalhar com ele, usando apenas linguagem de programação R, pensando em usuários de programação que não são da área de tecnologia.
Important
Imagino que você deva estar com muita pressa para pôr a mão-na-massa e com muitas demandas, mas antes de ir para os códigos de fato, leia esta introdução BEM geral com calma. Ela te explicará alguns conceitos chaves que, sem ele, você não entenderá como o código e pode te complicar ainda mais.
O Git é um sistema de controle de versionamento de arquivos, onde permite que você controle as versões de um arquivo que vão para um repositório online ou no seu computador. Ele se apresenta como uma série de comandos de código. Devido a esta sua natureza, este pode não ser tão agradável para pessoas que não são da área de tecnologia e não estão acostumados ao uso de terminais.
O GitHub é uma plataforma online, que serve como rede social e conjunto de repositórios, que pode funcionar tanto com conexão com Git quanto de forma manual. Atualmente sob domínio da Microsoft, o GitHub é atualmente a maior plataforma online de repositórios de código aberto, onde boa parte dos softwares atualmente possuem seus códigos fonte hospedados no GitHub.
O fluxo de trabalho padrão para enviar um arquivo para um repositório funciona da seguinte forma:
- Projeto (pasta) conectado ao repositório do GitHub;
- Branch: uma
branché como uma linha do tempo. Um mesmo repositório pode ter mais de uma linha do tempo, que funcionam de formas independentes. Uma brach não interfere na outra, a não ser que você faça ummergede uma branch para outra. Por padrão, a branch principal se chamamain; - Status dos arquivos áptos: avalia quais arquivos estão
áptospara serem enviados ao repositório do GitHub, baseado se apresentam mudanças; - Adicionar arquivo: seleciona um arquivo
áptodentro da pasta para ser enviado para o GitHub. Os arquivos áptos precisam apresentam alguma forma de diferença com os arquivos do repositório do GitHub. Esse processo é como se você colocasse uma encomenda numa caixa de envios; - Commit: salva as mudanças do arquivo adicionado para as mudanças. O commit carrega uma mensagem sobre o que está sendo enviado. Esse processo é como se você colocasse as informações de destino e conteúdo da caixa de envio da encomenda;
- Push: envia as mudanças. As mudanças salvas já foram enviadas e, caso não haja nenhum conflito, estarão no repositório do GitHub. Esse processo é como se você enviasse para o serviço de envio da encomenda;
- Pull: puxa as mudanças do repositório para a pasta local, atualizando seus arquivos. Esse processo é como se você recebesse uma notificação que sua encomenda chegou no destinatário.
- Remover arquivo: remove arquivos do repositório do GitHub. Também funciona no sistema de commit, push e pull;
- Resetar arquivo adicionado: tira o status de adicionado de todos os arquivos adicionados para mudança;
- Resetar commit: apaga todos os commits feitos e não enviado para o repositório do GitHub.
flowchart LR
A{**Projeto**} --> B[**Branch main**]
A --> C[**Branch paralela**]
B --> D[**Adicionar o arquivo**]
D --> E[**Commitando a mudança**]
E --> F[**Pushando para o respositório**]
F --> G[**Pullando do respositório**]
H[**Removendo arquivo**] --> E
D --> I[**Resetar arquivos adicionados**]
E --> J[**Resetar commits**]
B --> H
B --> K[**Mergendo as branches**]
C --> K[**Mergendo as branches**]
B --> L[**Status dos arquivos que possuem mudanças**]
style A fill:forestgreen, color:black, stroke:black, stroke-width:2px
style B fill:gold, color:black, stroke:black, stroke-width:2px
style C fill:royalblue, color:black, stroke:black, stroke-width:2px
style D fill:goldenrod, color:black, stroke:black, stroke-width:2px
style E fill:goldenrod, color:black, stroke:black, stroke-width:2px
style F fill:goldenrod, color:black, stroke:black, stroke-width:2px
style G fill:goldenrod, color:black, stroke:black, stroke-width:2px
style H fill:orangered, color:black, stroke:black, stroke-width:2px
style I fill:tomato, color:black, stroke:black, stroke-width:2px
style J fill:tomato, color:black, stroke:black, stroke-width:2px
style K fill:lightgreen, color:black, stroke:black, stroke-width:2px
style L fill:yellow, color:black, stroke:black, stroke-width:2px
linkStyle default stroke-width:3px
Os pacotes usados nestas operações são:
- usethis: inicia a ssesão com o GitHub e conecta a pasta ao repositório;
- gitcreds: credencia as chaves de permissão e acesso ao GitHub;
- gert: faz o processo de adicionar, commit, push, pull e outros processos de fluxo de trabalho.
Important
Antes de carregar os pacotes, certifique os mesmos estão previamente
instalados. Caso não, instale-os usando a função install.packages().
library(usethis)
library(gitcreds)
library(gert)Para começar, precisamos configurar nosso perfil do GitHub para o
RStudio. Usamos o pacote usethis, através da função
use_git_config().
usethis::use_git_config(user.name = "seuusername",
user.email = "seuemail@gmail.com")Em seguida, vamos autenticar a conexão do seu computador para a sua
conta do GitHub. Precisamos informar ao GitHub que o seu computador está
autorizado a mandar as modificações para a sua conta. Para isso, usamos
o pacote usethis, através da função create_github_token().
usethis::create_github_token()Essa função abre no seu navegador a sua conta do GitHub. Nesta página,
você irá criar um token, uma chave de acesso e permissão. Esta chave
tem limite de tempo, e você pode escolher quando ela irá expirar. Após
cria-la, você irá copia-la e coloca-la dentro do R. Para isso, usamos o
pacote gitcreds, através da função gitcreds_set().
gitcreds::gitcreds_set("seu_token_vem_aqui")Important
Talvez seja óbvio, mas não divulgue seu token. Seu token não é público e só você tem acesso. Caso outras pessoas tenham acesso, elas poderão ter acesso à sua conta do GitHub e poderão fazer alterações sem a sua permissão.
Agora que seu computador e seu R já podem enviar arquivos para os
repositórios da sua conta do GitHub, agora vamos conectar o R a algum
repositório. Naturalmente, o RStudio cria projetos
(RProj), pastas
separadas, para cada repositório conectado. Para isso, existem duas
posíveis formas de fazer a conexão:
- Você cria um novo projeto para o repositório;
- Você conecta um projeto
(
RProj) existente ao repositório desejado.
Important
Por padrão, O RStudio abre a sessão no último projeto aberto, no
momento que você liga o RStudio. Na pasta do seu computador onde fica
o RProj, existe um arquivo .Rproj, que ao clicar, você acesso aquele
projeto em específico. Para evitar que o RStudio carregue o último
projeto aberto e hajam confusões, e então carregue uma sessão “limpa”,
vá em no seu RStudio em:
- Tools;
- Global Options;
- R General;
- Desmarque a opção
Restore the most recently opened project at restartup.
Para mais informações sobre RProjs, clique neste artigo do Curso-R sobre o assunto.
Para primeira opção, usamos o pacote gert, através da função
git_clone(). Isso cria um clone do repositório no seu computador, onde
você informa a URL do repositório (argumento url) e a pasta do seu
computador onde o projeto do repositório ficará (argumento path).
gert::git_clone(url = "url_do_seu_repositório.git",
path = "caminho_da_pasta_do_seu_computador")Para segunda opção, usamos o pacote usethis, através da função
use_git_remote(). Esta função informa o repositório (argumento url)
e o nome que damos a ele (argumento name), que é como o R irá
reconhecer a conexão com o repositório.
usethis::use_git_remote(name = "nome_do_remote",
url = "url_do_seu_repositório.git",
overwrite = TRUE)Desta forma, é possível conectar mais de um repositório para um único
projeto. Para listar os repositórios conectados ao projeto, usamos o
pacote gert, através da função git_remote_ls().
gert::git_remote_ls()Agora que estamos de fato conectados um repositório do GitHub, podemos enviar nossos arquivos. O primeiro passo é identificar quais os arquivos áptos a serem enviados ao GitHub. Quando estamos conectados a um repositório do GitHub, ele automaticamente identifica quais arquivos do seu computador estão lá, e se há modificações entre o arquivo do seu computador e sua versão do repositório, baseado em seus nomes.
Para isso, usamos o pacote gert, através da função git_status().
Esta função gera um dataframe, com as informações do nome do arquivo
áptos para enviar ao repositório do GitHub (coluna file), se o arquivo
é novo em relação ao repositório ou se este arquivo é um arquivo
modificado (coluna status) e se ele está marcado para ser enviado
(coluna staged).
gert::git_status()Sabendo quais são os aquivos áptos a serem enviados ao GitHub, podemos
selecionar os arquivos e adiciona-los. Para isso, usamos a função
git_add(), do pacote gert. Podemos selecionar apenas um arquivo pelo
seu nome completo, ou diversos arquivos, através de padrões dos seus
nomes, como selecionar arquivos que comecem com a string script_ ou
arquivos de um formato em específico, como .R, usando a função
list.files().
gert::git_add(files = "script_de_analises.R")
gert::git_add(files = list.files(pattern = "^script_"))
gert::git_add(files = list.files(pattern = ".R$"))Important
Dentro de uma string (" "), usamos ^ para dizer que queremos
apenas os arquivos que comecem com aquele padrão de string, e $ para
dizer que queremos apenas os arquivos que terminem com aquele padrão
de string. Para mais informações sobre como funciona padrões de
detecção de strinfs, veja este tutorial sobre Regular Expressions
(RegEx)
e este
também.
Agora que os arquivos foram selecionados e adicionados, podemos fazer
nossos commits. Estes são feitos usando a função git_commit(), do
pacote gert. Procure criar commits que expliquem o que é o arquivo e
para o que ele serve.
gert::git_commit(message = "Script para analisar os dados")O próximo passo é de fato enviar ao repositório. Isso é feito pela
função git_push(), do pacote gert. Você deve informar qual remote
você está escolhendo. Podemos forçar o envio, caso os arquivos do
repositório estajam diferentes dos arquivos do computador.
gert::git_push(remote = "nome_do_remote")
gert::git_push(remote = "nome_do_remote", force = TRUE)Important
Pode ser perigoso forçar o envio. Em alguns casos, pode apagar os arquivos do repositório. Tome cuidado ao executá-lo.
Agora que enviado, vamos atualizar nossos arquivos para possíveis
mudanças feitas, usando a função git_pull(), do pacote gert.
gert::git_pull(remote = "nome_do_remote")Além destes processos padrões, existem algumas outras coisas que é possível serem feitas, que são muito úteis.
Não é incomum ocorrer erros em que arquivos que não deveriam foram
subidos por engano. Para isso, o fluxo é parecido com o mostrado
anteriormente, mas substituímos a função git_add() por git_rm(). O
mesmo processo de usar a função list.files() pode ser usado.
# Removendo
gert::git_rm(files = "script_de_analises.R")
# Commitando
gert::git_commit(message = "Removerndo o script para analisar os dados")
# Push
gert::git_push(remote = "nome_do_remote")
# Pull
gert::git_pull(remote = "nome_do_remote")Algumas vezes precisamos resetar algumas alterações, como os arquivos
adicionados e ou os commits feitos, seja porque não selecionamos
corretamente os arquivos a serem adicionados seja porque a mensagem do
commit foi feita de forma errada. Para isso, usamoas as funções
git_reset_mixed() e git_reset_soft(), respectivamente.
# Resetando os arquivos adicionados
gert::git_reset_mixed()
# Resetando o último commit feito
gert::git_reset_soft(ref = "HEAD~1")Uma medida de segurança que pode ser feita ao trabalhar com
versionamento de arquivos é não enviar os arquivos direto para a
branch main, mas sim para branches paralelas. Após conferir e
confirmar que tudo está ok, fazer um merge entre as branches. Para
criar uma nova branch, usamos a função git_branch_create(), e a função
git_branch_list() para checar as branches que existem no repositório.
# Criando a nova branch
gert::git_branch_create(branch = "nova_branch")
# Checando quais as branches existentes
gert::git_branch_list()O próximo passo é mudar de branch. Para isso, usamos a função
git_branch_ckeckout().
gert::git_branch_checkout(branch = "nova_branch")Agora todos os arquivos enviados para o seu repositório irão para a
branch paralela. Enviados aos arquivos para a branch paralela e estes
estando ok, podemos fazer o merge para a branch principal. Para isso,
precisamos mudar a branch main. Antes de qualquer operação, precisamos
checar se a branch main e branch paralela não apresentam conflitos
que podem dificultar uni-las, e como proceder. Para isso, usamos a
função git_merge_analysis(). Esta função retorna se o processo está
como Fast-forward (não há conflitos entre as branches e o merge será
automático), normal (precisará fazer um commit da merge, pois há
conflitos entre as duas branches) ou up_to_date (não há diferenças
entre as branches).
gert::git_merge_analysis("nova_branch")Agora que sabemos o que fazer, podemos continuar. Em caso de positivo
para o merge, usamos a função git_merge().
gert::git_merge("nova_branch")