Nas partes anteriores vimos o controle de versões local e o trabalho com ramos. Neste último capítulo damos o salto para os **repositórios remotos**, criamos **aliases** para ir mais rápido, guardamos alterações sem comprometê-las com o **stash** e marcamos versões com **tags**. 🎸 💾 #GITandRoll
Aviso: Este post foi traduzido para o português usando um modelo de tradução automática. Por favor, me avise se encontrar algum erro.
📚 **Esta entrada faz parte da série _Guia de Git_**, dividida em três capítulos que são lidos em ordem:
> * Parte 1: Controle de versões local
* Parte 2: Ramos
* 👉 **Parte 3: Repositórios remotos, stash e tags**
Trabalhando com repositórios remotos
Quando desenvolvemos software, normalmente não o fazemos sozinhos; costumamos trabalhar em equipe, por isso não faz sentido ter um repositório local de git, mas sim ter um repositório remoto com o qual todos trabalhemos e compartilhemos os avanços
Nota: O objetivo deste post é explicar git. Para a conexão com repositórios remotos, vou explicá-lo com GitHub porque é o serviço de hospedagem de repositórios git mais usado, mas não vou entrar em profundidade no GitHub
Clonar um repositório remoto (git clone <repositorio>)
Se começarmos a trabalhar em um repositório que já foi criado, a primeira coisa que temos de fazer é cloná-lo; para isso, o que temos de fazer é git clone <repositorio>, onde <repositorio> pode ser uma URL ou um endereço SSH. Como agora mesmo todo o tema dos grandes modelos de linguagem e ChatGPT está muito na moda, vamos clonar um repositório open source criado pela comunidade, Open-Assistant, para isso faremos git clone https://github.com/LAION-AI/Open-Assistant
InputPython!git clone https://github.com/LAION-AI/Open-Assistant.gitCopied
Clonando en 'Open-Assistant'...remote: Enumerating objects: 29769, done.remote: Counting objects: 100% (673/673), done.remote: Compressing objects: 100% (310/310), done.remote: Total 29769 (delta 398), reused 577 (delta 354), pack-reused 29096Recibiendo objetos: 100% (29769/29769), 33.61 MiB | 29.29 MiB/s, listo.Resolviendo deltas: 100% (19967/19967), listo.
Isso nos cria a pasta Open-Assistant com todo o código do repositório; podemos entrar nela e ver todo o código
InputPython!cd Open-Assistant && lsCopied
ansible deploy model safetyassets discord-bots notebooks scriptsbackend docker oasst-data setup.cfgCODEOWNERS docker-compose.yaml oasst-shared text-frontendCONTRIBUTING.md docs pyproject.toml websitecopilot inference README.mddata LICENSE redis.conf
Eliminou a pasta
InputPython!rm -r Open-AssistantCopied
Vincular um repositório local a um remoto
Se acontecer ao contrário, se primeiro começarmos a desenvolver localmente e depois quisermos sincronizar com um repositório remoto, temos de fazer o seguinte
- Primeiro, crie um repositório remoto vazio; no meu caso, criei o repositório
notebook_gitno GitHub, que depois apagarei - Obter a URL do repositório ou o endereço SSH
- Sincronizá-los por meio de
git remote add origin <URL>
O repositório vazio que criei no GitHub se vê assim
No meu caso, vou usar o endereço SSH que é git@github.com:maximofn/notebook_git.git
InputPython!cd notebook_git && git remote add origin git@github.com:maximofn/notebook_git.gitCopied
Já estão vinculados, mas para garantir podemos executar git remote -v
InputPython!cd notebook_git && git remote -vCopied
origin git@github.com:maximofn/notebook_git.git (fetch)origin git@github.com:maximofn/notebook_git.git (push)
Enviar as alterações de um repositório local para um repositório remoto (git push)
Como dissemos, eles estão vinculados, mas se eu for ao meu repositório no GitHub, ele continua aparecendo assim
O repositório local e o remoto estão vinculados, mas agora é preciso enviar todas as alterações do repositório local para o remoto; para isso, deve-se usar git push origin <rama local>:<rama remota>, ou seja, como nossa rama principal se chama main e a rama principal no GitHub se chama main, seria necessário fazer git push origin main:main.
Se você se lembra, o git por padrão chamava a branch principal de master, mas o GitHub chama por padrão a branch principal de main, então, se cada pessoa chama, no seu repositório local, suas branches de uma maneira, é necessário especificar qual branch local grava em qual branch remota
Pode-se configurar a conexão padrão entre ramos no git; para isso, é preciso fazer git push --set-upstream origin main. Isso estabelece uma relação entre a rama local main e a rama remota main. Uma vez feita essa relação, já só é necessário fazer git push para enviar as alterações feitas localmente para o servidor remoto.
De modo que estabelecemos a conexão entre ramos
InputPython!cd notebook_git && git push --set-upstream origin mainCopied
Enumerando objetos: 51, listo.Contando objetos: 100% (51/51), listo.Compresión delta usando hasta 12 hilosComprimiendo objetos: 100% (38/38), listo.Escribiendo objetos: 100% (51/51), 4.21 KiB | 2.11 MiB/s, listo.Total 51 (delta 18), reusado 0 (delta 0)remote: Resolving deltas: 100% (18/18), done.To github.com:maximofn/notebook_git.git* [new branch] main -> mainRama 'main' configurada para hacer seguimiento a la rama remota 'main' de 'origin'.
Agora já podemos fazer apenas git push para enviar as alterações locais para o repositório remoto
InputPython!cd notebook_git && git pushCopied
Everything up-to-date
Se agora voltarmos ao nosso repositório do GitHub, ele fica assim
Se fizermos um ls no nosso repositório local, poderemos ver que os arquivos que temos no repositório remoto também estão no repositório local, ou seja, sincronizamos o repositório local e o remoto
InputPython!cd notebook_git && ls -aCopied
. .. api_keys.py archivo1.py archivo2.py archivo8.py .git .gitignore
Os únicos que não estão no repositório remoto são api_keys.py, que é o que adicionámos ao ficheiro .gitignore, ou seja, o que dissemos ao git para não seguir. E .git, que é onde está a configuração do nosso repositório local e que não tem de ser enviado para o repositório remoto, porque cada pessoa terá a sua própria configuração do git e, portanto, não tem de ser sincronizada
Baixar as alterações de um repositório remoto para um repositório local (git pull)
Agora vamos fazer ao contrário, vamos baixar as novas alterações que tenham sido feitas no repositório remoto. Se observarmos como está o repositório remoto, poderemos ver que há um botão que diz Add a README, então clicamos nele para adicioná-lo
Ao clicar, um editor será aberto; deixamos o que o GitHub colocou e salvamos as alterações clicando no botão Commit changes...
Vai aparecer uma janela na qual nos pedirá uma mensagem de commit; deixamos a que vem por padrão e clicamos em Commit changes
Ao fazer isso, o repositório ficará assim
!pull do repositório git do notebook
Foi criado um novo arquivo chamado README.md, mas se executarmos ls no repositório local não o encontraremos
InputPython!cd notebook_git && ls | grep READMECopied
Como temos que trazer as alterações do repositório remoto para o local, para isso é preciso fazer git pull origin <rama remota> para indicar ao git sobre qual ramo remoto vamos trazer os dados, mas, assim como antes, podemos estabelecer uma relação entre o ramo remoto e o ramo local da seguinte forma git branch --set-upstream-to=origin/<rama local> <rama remota>, mas como nosso ramo local se chama main e o ramo remoto do GitHub também se chama main, teríamos que mudar o anterior para git branch --set-upstream-to=origin/main main.
Uma vez feito isso, para baixar as novas alterações do repositório remoto para o local, só seria necessário fazer git pull
Vamos estabelecer a relação entre branches com git branch --set-upstream-to=origin/main main
InputPython!cd notebook_git && git branch --set-upstream-to=origin/main mainCopied
Rama 'main' configurada para hacer seguimiento a la rama remota 'main' de 'origin'.
Agora podemos trazer as alterações do repositório remoto para o repositório local com git pull
InputPython!cd notebook_git && git pullCopied
remote: Enumerating objects: 4, done.remote: Counting objects: 100% (4/4), done.remote: Compressing objects: 100% (2/2), done.remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0Desempaquetando objetos: 100% (3/3), 646 bytes | 646.00 KiB/s, listo.Desde github.com:maximofn/notebook_git679bb49..527e07a main -> origin/mainActualizando 679bb49..527e07aFast-forwardREADME.md | 1 +1 file changed, 1 insertion(+)create mode 100644 README.md
Como vemos, diz que foi adicionado README.md, verificamos isso fazendo ls
InputPython!cd notebook_git && ls | grep READMECopied
README.md
Temos o arquivo localmente
Sincronizar os branches remotos e locais
Como vimos, tivemos que sincronizar os branches remotos e locais para poder enviar e baixar os dados. No entanto, se primeiro criarmos o repositório no GitHub e depois o clonarmos, já não é necessária essa sincronização.
Alias
Sempre que quisemos fazer um log, usamos este comando git log --graph --oneline --decorate, no entanto, lembrar-se deste comando é bastante complicado; na verdade, eu não me lembro dele. Cada vez que quis usá-lo, tive que procurá-lo porque não o lembrava, por isso seria ótimo ter uma maneira de o abreviar.
Para isso, o git oferece os alias, de modo que você pode criar aliases dos comandos que quiser; para isso, você tem que executar git config --global alias.<nombre del alias> "comando"
Portanto, vamos chamar git tree ao comando git log --graph --oneline --decorate, já que nos permite ver o histórico, com a bifurcação e fusão de branches como se fosse o crescimento de uma árvore, por isso fazemos git config --global alias.tree "log --graph --oneline --decorate"
**Importante**: Não é necessário colocar a palavra
gitdentro do comando
InputPython!git config --global alias.tree "log --graph --oneline --decorate"Copied
Se agora formos ao nosso repositório e executarmos git tree, veremos o histórico como fazíamos antes
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, origin/main) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Como vemos, foi criado o nosso alias
Aliases de comandos existentes do git
Podem ser criados aliases de comandos que já existem no git, de fato, é uma prática que muita gente usa, sobretudo para abreviar, por isso vamos fazer um. Vamos fazer um alias do comando git status e vamos renomeá-lo como git st da seguinte forma git config --global alias.st "status"
InputPython!git config --global alias.st "status"Copied
Vamos testar agora
InputPython!cd notebook_git && git stCopied
En la rama mainTu rama está actualizada con 'origin/main'.nada para hacer commit, el árbol de trabajo está limpio
Já temos o comando git status simplificado para git st
Aliases de comandos que não são do git
Podemos criar aliases de comandos que não sejam do git; por exemplo, porque achamos que o git precisa desse novo comando, faz-se da mesma forma, com a exceção de que o comando tem de ir precedido de !, ou seja, seria git config --global alias.<nombre del alias> "!comando"
Quando vimos os conflitos, vimos que o git nos dizia onde estavam, mas para resolvê-los temos de editar o código nós mesmos, por isso podemos criar um alias do git de forma que possamos abrir um ficheiro com o editor de texto que quisermos, no meu caso vou criar um alias que me abrirá os ficheiros com vscode, para isso tenho de fazer git config --global alias.code "!code"
InputPython!git config --global alias.code "!code"Copied
Vamos testá-lo
InputPython!cd notebook_git && git code README.mdCopied
Depois de fazer isso, foi aberto README.md no VSCode
Lista com todos os alias
No caso de não nos lembrarmos dos aliases que criámos, podemos ver a configuração global do git, mas como isso pode ser um pouco avassalador porque nos dá muita informação, podemos filtrar para que nos mostre apenas os aliases que criámos; para isso usamos git config --get-regexp ^alias\.
InputPython!git config --get-regexp ^alias.Copied
alias.tree log --graph --oneline --decoratealias.st statusalias.code !code
Obtemos os aliases que criamos
Mas ainda melhor, podemos criar um alias para obter os aliases, para isso fazemos git config --global alias.alias "config --get-regexp ^alias\."
InputPython!git config --global alias.alias "config --get-regexp ^alias."Copied
Se agora fazemos git alias
InputPython!git aliasCopied
alias.tree log --graph --oneline --decoratealias.st statusalias.code !codealias.alias config --get-regexp ^alias.
Obtemos a lista com todos os nossos aliases
Armazenar no stash (git stash)
Suponhamos que estamos trabalhando em uma branch, temos vários arquivos modificados, não fizemos commit, e por alguma razão temos que passar para outra branch. Por exemplo, estamos em uma branch desenvolvendo uma nova funcionalidade, e temos que deixá-la pela metade porque há um bug crítico na branch main
Uma solução seria fazer um commit para guardar as alterações e voltar mais tarde. Mas talvez tenhamos deixado o código pela metade e não queiramos fazer um commit. Então, para isso, foi inventado o stash, que é como um armazém, onde você deixa o seu código armazenado para depois poder recuperá-lo novamente.
É uma pilha, isso quer dizer que o último que entra é o primeiro a sair
Vamos ver como fazer isso, em primeiro lugar, criamos um novo ramo que vamos chamar new_feature
InputPython!cd notebook_git && git branch new_featureCopied
Mudamos para ela
InputPython!cd notebook_git && git switch new_featureCopied
Cambiado a rama 'new_feature'
Vamos modificar arquivo2.py e arquivo8.py
InputPython!cd notebook_git && echo "print('new_feature')" >> archivo2.py && echo "print('new_feature')" >> archivo8.pyCopied
Fazemos um git status para verificar se foram modificados
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios no rastreados para el commit:(usa "git add <archivo>..." para actualizar lo que será confirmado)(usa "git restore <archivo>..." para descartar los cambios en el directorio de trabajo)modificados: archivo2.pymodificados: archivo8.pysin cambios agregados al commit (usa "git add" y/o "git commit -a")
Vamos a colocar archivo8.py na área de staged
InputPython!cd notebook_git && git add archivo8.pyCopied
Vamos fazer novamente um git status
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)modificados: archivo8.pyCambios no rastreados para el commit:(usa "git add <archivo>..." para actualizar lo que será confirmado)(usa "git restore <archivo>..." para descartar los cambios en el directorio de trabajo)modificados: archivo2.py
Como vemos, temos dois arquivos modificados, dos quais um deles também está na área de staged. Se agora tivéssemos que mudar de branch, para não perder as alterações poderíamos fazer um commit, ou guardá-las no armazenamento stash, então vamos fazer isso último por meio de git stash
InputPython!cd notebook_git && git stashCopied
Directorio de trabajo y estado de índice WIP on new_feature: 527e07a Create README.md guardados
Se agora voltarmos a fazer git status, vejamos o que acontece
InputPython!cd notebook_git && git statusCopied
En la rama new_featurenada para hacer commit, el árbol de trabajo está limpio
Os arquivos modificados já não aparecem, é como se tivéssemos feito um commit
**Importante**: Os arquivos novos criados, que nunca foram rastreados pelo Git, não irão para o repositório, por isso com os arquivos novos é necessário, pelo menos, fazer primeiro um
git add
Se eu agora criar um arquivo novo e tentar enviá-lo para o armazenamento, ele me dará um erro
InputPython!cd notebook_git && touch archivo9.pyCopied
InputPython!cd notebook_git && git statusCopied
En la rama new_featureArchivos sin seguimiento:(usa "git add <archivo>..." para incluirlo a lo que se será confirmado)archivo9.pyno hay nada agregado al commit pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
InputPython!cd notebook_git && git stashCopied
No hay cambios locales para guardar
InputPython!cd notebook_git && git statusCopied
En la rama new_featureArchivos sin seguimiento:(usa "git add <archivo>..." para incluirlo a lo que se será confirmado)archivo9.pyno hay nada agregado al commit pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
Como vemos archivo9.py não foi guardado no repositório, portanto deveria ter sido adicionado com git add.
InputPython!cd notebook_git && rm archivo9.pyCopied
Tudo para o stash (git stash -u -a)
Como vimos, apenas são enviados para o armazenamento os arquivos aos quais o git está rastreando, mas se tivermos novos arquivos criados, ou arquivos ignorados, eles não serão enviados, então para solucionar isso podemos usar as flags -u ou --include-untracked para que enviem os novos arquivos aos quais o git ainda não fez rastreamento, e a flag -a ou --all para incluir tudo, inclusive os arquivos ignorados
Lista de armazéns (git stash list)
Como comentamos, o armazenamento atua como uma pilha, portanto, se usarmos esse armazenamento muitas vezes, na verdade vamos ter uma lista de armazenamentos, e para ver os que temos armazenados podemos usar git stash list
InputPython!cd notebook_git && git stash listCopied
stash@{0}: WIP on new_feature: 527e07a Create README.md
Como vemos, só temos uma, que nos indica o ramo (on new_feature), o último commit (Create README.md) e um identificador (527e07a)
Armazenar com descrição (git stash push -m <descrição>))
Como vimos, a lista nos devolve o ramo e o último commit, mas essa informação só nos serve para saber de onde começámos a modificar antes de guardar no histórico. Além disso, devolve-nos um identificador que não nos diz muito, por isso podemos adicionar uma primeira descrição ao stash com git stash push -m <descripción>
Primeiro fazemos um git status para ver o que temos sem commitar
InputPython!cd notebook_git && git statusCopied
En la rama new_featureArchivos sin seguimiento:(usa "git add <archivo>..." para incluirlo a lo que se será confirmado)archivo9.pyno hay nada agregado al commit pero hay archivos sin seguimiento presentes (usa "git add" para hacerles seguimiento)
Temos archivo9.py, mas lembremos que nunca foi seguido pelo git, então para incluí-lo em um stash precisamos usar a flag -u ou a flag -a, de modo que criamos um novo stash com uma descrição com o comando git stash push -u -m <descripción>
InputPython!cd notebook_git && git stash push -u -m "archivo9.py"Copied
Directorio de trabajo y estado de índice On new_feature: archivo9.py guardados
Tiramos a lista do stash
InputPython!cd notebook_git && git stash listCopied
stash@{0}: On new_feature: archivo9.pystash@{1}: WIP on new_feature: 527e07a Create README.md
Já aparece o novo de maneira muito mais clara
Recuperar o último stash (git stash pop)
Como dissemos, o stash é uma pilha com armazenamentos, então, na hora de recuperá-los, faremos isso da mesma forma que uma pilha, recuperando sempre o último.
Para recuperar o último stash, temos que fazer git stash pop
Primeiro fazemos um git status para ver se não temos nenhuma alteração pendente
InputPython!cd notebook_git && git statusCopied
En la rama new_featurenada para hacer commit, el árbol de trabajo está limpio
Agora recuperamos o último stash
InputPython!cd notebook_git && git stash popCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)nuevos archivos: archivo9.pyDescartado refs/stash@{0} (0246b0e922f654e7fc68cfeaf26e24fc511feb37)
Se voltarmos a executar git status, veremos que voltamos a ter arquivo9.py pendente de fazer um commit
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)nuevos archivos: archivo9.py
E se verificarmos a lista de stash, veremos que agora só temos um.
InputPython!cd notebook_git && git stash listCopied
stash@{0}: WIP on new_feature: 527e07a Create README.md
Eliminar um stash (git stash drop <posição>)
Se queremos eliminar um stash, temos que fazer git stash drop <posição>, onde <posição> é a posição que o stash ocupa na lista.
Obtemos a lista dos stashs
InputPython!cd notebook_git && git stash listCopied
stash@{0}: WIP on new_feature: 527e07a Create README.md
No nosso caso, temos apenas um e na posição 0 (stash@{0}), então para eliminá-lo teríamos que fazer git stash drop 0; no entanto, não vou fazer isso porque vou eliminá-lo agora depois com outro comando
Eliminar todos os stashes (git stash clear)
Se queremos esvaziar a lista inteira de stash, temos que fazer git stash clear
InputPython!cd notebook_git && git stash clearCopied
Se agora pedimos a lista de stash
InputPython!cd notebook_git && git stash listCopied
Não obtemos nada porque eliminamos tudo
Vamos deixar tudo como estava, fazemos um git status para lembrar as alterações que tínhamos pendentes
InputPython!cd notebook_git && git statusCopied
En la rama new_featureCambios a ser confirmados:(usa "git restore --staged <archivo>..." para sacar del área de stage)nuevos archivos: archivo9.py
Vemos que estamos na rama new_feature e que temos archivo9.py pendente de fazer um commit. Como o criamos para o exemplo, o eliminamos e voltamos para a rama principal
InputPython!cd notebook_git && git reset archivo9.pyCopied
InputPython!cd notebook_git && rm archivo9.pyCopied
InputPython!cd notebook_git && git switch mainCopied
Cambiado a rama 'main'Tu rama está actualizada con 'origin/main'.
Tags
Quando estamos desenvolvendo código, chegam momentos em que geramos versões, por exemplo v1.1, v1.2, etc. Para ter isso mais controlado, o Git nos fornece as tags.
Criar uma nova tag (git tag -a <nome_da_tag> -m "<mensagem>")
Para criar uma tag temos que fazer git tag -a <nombre_de_etiqueta> -m "<mensaje>"
Por exemplo, vamos criar uma tag na versão atual do repositório, para isso farei git tag -a v_tag -m "Tag con el repositorio en la parte final, en la que explicamos los tags"
InputPython!cd notebook_git && git tag -a v_tag -m "Tag con el repositorio en la parte final, en la que explicamos los tags"Copied
Lista de tags (git tag)
Para ver as tags que criamos, podemos fazer git tag
InputPython!cd notebook_git && git tagCopied
v_tag
Criar uma tag de um commit antigo (git tag -a <nome_da_etiqueta> -m "<mensagem>" <hash>)
Vamos fazer um git tree para ver o histórico
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Embora isso não esteja indicado na descrição, quando fizemos o commit 4bb9d75 foi quando terminámos a parte de controlo de versões de forma local, pelo que também seria bom ter uma tag desse momento. Para isso, o que temos de fazer é criar uma tag adicionando o hash desse momento
InputPython!cd notebook_git && git tag -a v_local -m "Tag con el repositorio en la parte de control de versiones de manera local" 4bb9d75Copied
Se agora fizermos uma lista das tags, aparece a nova
InputPython!cd notebook_git && git tagCopied
v_localv_tag
E se vemos o histórico de commits
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
No ponto do histórico em que criámos a tag, agora aparece a tag que criámos * 4bb9d75 (tag: v_local, new_branch) Commit com o arquivo 7
Mudar entre tags (git reset --hard <tag> ou git reset --soft <tag>)
Assim como podemos nos mover entre diferentes commits do histórico, também podemos nos mover entre tags. Isso tem a vantagem de que podemos ir para outro momento do histórico sem precisar saber o hash; sabendo o nome da tag que definimos naquele momento, podemos nos mover simplesmente fazendo git reset --hard <tag> ou git reset --soft <tag>
Primeiro vamos fazer um ls para ver os arquivos que temos
InputPython!cd notebook_git && lsCopied
api_keys.py archivo1.py archivo2.py archivo8.py README.md
Fazemos também um git tree para ver em que momento do histórico estamos
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Agora passamos ao ponto em que criamos a tag v_local por meio de git reset --hard v_local
InputPython!cd notebook_git && git reset --hard v_localCopied
HEAD está ahora en 4bb9d75 Commit con el archivo 7
Se agora fizermos novamente um ls, vemos que não temos os mesmos arquivos
InputPython!cd notebook_git && lsCopied
api_keys.py archivo1.py archivo2.py archivo4.py archivo7.py hola.py
Se também olharmos o histórico, vemos que mudámos de momento do histórico
InputPython!cd notebook_git && git treeCopied
* 4bb9d75 (HEAD -> main, tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py
Para voltar ao último momento do histórico, como também criamos uma tag, bastará fazer git reset --hard v_tag
InputPython!cd notebook_git && git reset --hard v_tagCopied
HEAD está ahora en 527e07a Create README.md
Voltamos a ver o histórico para verificar que retornamos ao último momento do histórico
InputPython!cd notebook_git && git treeCopied
* 527e07a (HEAD -> main, tag: v_tag, origin/main, new_feature) Create README.md* 679bb49 archivo1.py con el merge resuelto|\| * 32851c3 archivo1.py en rama rama_con_conflicto* | 53f909b archivo1.py en rama main|/* 52acb97 Merge squash de los commits de la rama branch_squash* 274529c Merge branch 'branch_no_fast_forward' into main|\| * 8df3429 (branch_no_fast_forward) file2| * e4e23c9 file1* | 8bdf4d8 file3|/* 94149fc (branch_fast_forward) Eliminado hola.py* 4484e70 Eliminado archivo4.py* 564ccfb (new_branch2) Commit con el archivo 8* 5168f78 Eliminado archivo7.py* 4bb9d75 (tag: v_local, new_branch) Commit con el archivo 7* ea615a9 Eliminado archivo5.py* e3153a5 Commit con los archivos 4 y 5* 0b09cfa Añadido .gitignore* 04ebd1f Commit con los archivos 1 y 2* c4930d7 Tercer commit, hola.py* 6e99e73 Segundo commit, hola.py* 1c95e4f Primer commit, hola.py