De artista.frustrado
Tabela de conteúdo |
Git
Git é um sistema de controle de versões distribuído (DVCS) criado pelo finlandês Linus Torvalds. Descrito por muitos como o DVCS criado com o intuito de fazer as pessoas sentirem-se menos inteligentes do que realmente são e como "o gerenciador de informação do inferno" por seu criador, Git tem expandido seus recursos assim como sua base de usuários de forma exponecial desde sua criação em 2005.
Assim como a kernel do Linux, a criação do git é marcado por uma determinação de desenvolver a melhor ferramenta com o senso de humor de Linus. Enquanto a base do código do git é levada muito a sério, com objetivos e princípios bem definidos, o ambiente de desenvolvimento é bem humorado. O próprio nome dado ao programa ... Racionalizando sobre o nome, Linus observa:
“Sou um bastardo egoísta e nomeio todos os meus projetos em homenagem a mim mesmo. Primeiro Linux, agora git.”
- Linux = Híbrido dos nomes Linus e Mimix
- Git = gíria britânica que descreve uma pessoa idiota ou sem valor.
Sistemas de Controles de Versão
Siglas/Nomenclatura
Siglas para sistemas de controle de versão:
- VCS – Version Control System
- SCM – Source Code Manager
- RCS – Revision Control System
Histórico dos Sistemas de Controle de Versão
História de SCMs:
SCCS – Source Code Control System
- Criado no Início dos anos 1970 por M.J. Rochkind
- Início de conceitos ainda pertinentes nos SCMs atuais. ex.: repositório
- Problema: arquivo de LOCK - enquanto um usuário trabalha outro não tem acesso ao arquivo
RCS – Revision Control System
- Criado no início dos anos 1980 por Walter Tichy
CVS – Concurrent Version System
- Criado em 1986 por Dick Grune.
- Extendeu e modificou o modelo do RCS
- Altera sistema de lock de forma a permitir que várias pessoas possam trabalhar no mesmo arquivo concorrentemente. Introduzido o conceito de mescla (merge).
SVN – Subversion
- Criado com o intuito de corrigir as falhas de arquitetura do CVS
- Introduziu:
- Commit Atomico
- Melhor suporte a galhos (branches)
BitKeeper e Mercurial
- Distanciam-se do modelo dos sistemas anteriores ao eliminar o repositório central.
- Armazenagem distribuída:
- cada desenvolvedor possui sua própria cópia completa e compartilhável
- derivado do modelo P2P (peer-to-peer)
Mercurial e Monotone
- Utilizam hash para identificar o conteúdo dos arquivos - Influenciou a arquitetura do git.
Git
Kernel do Linux
- Utilizou tarbals e arquivos de patch.
- Controvérsia com a utilização do BitKeeper (proprietário)
- Problema de Licença do BitKeeper - Larry McVoy removeu a licença de utilização do BitKeeper para projetos de código aberto depois de acusar Andrew Tidwell de tentar executar engenharia reversa no BitKeeper.
- Linus Torvalds faz acordo com McVoy e abandona BitKeeper no desenvolvimento da kernel.
- Linus analisa SCMs abertos e conclui que nenhum deles respondem à suas necessidades. Entre as opções de voltar a tarballs / patches e criar um SCM próprio opta pela segunda.
Utilizadores do Git
- Git
- Linux Kernel
- Perl
- Eclipse
- Gnome
- KDE
- Qt
- Ruby on Rails
- Android
- PostgreSQL
- Debian
- X.org
- Zend Framework 2
Objetivos do Git
- Facilitar desenvolvimento distribuído
- Escalável – suportar milhares de usuários
- Execução rápida e eficiente
- Manter integridade e confiança
- Obrigar responsabilidades (enforce accountability)
- Imutabilidade – depois de criados os objetos não podem ser alterados.
- Transações atômicas – alterações diferentes mas relacionadas são executadas como um todo ou não são executadas.
- Suportar e incentivar desenvolvimento ramificado (Branched Development)
- Repositórios completos
- Design interno limpo
- Livre, “como em liberdade”
Arquitetura
Modelo de Objetos
Baseado em estrutura de sistemas de diretórios.
SHA
Toda informação necessária para representar a história de um projeto é aramazenada em arquivos referenciados plor um nome de objeto de 40 dígitos.
EX:
6ff87c4664981e4397625791c8ea3bbb5f2279a3
Nome dos objetos - hash SHA1 do conteúdo do objeto
Hash SHA1 = função critpográfica
Vantagens de SHA
- Conflitos de nomenclatura: virtualmente impossível encontrar 2 objetos com o mesmo nome
- Comparação: a identificação de objetos idênticos é rápida pois só é necessário comparar os nomes
- Consistencia de nome em vários repositórios: os nomes dos objetos são calculados da mesma forma nos vários repositórios - o mesmo conteúdo armazenado em 2 repositórios terá o mesmo nome
- Detecção de erros nos objetos: git pode identificar erros na leitura de objetos ao conferir o nome do objeto com o hash SHA1 do seu conteúdo.
Atributos
Tipos:
- Blob: utilizado para armazenar dados de arquivos - normalmente um arquivo
- Tree: basicamente como um diretório - referencia outros objetos (trees, blobs) assim como diretórios referenciam subdiretórios e arquivos
- Commit: aponta para uma árvore marcando seu estado em um determinando momento. Contém meta informações sobre esse momento como: timestamp, autor das alterações desde o último commit, um ponteiro para os commits anteriores, etc.
- Tag: maneira de marcar commits como sendo especiais. comumente utilizado para marcar commits de uma versão específica do app ou algo neste sentido.
Configuração
arquivo de configuração .git/config
[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = usuario@servidor:/caminho/projetox/ [branch "master"] remote = origin merge = refs/heads/master
Importante
- Git: Faz snapshot do estado atual dos arquivos na estrutura de árvores a cada commit.
- Git gerencia conteúdo, não arquivos.
- Git percebe quando conteúdo é movido de um arquivo para outro.
- Arquivos/pastas vazios não são armazenados no repositório.
Progamação Não Linear
- Desenvolver vários recursos simultaneamente utilizando a mesma base de código mas em galhos separados.
- Mesclar recursos/alterações quando as mesmas estiverem comprovadamente funcionais.
Ex.
Na figura acima vemos um exemplo clássico de programação não linear. Em um branch master (galho principal no git), são criados galhos para cada recurso/alteração. Quando os mesmos são concluídos e/ou aprovados pelo cliente são mesclados no master, caso contrário são abandonados/apagados.
Instalação Git
Debian/Ubuntu
sudo apt-get install git-core gitk
Windows
Baixar e instalar MsGit e TortoiseGIT
Eclipse
Configuração
Usuário
git config --global user.name "Fernando Michelotti" git config --global user.email artista.git@frustrado.com.br
Ambiente
git config --global color.branch auto git config --global color.diff auto git config --global color.interactive auto git config --global color.status auto
Exemplo de Progamação Não Linear
Nada como um bom exemplo prático para facilitar o entendimento de novos conceitos e ferramentas. Por isso iremos utilizar como exemplo um sistema fictício de citações.
Abaixo temos uma especificação super simplificada:
Projeto exemplo: Sistema de citações. Descrição dada pelo cliente/chefe: “Uma paginazinha com citações de pensadores para os visitantes perceberem nossa superioridade intelectual.” (citação direta) Dados fornecidos pelo cliente: 1 citação: Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de falhar. - Bill Gates - The Road Ahead (1995) Solução proposta: KISS (Keep It Simple Stupid) 1 página + 1 citação = 1 html estático
Implementação
1a versão
<html> <head> </head> <body> <h1>Pensamento</h1> <p> Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder. - Bill Gates - The Road Ahead (1995) </p> </body> </html>
Criar repositório:
$ mkdir projeto $ cd projeto $ git init Initialized empty Git repository in /tmp/projeto/.git/ $ vim index.html $ git add index.html $ git commit -a -m 'inicio do projeto' [master (root-commit) a8f0cc2] inicio do projeto 1 files changed, 10 insertions(+), 0 deletions(-) create mode 100644 index.html
Alteração
Mostrar uma de 3 citações aleatoriamente toda vez que a página é acessada.
Criar branch:
$ git checkout -b aleatorio Switched to a new branch 'aleatorio' $ git mv index.html index.php $ vim index.php
<html> <head> </head> <body> <h1>Pensamento</h1> <?php $pensamentos = array(); $pensamentos[] = "Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder. - Bill Gates - The Road Ahead (1995)"; $pensamentos[] = "Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder. - Bill Gates - The Road Ahead (1995)"; $pensamentos[] = "Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder. - Bill Gates - The Road Ahead (1995)"; echo "<p>". $pensamentos[rand(0, count($pensamentos) - 1)] . "</p>\n"; ?> </body> </html>
Commit:
$ git commit -a [aleatorio 02a2fb2] Subsituído html estático por escolha aleatória de citações utilizando a função rand em chaves de array 2 files changed, 16 insertions(+), 10 deletions(-) delete mode 100644 index.html create mode 100644 index.php $ git branch * aleatorio master
Mesclar (merge): $ git checkout master Switched to branch 'master' $ git pull . aleatorio From . * branch aleatorio -> FETCH_HEAD Updating a8f0cc2..02a2fb2 Fast-forward index.html | 10 ---------- index.php | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) delete mode 100644 index.html create mode 100644 index.php $ ls index.php
Refatoração:
$ git checkout -b refatoracao Switched to a new branch 'refatoracao' $ vim funcoes.php
<?php function escolher_citacao() { $pensamentos = array(); $pensamentos[] = "Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder. - Bill Gates - The Road Ahead (1995)"; $pensamentos[] = "Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder. - Bill Gates - The Road Ahead (1995)"; $pensamentos[] = "Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder. - Bill Gates - The Road Ahead (1995)"; return $pensamentos[rand(0, count($pensamentos) - 1)]; }
$ vim index.php<html> <head> </head> <body> <h1>Pensamento</h1> <?php include_once "funcoes.php"; echo "<p>". escolher_citacao()."</p>"; ?> </body> </html>
Refatoração:
$ git add funcoes.php $ git commit -a [refatoracao ecd9f1b] Separada lógica da apresentacao atraves da criação de arquivo funcoes.php 2 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 funcoes.php rewrite index.php (88%)
Layout:
$ git checkout master $ git checkout -b layout $ vim estilo.css
body, td, div, p { font-family: Verdana, Arial, Helvetica, Sans-Serif; font-size: 11px;} body { background-color: #EEEEEE; }
$ vim index.php<head> <link rel="stylesheet" href="estilo.css" media="screen" /> </head>
$ git add estilo.css $ git commit -a [layout ccff6c9] Colocadas instrucoes de layout em arquivo css externo 2 files changed, 11 insertions(+), 0 deletions(-) create mode 100644 estilo.css
Mescla:
$ git pull . layout refatoracao From . * branch layout -> FETCH_HEAD * branch refatoracao -> FETCH_HEAD Fast-forwarding to: ccff6c99f190896c3d37f10bfad4813c85f18204 Trying simple merge with ecd9f1b6e8953bc95c5ab1274a5c19987286e59a Simple merge did not work, trying automatic merge. Auto-merging index.php Merge made by octopus. estilo.css | 10 ++++++++++ funcoes.php | 12 ++++++++++++ index.php | 9 +++------ 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 estilo.css create mode 100644 funcoes.php
Repositórios remotos:
Criando repositório remoto:
$ssh usuario@servidor $ mkdir projetox $ cd projetox/ $ git init --bare Initialized empty Git repository in /tmp/projetox/
Adicionando repositório remoto à lista do repositotio local:
git remote add empresax usuario@servidor:/tmp/projetox/
Histórico
Histórico:
$ git log commit 12e615323dee6eb9a3548369981a549133291710 Merge: ccff6c9 ecd9f1b Author: Fernando Michelotti <artista@frustrado.com.br> Date: Tue May 31 05:25:52 2011 -0300 Merge branches 'layout' and 'refatoracao' commit ccff6c99f190896c3d37f10bfad4813c85f18204 Author: Fernando Michelotti <artista@frustrado.com.br> Date: Tue May 31 05:21:06 2011 -0300 Colocadas instrucoes de layout em arquivo css externo commit ecd9f1b6e8953bc95c5ab1274a5c19987286e59a Author: Fernando Michelotti <artista@frustrado.com.br> Date: Tue May 31 05:04:27 2011 -0300
Repositórios remotos:
Adicionando repositório remoto à lista do repositotio local:
git remote add empresax usuario@servidor:/tmp/projetox/ Exportando branch master para repositório remoto (empresax): $ git push empresax master Counting objects: 17, done. Delta compression using up to 2 threads. Compressing objects: 100% (15/15), done. Writing objects: 100% (17/17), 2.07 KiB, done. Total 17 (delta 5), reused 0 (delta 0) Unpacking objects: 100% (17/17), done. To /tmp/projetox/ * [new branch] master -> master
Clonando repositório:
$ git clone usuario@servidor:/tmp/projetox/ Cloning into projetox... Done. $ cd projetox/ $ vim citacoes.sql
CREATE DATABASE citacao; USE citacao; CREATE TABLE IF NOT EXISTS `citacao` ( `id` int(11) NOT NULL AUTO_INCREMENT, `citacao` text NOT NULL, `autor` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; INSERT INTO `citacao` (`id`, `citacao`, `autor`) VALUES (1, 'Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder.', 'Bill Gates - The Road Ahead (1995)'), (2, 'Sucesso é um péssimo professor. Ele seduz pessoas espertas em pensar que eles são incapazes de perder.', 'Bill Gates - The Road Ahead (1995)');
$ git add citacao.sql $ git commit -a [master e973365] adicionado script sql para banco de dados 1 files changed, 13 insertions(+), 0 deletions(-) create mode 100644 citacao.sql $ git push origin master Counting objects: 4, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 699 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To /tmp/projetox/ 12e6153..e973365 master -> master
$ git rebase origin master Already on 'master' Current branch master is up to date. $ vim funcoes.php $ git commit -a [master 023781a] removida array e implementada solucao baseada em banco de dados 1 files changed, 11 insertions(+), 12 deletions(-) rewrite funcoes.php (93%) $ git push origin master Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 503 bytes, done. Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To /tmp/projetox/ e973365..023781a master -> master
Gitk
Faxina:
$ git branch aleatorio layout * master refatoracao $ git branch -d aleatorio Deleted branch aleatorio (was 02a2fb2). $ git branch -d layout Deleted branch layout (was ccff6c9). $ git branch -d refatoracao Deleted branch refatoracao (was ecd9f1b). $ git branch * master
Tags
$ git log commit 023781a376765bf37b30e51f5ba67d8103a86c88 Author: Fernando Michelotti <fernando.michelotti@cnt.com.br> Date: Tue May 31 06:19:55 2011 -0300 removida array e implementada solucao baseada em banco de dados commit e973365a451ab0d7fa842d6e2ae6da7d96f1bca6 Author: Fernando Michelotti <fernando.michelotti@cnt.com.br> Date: Tue May 31 06:03:04 2011 -0300 adicionado script sql para banco de dados $ git tag estavel-1 023781a376765bf37b30e51f5ba67d8103a86c88 $ git tag rc1 12e615323dee6eb9a3548369981a549133291710 $ git tag estavel-1 rc1
Checkout de versões antigas:
$ git log commit 023781a376765bf37b30e51f5ba67d8103a86c88 Author: Fernando Michelotti <fernando.michelotti@cnt.com.br> Date: Tue May 31 06:19:55 2011 -0300 removida array e implementada solucao baseada em banco de dados commit e973365a451ab0d7fa842d6e2ae6da7d96f1bca6 Author: Fernando Michelotti <fernando.michelotti@cnt.com.br> Date: Tue May 31 06:03:04 2011 -0300 adicionado script sql para banco de dados
Checkout de commits antigos:
$ git checkout 12e615323dee6eb9a3548369981a549133291710 Note: checking out '12e615323dee6eb9a3548369981a549133291710'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 12e6153... Merge branches 'layout' and 'refatoracao' $ git checkout master Previous HEAD position was 12e6153... Merge branches 'layout' and 'refatoracao' Switched to branch 'master'
Checkout de uma Tag:
$ git tag estavel-1 rc1 $ git checkout rc1 Note: checking out 'rc1'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 12e6153... Merge branches 'layout' and 'refatoracao'

