LAB – Compreendendo o Git

07 jan

LAB – Compreendendo o Git

Design sem nome (2)

Introdução

Git é um sistema de controle de versões distribuído, geralmente utilizado no desenvolvimento de softwares, podendo ser utilizado para registrar o histórico de edições de qualquer tipo de arquivo. Foi desenvolvido por Linus Torvalds em 2005 para o desenvolvimento do kernel do Linux. É um software livre e de código aberto distribuído sob os termos da GNU GPLv2.

Um sistema distribuído de controle de versões tem como finalidade gerenciar diferentes versões de um projeto, onde os clientes não somente usam o estado mais atual dos arquivos, eles duplicam todo o repositório localmente. Assim se qualquer servidor ficar inoperante, qualquer um dos clientes pode ser utilizado para copiar de volta para outro servidor o repositório “perdido”.

Figura 1 - Sistema distribuído de controle de versões

O sistema Git trabalha com o conceito de repositório, onde é informado ao Git que um determinado repositório e seus arquivos terão suas versões controladas. Para isso é criado um snapshot para a versão inicial de todos os arquivos contidos no repositório. Assim toda vez que é feito um commit ou o estado do projeto é salvado no Git, ele basicamente tira um snapshot de como todos os arquivos se parecem naquele instante e armazena uma referência desse snapshot.

Para ser eficiente, se os arquivos não forem alterados, o Git não armazena o arquivo novamente, apenas cria um ponteiro para o arquivo idêntico já armazenado.

Figura 2 - Fluxo de trabalho do Git

Utilizando o Git

Para utilizar o Git é necessário realizar o download do mesmo no site oficial https://git-scm.com/downloads, de acordo com seu sistema operacional, os seguintes sistemas são suportados Mac OS X, Windows, Linux e Unix.

Será utilizado o sistema operacional Oracle Linux 7.6 e Git versão 1.7.1.

yum -y install git

1. Configuração inicial do Git

git config --global user.name "Dataunique Tecnologia"
git config --global user.email "[email protected]"
git config --global core.editor vim

2. Criando e iniciando um repositório

mkdir /root/lab-git

cd lab-git

git init

3. Entendo o ciclo de vida dos arquivos

Um arquivo no seu repositório pode estar em um dos dois status:

Untracked – São arquivos que não fazem parte do seu último snapshot e não foram adicionados no Git;

Tracked – São arquivos que estavam no seu último snapshot, ou seja, são reconhecidos pelo Git e podem ter o status de unmodified, modified ou staged.

De forma resumida um arquivo é criado no repositório ficando com o status unatracked, depois de ser adicionado ao Git ele passa o status tracked staged (pronto para o commit), após o arquivo ser editado seu status muda para tracked modified. Após o commit o arquivo muda o status para tracked unmodified.

Figura 3 - Ciclo de vida do status dos arquivos

Quando se cria um commit, o Git calcula o checksum de cada subdiretório e armazena os objetos de árvore no repositório

do Git. Em seguida é criado um objeto commit que tem os metadados e um ponteiro para a árvore do projeto raiz.

  • O repositório Git passa a ter cinco objetos:
  • Um blob para o conteúdo de cada um dos arquivos;
  • Uma árvore (tree) que lista o conteúdo do diretório e especifica quais nomes de arquivos são armazenados em cada blob;

Um commit com o ponteiro para a raiz dessa árvore com todos os metadados do commit. Este procedimento gera uma estrutura similar a Figura 4.

Figura 4 - Modelo conceitua de um commit

 

3.1 Adicionando o arquivo ao Git

git status

# On branch master
#
# Initial commit
# nothing to commit (create/copy files and use "git add" to track

echo "#Lab Git" > Readme.md

git status

# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# Readme.md

nothing added to commit but untracked files present (use "git add" to track)

git add Readme.md

git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: Readme.md
#

3.2 Modificando um arquivo

echo "Lab sobre comandos básicos do git" >> Readme.md

git status

# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached ..." to unstage)
#
# new file: Readme.md
#
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: Readme.md
#

git add Readme.md

git status

# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached ..." to unstage)
#
# new file: Readme.md
#
git commit –m "Adicionado o arquivo Readme.md"

[master (root-commit) 1c64768] Adicionado o arquivo Readme.md 1 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 Readme.md

git status

# On branch master nothing to commit (working directory clean)

Para tornar esse processo mais ágil, digite o comando git commit -am "Com seu comentário" os arquivos modificados serão atualizados para a nova versão.

Após as modificações serem feitas, o novo commit armazenará um ponteiro para o commit imediatamente anterior. Conforme ilustrado na Figura 5.

Figura 5 - Dados para múltiplos commits.

4. Verificando as modificações realizadas e corrigindo erros

O comando git diff é utilizado para verificar o que foi modificado no arquivo, caso algo tenha ficado errado e necessário desfazer as alterações, utilize o comando git checkout. O único detalhe neste processo é que ele deve ser feito antes da realização do git commit.

echo "Linha 1" &gt; Readme.md
git add Readme.md
git commit -m "Primeira linha"

[master (root-commit) 10c0770] Premeira linha
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 Readme.md

echo "Linha 2" >> Readme.md
git diff

diff --git a/Readme.md b/Readme.md
index 5f9afb6..d753973 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1 +1,2 @@
Linha 1</span>
+Linha 2</span>

git checkout Readme.md
git diff
git status

# On branch master
nothing to commit (working directory clean)

Caso tenha feito a modificação e realizado o commit, o procedimento para reverter está modificação deve ser feito utilizando o comando git reset, selecionando entre as opções --soft, --mixed ou --hard. Onde:

  • --soft – Reverte o commit e deixa os arquivos no status stated;
  • --mixed – Reverte o commit e deixa os arquivos no status modified;
  • --hard – Reverte o commit e ignora todas as modificações feitas.
echo "Linha 2" >> Readme.md
git commit -am "Inserindo segunda linha"
[master fc0a075] Inserindo segunda linha
1 files changed, 1 insertions(+), 0 deletions(-)

git log

commit fc0a0756cd9e2f1468aa11889c8b15a4391a9853
Author: Dataunique\ Tecnologia [email protected]
Date: Sat Dec 15 16:51:18 2018 -0200
Inserindo segunda linha</span>

commit 10c07703ac6caf8335e8687c1b1ccd2e4898417b
Author: Dataunique\ Tecnologia [email protected]
Date: Sat Dec 15 16:15:49 2018 -0200
Primeira linha

git show fc0a0756cd9e2f1468aa11889c8b15a4391a9853

commit fc0a0756cd9e2f1468aa11889c8b15a4391a9853
Author: Dataunique\ Tecnologia [email protected]
Date: Sat Dec 15 16:51:18 2018 -0200
Inserindo segunda linha

diff --git a/Readme.md b/Readme.md
index 5f9afb6..d753973 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1 +1,2 @@
Linha 1
+Linha 2

git reset --soft 10c07703ac6caf8335e8687c1b1ccd2e4898417b
git diff
git status

# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: Readme.md
#

git commit -m "Nova Linha"

[master a581e79] Nova Linha
1 files changed, 1 insertions(+), 0 deletions(-)

git log

commit a581e7984b4d16537c85ee91d08b47a5151a506d
Author: Dataunique\ Tecnologia [email protected]
Date: Sat Dec 15 17:01:04 2018 -0200
Nova Linha

commit 10c07703ac6caf8335e8687c1b1ccd2e4898417b
Author: Dataunique\ Tecnologia [email protected]
Date: Sat Dec 15 16:15:49 2018 -0200
Primeira linha

git reset --mixed 10c07703ac6caf8335e8687c1b1ccd2e4898417b

Unstaged changes after reset:
M Readme.md

git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: Readme.md
#
no changes added to commit (use "git add" and/or "git commit -a"

git diff

diff --git a/Readme.md b/Readme.md
index 5f9afb6..d753973 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1 +1,2 @@
Linha 1
+Linha 2

git commit -am "Mais uma vez"

[master 27d1893] Mais uma vez 1 files changed,
1 insertions(+), 0 deletions(-)

git log

commit 27d189310d29984b3ac09bd961942944352ad50b
Author: Dataunique\ Tecnologia [email protected]
Date: Sat Dec 15 17:06:53 2018 -0200
Mais uma vez

commit 10c07703ac6caf8335e8687c1b1ccd2e4898417b
Author: Dataunique\ Tecnologia [email protected]
Date: Sat Dec 15 16:15:49 2018 -0200
Primeira linha

git reset --hard 10c07703ac6caf8335e8687c1b1ccd2e4898417b

HEAD is now at 10c0770 Primeira linha

git diff
git log

# On branch master
nothing to commit (working directory clean)

5. Branch

O termo Branch significa dizer que o projeto irá divergir da linha principal de desenvolvimento, possibilitando a implementação de novas funcionalidades, correções de bug ou até mesmo um novo fluxo de trabalho. Um branch no Git é um ponteiro móvel que aponta para um determinado commit, sendo master o nome do branch padrão do Git.

Para criar um branch basta digita o comando git branch “nome do branch”, a Figura 6 ilustra o branch “testing que aponta para o mesmo commit do branch master. Para o Git saber em qual branch você está trabalhando, ele utiliza um ponteiro especial chamado Head.

Figura 6 - Head apontando para o branch atual.

git branch testing
git branch

* master
testing

git checkout testing
git branch

master
* testing

echo "Linha 3" >> Readme.md
git commit -am "Nova linha no Readme.md"

git log --graph

[root@srvtower01 lab-git]# git log --graph

* commit 3e3bc9f68e75d80291a651bf3bd879928c0e5769
| Author: Dataunique Tecnologia [email protected]
| Date: Mon Dec 17 17:23:20 2018 -0200
|
| Nova linha no Readme.md
|
* commit aafc335484f0c66cafd3d70b12a353c1658591dc
Author: Dataunique Tecnologia [email protected]
Date: Mon Dec 17 17:11:55 2018 -0200
Commit inicial

git checkout master

Switched to branch 'master'

git log --graph

commit aafc335484f0c66cafd3d70b12a353c1658591dc
Author: Dataunique Tecnologia [email protected]
Date: Mon Dec 17 17:11:55 2018 -0200
Commit inicial

Após ter realizado as operações acima, teremos um cenário próximo ao ilustrado na Figura 7.

Figura 7 - O Head retorna ao branch master.


5.1 Branch e Merge Básico

O merge é utilizado para unir branch e unificar dois fluxos de trabalhos distintos. Continuando o exemplo anterior, iremos criar um novo commit no branch master e posteriormente uni-lo, conforme ilustrado na Figura 8.

Figura 8 - Merge básico.

git checkout master
echo "Outro arquivo" &gt; Arquivo.txt
git add Arquivo.txt
git commit -m "Adicionado o arquivo.txt"
git merge testing
git log --graph

* commit 5b05e635bb11533df1160e18a25d5421910a7e70
|\ Merge: fc8e187 3e3bc9f
|| Author: Dataunique Tecnologia [email protected]
| | Date: Mon Dec 17 21:43:40 2018 -0200
| |
| | Merge branch 'testing'
| |
| * commit 3e3bc9f68e75d80291a651bf3bd879928c0e5769
| | Author: Dataunique Tecnologia [email protected]
| | Date: Mon Dec 17 17:23:20 2018 -0200
| |
| | Nova linha no Readme.md
| |
* | commit fc8e1875e0d57a63ded14cf323bf5ca015a1cd24
|/ Author: Dataunique Tecnologia [email protected]
| Date: Mon Dec 17 21:42:25 2018 -0200
|
| Adicionado o arquivo.txt
|
* commit aafc335484f0c66cafd3d70b12a353c1658591dc
Author: Dataunique Tecnologia [email protected]
Date: Mon Dec 17 17:11:55 2018 -0200
Commit inicial

6. Criando um servidor Git

Antes de criar o servidor é necessário introduzir o conceito do arquivo “.gitignore”, pois ele serve para evitar o envio de arquivos desnecessários para o servidor remoto. Ele é um arquivo simples, onde serão inseridos as expressões regulares e os diretórios que não devem ser sincronizados com o servidor remoto. Acessando o link https://github.com/github/gitignore pode ser encontrado diversos exemplos para serem usados como referência para seu repositório de acordo com a necessidade do seu projeto.

ssh webservice01
su - git
mkdir .ssh && chmod 700 .ssh
touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys

cd /u01
mkdir projects.git
git init --bare
exit

ssh-copy-id -i /root/.ssh/id_rsa.pub git@webservice01
git remote add dataunique git@webservice01:/u01/projects.git
git push dataunique master
exit

ssh webservice01
which git-shell >> /etc/shells
chsh git -s $(which git-shell)

Counting objects: 535, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (453/453), done.
Writing objects: 100% (535/535), 57.69 MiB | 477.00 KiB/s, done.
Total 535 (delta 130), reused 0 (delta 0)
To git@webservice01:/u01/projects.git
* [new branch] master -> master

Para confirmar que o procedimento ocorreu com sucesso, realize o git clone em outro diretório.

mkdir temp
git clone git@webservice01:/u01/projects.git

Cloning into 'projects'... 
remote: Counting objects: 535, done. 
remote: Compressing objects: 100% (323/323), done. 
remote: Total 535 (delta 130), reused 535 (delta 130) 
Receiving objects: 100% (535/535), 57.69 MiB | 623.00 KiB/s, done. 
Resolving deltas: 100% (130/130), done.

ll -h

projects