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" > 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" > 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