Git
Workshop
Git...
- Sistema de controle de versão Distribuído (DSCS).
- Ferramenta Open Source
- Desenvolvida por Linus Tovals para o Kernel do Linux (2005).
- Foco na velocidade, integridade dos dados
Descentralizado...
.. mas centralizado
Descentralizado...
.. mas centralizado
Entendendo o Git
Os espaços...
Os espaços...
Remote
Local
Os espaços...
Remote
Local
Upstream
Repository
Local
Repository
...
Os espaços...
Remote
Local
Upstream
Repository
Local
Repository
Workspace
...
...
Os espaços...
Remote
Local
Upstream
Repository
Local
Repository
Index
(Staging)
Workspace
...
Os espaços...
Remote
Local
Upstream
Repository
Local
Repository
Index
(Staging)
Workspace
Stash
Os espaços...
Ciclo de vida dos arquivos
Sempre trabalhamos com branches, e criamos marcações, chamadas de tags
Branches!!
git init
Inicia um repositório local git
git add
Adiciona um arquivo na área de staging
git commit
Adiciona os arquivos da área de stagins para o seu repositório local
git status
Mostra a situação atual dos arquivos do seu repositório
$ git status
No ramo feature/nova_feature
Changes not staged for commit:
(utilize "git add <arquivo>..." para atualizar o que será submetido)
(utilize "git checkout -- <arquivo>..." para descartar mudanças no diretório de trabalho)
modificado: teste2.txt
Arquivos não monitorados:
(utilize "git add <arquivo>..." para incluir o que será submetido)
.project
novo_arquivo.txt
nenhuma modificação adicionada à submissão (utilize "git add" e/ou "git commit -a")
$ cat my-project/.gitignore
# Ignore modeulos, demas e vendor
/core
/modules
/themes
/vendor
# Ignora arquivos de configurações
sites/*/settings*.php
sites/*/services*.yml
# Ignora arquivos privados
sites/*/files
sites/*/private
# Ignora todos diretórios, exceto um
/some-dir/*
!/some-dir/dont-ignore-me.txt
.gitignore
Arquivos que devem ficar ocultos do git
$ git log
commit 5e31a9080c7f0a9b0390cd7dd2aa8e59a28a7328
Author: Yves Laroche <yves.laroche@logicnow.com>
Date: Tue Feb 2 20:02:08 2016 +0000
My first commit
# Short
$ git log --oneline
5e31a90 My first commit
# Limit number of commits
$ git log -10
$ git log --since=1.week
$ git log --after='2016-01-10'
git log
Arquivos que devem ficar ocultos do git
RM e MV
$ git rm my-first-file
rm 'my-first-file'
$ git status
On branch my-new-feature
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: my-first-file
$ git status
On branch my-new-feature
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: my-first-file -> other-name
Let's Git !!!
> mkdir repo1
> cd repo1
> ls -la
total 8
drwxrwxr-x 2 asp asp 4096 jun 5 13:28 .
drwxrwxr-x 3 asp asp 4096 jun 5 13:28 ..
> git init
Initialized empty Git repository in /home/asp/repositories/repo1/.git/
> ls -la
total 12
drwxrwxr-x 3 asp asp 4096 jun 5 13:28 .
drwxrwxr-x 3 asp asp 4096 jun 5 13:28 ..
drwxrwxr-x 7 asp asp 4096 jun 5 13:28 .git
... e criar um arquivo:
> cat > file.txt
this is a file
^C
> ls -la
total 16
drwxrwxr-x 3 asp asp 4096 jun 5 13:30 .
drwxrwxr-x 3 asp asp 4096 jun 5 13:28 ..
-rw-rw-r-- 1 asp asp 15 jun 5 13:30 file.txt
drwxrwxr-x 7 asp asp 4096 jun 5 13:28 .git
iniciar um repositório local...
> git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
file.txt
nothing added to commit but untracked files present (use "git add" to track)
>
... indexar o novo arquivo...
> git add file.txt
> git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: file.txt
>
...Verificar o status do Repositório...
> git config user.name "Your name here"
> git config user.email "your@email.here"
Antes do primeiro commit...configurar a sua conta
Esta informação é usada para saber qual usuário fez em cada commit
> git commit -m "New file file.txt"
[master (root-commit) d87946f] New file file.txt
1 file changed, 1 insertion(+)
create mode 100644 file.txt
> git status
On branch master
nothing to commit, working directory clean
>
... e ver o histórico do nosso repositório:
> git log
commit d87946fa2d170113dcbda46d4b095a1a30e852ca
Author: acanimal <fabio.nowaki@bcash.com.br>
Date: Mon Feb 20 13:38:27 2016 +0200
New file file.txt
... vamos fazer o primeiro commit...
... e com um pouco mais de detalhes:
> git log --decorate=full --name-status
commit d87946fa2d170113dcbda46d4b095a1a30e852ca (HEAD, refs/heads/master)
Author: fabio.nowaki <fabio.nowaki@bcash.com.br>
Date: Mon Feb 20 13:38:27 2016 +0200
New file file.txt
A file.txt
git status, mostra o status da árvore de trabalho
git log, mostra o histórico de mudanças através de logs dos commits
git status VS git log
... criar novo arquivo "other.txt", modificar o existente "file.txt" e verificar o status novamente:
> git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
other.txt
no changes added to commit (use "git add" and/or "git commit -a")
... adicionar o novo arquivo "other.txt" para o índice:
> git add other.txt
> git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: other.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file.txt
... Indexar e comitar as mudanças no mesmo tempo:
> git commit -am "Added new file other.txt"
[master a709c60] Added new file other.txt
2 files changed, 2 insertions(+)
create mode 100644 other.txt
> git status
On branch master
nothing to commit, working directory clean
... ver o histórico:
> git log --decorate=full --name-status
commit a709c60d5c885beeeaf2a7d6fd6f129dbeead216 (HEAD, refs/heads/master)
Author: fabio.nowaki <fabio.nowaki@bcash.com.br>
Date: Fri Jun 5 15:59:05 2015 +0200
Added new file other.txt
M file.txt
A other.txt
commit d87946fa2d170113dcbda46d4b095a1a30e852ca
Author: fabio.nowaki <fabio.nowaki@bcash.com.br>
Date: Fri Jun 5 13:38:27 2015 +0200
New file file.txt
A file.txt
Resumo
Trabalhando com branches
git branch
Permite criar, listar, renomear e deletar branches
$ git branch
develop
* feature/nova_feature
master
$ git branch 'projeto1'
Cria uma nova branch chamada projeto1
git checkout
Permite alternar entre branches criadas pelo git branch
$ git checkout 'projeto1'
Altera seu diretório de trabalho para a branch
> git branch projeto1
> git checkout projeto1
> git checkout -b projeto1
... é o mesmo que ...
git merge
Permite fazer o merge entre brenches
$ git branch master
Alternar para a branch master
$ git merge --no-ff 'projeto1'
Mergea as alterações da branch 'projeto1' para a 'master
Let's Git !!!
Por padrão, quando criamos um repositório, o Git cria uma branch master:
> git branch
* master
Vamos criar uma branch para corrigir um Bug:
> git branch bug01
> git branch
bug01
* master
Estamos trabalhando na branch master, vamos mudar nossa working branch para a branch bug01 :
> git checkout bug01
Switched to branch 'bug01'
> git branch
* bug01
master
> cat > file_on_bug01.txt
fix the bug
^C
> git status
On branch bug01
Untracked files:
(use "git add <file>..." to include in what will be committed)
file_on_bug01.txt
nothing added to commit but untracked files present (use "git add" to track)
... criar um novo arquivo para resolver o bug...
...adicionar arquivo e comitar:
> git add file_on_bug01.txt
> git status
On branch bug01
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: file_on_bug01.txt
> git commit -am "Bug fixed"
[bug01 776d7ee] Bug fixed
1 file changed, 1 insertion(+)
create mode 100644 file_on_bug01.txt
> git status
On branch bug01
nothing to commit, working directory clean
> git status
On branch bug01
nothing to commit, working directory clean
> ls -l
total 12
-rw-rw-r-- 1 asp asp 12 jun 11 12:08 file_on_bug01.txt
-rw-rw-r-- 1 asp asp 17 jun 5 15:55 file.txt
-rw-rw-r-- 1 asp asp 21 jun 5 15:54 other.txt
...mudar para master e listar os arquivos:
> git checkout master
Switched to branch 'master'
> ls -l
total 8
-rw-rw-r-- 1 asp asp 17 jun 5 15:55 file.txt
-rw-rw-r-- 1 asp asp 21 jun 5 15:54 other.txt
Listar arquivos na branch bug01:
> git merge bug01
Updating a709c60..776d7ee
Fast-forward
file_on_bug01.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 file_on_bug01.txt
... e listar os arquivos:
> ls -l
total 12
-rw-rw-r-- 1 asp asp 12 jun 11 15:16 file_on_bug01.txt
-rw-rw-r-- 1 asp asp 35 jun 11 13:48 file.txt
-rw-rw-r-- 1 asp asp 21 jun 5 15:54 other.txt
Agora vamos fazer o merge da bug01 para master
E deletar a branch bug01
> git branch -d bug01
Deleted branch bug01 (was 776d7ee).
Vamos criar uma branch bug02 e modificar a primeira linha do arquivo file.txt e comitar a alteração:
> git checkout master
Switched to branch 'master'
> vi file.txt
> git commit -am "Added new line on file.txt at master"
[master 3c07391] Added new line on file.txt at master
1 file changed, 1 insertion(+)
> git checkout -b bug02
Switched to a new branch 'bug02'
> git branch
* bug02
master
>
> vi file.txt
>
> git commit -am "Modified file.txt on bug02"
[bug02 fa2a1b4] Modified file.txt on bug02
1 file changed, 1 insertion(+)
Vá para a branch master e modifica o file.txt também:
Fácil? Vamos gerar um conflito!!!
Tente mergear a bug02 na master:
> git branch
bug02
* master
> git merge bug02
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.
> more file.txt
<<<<<<< HEAD
New line at 'master'
=======
New line here at 'bug02'.
>>>>>>> bug02
this is a file
.
Vamos verificar o git status ?
> git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: file.txt
no changes added to commit (use "git add" and/or "git commit -a")
Edit file.txt, resolve conflicts and try again:
> vi file.txt
> more file.txt
New line at 'master'
New line here at 'bug02'.
this is a file
> git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: file.txt
no changes added to commit (use "git add" and/or "git commit -a")
Execute git add para indicar que os conflitos foram resolvidos e comite:
> git add file.txt
> git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
nothing to commit, working directory clean
> git commit -am "Merge done"
[master cb2da7c] Merge done
> git status
On branch master
nothing to commit, working directory clean
Criar tag
# Mostrar todas as tags
> git tag
# Criar um tag
> git tag -a 0.1.0 -m 'Release 0.1.0 do projeto'
# Checkout de uma tag específica
> git checkout -b 0.1.0
# Criar branch da tag
> git checkout -b hotfix-0.1.1 0.1.0
Switched to a new branch 'hotfix-0.1.1'
Resumo
Repositórios Remotos
Remoto
- Repositório de sincronização
- Necessário para trabalhar de forma colaborativa
- Nós fazemos push/pull dos dados do repositório remoto para repositório local
Local
Remote (origin)
Lembrando os espacos...
Remote
Local
Upstream
Repository
Local
Repository
Index
(Staging)
Workspace
Stash
git clone
Cria uma cópia de um respositório git
$ git clone git@git.bcash.com.br/bcash/api.git
git push
Envia os commits do seu repositório local para o repostiório remoto
$ git push origin master
git fetch
Importa somente os índices do repositório remoto para seu repositório local
Não é executado merge no seu código
$ git fetch origin
git pull
Importa os commits do repositório remoto para seu repositório local e faz o merge no seu diretório de trabalho atual
$ git pull
git pull é o mesmo que:
$ git fetch origin
$ git merge
git push
Transferir os commits do repositório local para o repositório remoto
$ git push origin master
git remote
Especifica um repositório remoto para seu repositório local
$ git remote add origin https://git.bcash.com.br/fabio.nowaki/teste.git
Let's Git !!!
Adicionar um repositório remoto para um projeto local:
> git remote add origin https://git.bcash.com.br/fabio.nowaki/teste.git
> git remote
origin
> git remote -v
origin https://git.bcash.com.br/fabio.nowaki/teste.git (fetch)
origin https://git.bcash.com.br/fabio.nowaki/teste.git (push)
>
> git push origin master
Username for 'https://git.bcash.com.br': fabio.nowaki
Password for 'https://fabio.nowaki@git.bcash.com.br':
Counting objects: 17, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (17/17), 1.45 KiB | 0 bytes/s, done.
Total 17 (delta 3), reused 0 (delta 0)
To https://git.bcash.com.br/fabio.nowaki/teste.git
* [new branch] master -> master
>
Push para "origin" da nossa branch "master" :
> git clone https://git.bcash.com.br/fabio.nowaki/teste.git test
Cloning into 'test'...
Username for 'https://git.bcash.com.br': fabio.nowaki
Password for 'https://fabio.nowaki@git.bcash.com.br':
remote: Counting objects: 23, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 23 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (23/23), done.
Checking connectivity... done.
...e veja as nossas branches e as configurações remotas:
> git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/fix01
remotes/origin/master
> git remote -v
origin https://git.bcash.com.br/fabio.nowaki/teste.git (fetch)
origin https://git.bcash.com.br/fabio.nowaki/teste.git (push)
Vá para outra pasta e clone o repositório remoto:
git clone...
- Configura uma origin remota
- Baixa a branch master
Crie o arquivo file02.txt, comita e de um push para o repositório remoto:
> vi file02.txt
> git add file02.txt
> git commit -m "New file 02"
[master d78e486] New file 02
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file02.txt
> git push
Username for 'https://git.bcash.com.br': fabio.nowaki
Password for 'https://fabio.nowaki@git.bcash.com.br':
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 337 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://git.bcash.com.br/fabio.nowaki/teste.git
720262a..d78e486 master -> master
Retorne para a pasta anterior (pasta do repositório inicial), adicione um novo arquivo, comite e tenta dar o push:
> git push origin master
Password for 'https://git.bcash.com.br/':
To https://git.bcash.com.br/fabio.nowaki/teste.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://git.bcash.com.br/fabio.nowaki/teste.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Repositório remoto foi alterado. Precisamos baixar e mergear com nossa branch local:
> git pull origin master
Password for 'https://git.bcash.com.br':
From https://git.bcash.com.br/fabio.nowaki/teste.git
* branch master -> FETCH_HEAD
Merge made by the 'recursive' strategy.
file02.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file02.txt
Não há conflitos... Então agora nós podemos fazer push da nossa branch:
> git push origin master
Password for 'https://git.bcash.com.br':
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 556 bytes | 0 bytes/s, done.
Total 5 (delta 2), reused 0 (delta 0)
To https://git.bcash.com.br/fabio.nowaki/teste.git
d78e486..4c15a4e master -> master
Criar tag e enviar para o repositório remoto
# Mostrar todas as tags
$ git tag
# Criar um tag
$ git tag -a 0.1.0 -m 'Release 0.1.0 do projeto'
# Tags não são 'pushed' por padrão
$ git push origin 0.1.0
# Push todas tags
$ git push origin --tags
# Checkout de uma tag específica
$ git checkout -b 0.1.0
Problema em produção?
# Criar branch da tag
> git checkout -b hotfix-0.1.1 0.1.0
Switched to a new branch 'hotfix-0.1.1'
Gitflow
- Nós podemos usar muitos workflow's diferentes quando trabalhamos com git: workflow centralizado, workflow de feature branch, ...
- Gitflow é baseado em um um modelo de branch de sucesso criado por Vincent Driessen.
O gitflow workflow...
- Define um modelo de branch
- Atribui regras especificas para diferentes branches e define como e quando ela deve ser interagida.
Gitflow branches
- master
- develop
- feature
- release
- hotfix
Branch: master
Branch de release e estável, então nós devemos gerar tags através da master.
Branch: develop
Atua como branch de integração das novas features.
Branch: feature
- Cada nova feature deve ter uma própria branch
- Quando o desenvolvimento da feature finalizar, deve ser integrada de volta para a develop
- Features nunca devem ser desenvolvidas direto na master
Branch: release
Uma vez finalizado o desenvolvimento das features e é planejado um deploy:
- Criar uma branch release da branch develop
- Neste ponto deve ser feito o teste de regressão
- Nenhuma nova feature pode ser adicionado a partir deste ponto. Somente corrigido bug, documentação, etc..
Uma vez pronto para o deploy:
- Mergear com a master e criar uma tab com o número da versão (Ex. 16.5.0)
- Mergear de volta para develop, pois algo pode ter sido alterado desde a criação da branch
Branch: hotfix
- Manutenção ou “hotfix” branches são usadas para corrigir bugs emergenciais em produção
- A branch deve ser criada da master
- Após a correção, ela deve ser mergeada de volta para a master e develop (ou uma branch release, se estiver alguma)
- Criar uma tag da master com o número da versão (ex. 16.4.1)
Workflow
Let's Git !!!
master
# Cria novo repositório
$ git init
# Clonar repositório
$ git clone git@git.bcash.com.br:bcash/api.git
git
develop
# Iniciar desenvolvimento na branch
$ git checkout -b develop master
git
# Inicializar flow
$ git flow init
git flow
feature
# Cria a branch nova-feature com base na develop
$ git checkout -b feature/nova-feature
# Faz o merge da nova-feature para a develop
$ git checkout develop
$ git merge --no-ff feature/nova-feature
# Deleta a branch nova-feature
$ git branch -d feature/nova-feature
# Envia as alterações da branch develop para o repositório remoto
$ git push origin develop
git
# Cria a branch e faz o checkout dela
$ git flow feature start nova-feature
# Faz o merge para a master/develop, deleta a branch
# e faz push para o remoto
$ git flow feature finish nova-feature
git flow
release
# Cria a release branch 2.3.0 com base na develop
$ git checkout -b release/2.3.0 develop
# Faz o merge da branch release 2.3.0 para a master
$ git checkout master
$ git merge --no-ff release/2.3.0
# Gera a tag
$ git tag -a v2.3.0
# Faz o merge da branch release 2.3.0 para a develop
$ git checkout develop
$ git merge --no-ff release/2.3.0
# Deleta a branch 2.3.0
$ git branch -d release/2.3.0
git
# Cria a branch e faz o checkout dela
$ git flow release start 2.3.0
# Faz o merge para a master/develop, deleta a branch
# e faz push para o remoto
$ git flow release finish 2.3.0
git flow
hotfix
# Cria branch para resolver bug emergencial baseado na master
$ git checkout -b hotfix/2.3.7 master
# Após correção, faz merge da branch hotfix para a master
$ git checkout master
$ git merge --no-ff hotfix/2.3.7
# Gera tag baseado na master
$ git tag -a 2.3.7
# Faz o merge da branch hotfix para a develop
$ git checkout develop
$ git merge --no-ff hotfix/2.3.7
# Deleta a branch hotfix
$ git branch -d hotfix/2.3.7
git
# Cria a branch e faz o checkout dela
$ git flow hotfix start 2.3.7
# Faz o merge para a master/develop, deleta a branch,
# faz push para o remoto, e gera a tag
$ git flow hotfix finish 2.3.7
git flow
Referências
Obrigado
Git - Introdução
By Fabio Nowaki
Git - Introdução
A short introduction to Git.
- 2,101