Git

Preview:

DESCRIPTION

Tópicos básicos e avançados para quem já usa Git ou SVN. Inclui comparações com SVN e uso do Git como cliente de SVN. Baixe o arquivo e abra no PowerPoint para ver as animações!

Citation preview

GitAuthor: Eduardo R. D’Avila <erdavila@gmail.com>Date: Fri Aug 31 12:00:00 2012 -0300

2

Tópicos

RepositóriosCommitsBranches e TagsRepositórios RemotosGit como cliente de SVNAlterações no HistóricoComandos e Opções Diversas

Repositórios

4

Distribuído x Centralizado

Distribuído Centralizado

Git é Distribuído•Todo diretório de trabalho é um repositório completo

• Contém todo histórico de alterações•Principais operações são locais

• Sem dependência de um servidor•Somente operações de “sincronização” necessitam acesso a outros repositórios

CVS

5

repositório

compartilhado

desenvolvedores

Workflows

tenentes

ditador

desenvolvedores

repositório

público

6

Repositórios

Repositório de desenvolvedor • Usado para se trabalhar no projeto• Com arquivos do projeto• Dados do Git no diretório .git na raiz do projeto

Repositório de servidor (bare)• Usado para compartilhar o projeto• Sem arquivos do projeto• Dados do Git diretamente na raiz do projeto

Criação de repositório:• git init [--bare] DIRETÓRIO

7

Git versus SVN

Git: versionamento do projeto como um todoSVN: versionamento dos arquivos e diretórios

Histórico• SVN: histórico de alterações se referem a arquivos/diretórios• Git: histórico de alterações se referem ao projeto inteiro

Branching• SVN: “branches” são implementados como cópias de diretórios• Git: branches são “realidades alternativas” do projeto inteiro

Concorrência• SVN: deixa alterar arquivos concorrentemente, possivelmente introduzindo problemas no

projeto• Git: só permite atualizar repositório compartilhado após fazer merge (ou rebase)

Navegação em interfaces web:• SVN: primeiro árvore de diretórios e arquivos, depois histórico de alterações de arquivo• Git: primeiro histórico de alterações do projeto, depois árvore de diretórios da versão do

projeto

8

Renomeação e Cópia

SVNComandos move e copy• Mantêm o histórico associado ao novo arquivo/diretório• Devem ser usados com diretórios (em vez de usar comandos do sistema operacional)

GitComando mv• Equivale a:

– git rm --cached NOME-ANTES # tira do versionamento mas mantém o arquivo no diretório

– mv NOME-ANTES NOME-DEPOIS– git add NOME-DEPOIS

Não tem comando para cópia• Executar:

– cp ARQUIVO NOVO-ARQUIVO– git add NOVO-ARQUIVO

... mas o Git se esforça para detectar renomeações e cópias!Parâmetros -M e -C em alguns comandos

9

Diretórios

SVN: versiona diretórios vazios

Git: não versiona diretórios vaziosSolução: criar um arquivo não usado dentro do diretório (.gitignore)

Comandos addsvn add DIRETÓRIO – Adiciona todos os itens dentro do diretório. Acusa erro se houver itens já adicionadosgit add DIRETÓRIO – Adiciona todos os itens dentro do diretório sem reclamar sobre itens já adicionados

Commits

11

Commit

Commits são representados por hashes SHA1• 40 caracteres!• Só é necessário usar caracteres o suficiente para não ser ambíguo, a partir de 4

caracteres

Conforme o comando, um commit representa:• Um estado do projeto• OU alterações aplicadas a um estado do projeto para gerar um novo estado (delta / diff)• OU histórico do início do projeto até o estado do commit

Comandos• git checkout COMMIT• git show COMMIT• git log COMMIT

commit 2874505bdb80ee8790296428576d977c28708e7fAuthor: Eduardo R. D'Avila <erdavila@gmail.com>Date: Sat Jul 28 13:48:56 2012 -0300

Force loading order of test scripts

SVN: revisões são números sequenciais

12

Commit

Index / Staging Area / CacheÉ um estágio pré-commit

Para identificar arquivos alterados e não-commitados:git status

Para commitar diretamente todos os arquivos alterados:git commit -a

arquivo alterado

index commitgit add git

commit

SVN: para commitar somente alguns arquivos, é necessário listá-

los todos na linha de comando

13

Comando status

index / staging area / cache

SVN: “git checkout -- ARQUIVO” corresponde a “svn revert

ARQUIVO”

Branchese Tags

15

Branches no SVN

São uma convençãoEstrutura de diretórios:• trunk/• branches/ABC/• branches/XYZ/• branches/.../

Criar branch:• svn copy .../trunk .../branches/XYZ

“Mergear” branch:• svn checkout .../trunk• svn merge .../branches/XYZ

16

Branches no Git

São uma feature obrigatóriaBranch master é criado por padrão• Não tem nada de especial

– Pode ser renomeado– Pode ser removido– Pode ser recriado

São locais a cada repositório• Podem corresponder automaticamente (“track”) a um branch em um repositório remoto

17

Branches

São implementados como referências a commits

O nome do branch pode ser usado no lugar do commit em comandos

master

format

align

master

clipboard

bullet

smaster

master

18

Operações com branches

Listar• git branch

O branch atual é marcado com “*”

Alternar• git checkout BRANCH

Criar• git branch BRANCH [COMMIT] # somente cria• git checkout –b BRANCH [COMMIT] # cria e alterna para o branch

Merge• git merge OUTRO-BRANCH

Excluir• git branch –d BRANCH # não deixa apagar branch não-mergeado• git branch –D BRANCH

Remove somente a referência. Os commits continuam no histórico.

SVN: comando switch

SVN: um novo commit é criado

SVN: um novo commit é criado

19

Merge

Cria imediatamente um novo commitA não ser que:• Resulte em um “fast-forward”• Haja algum conflito!

Facilmente identificável no histórico

I

new-feature

A B C

D E F

G H

master

HEAD

$ git checkout master

$ git merge new-feature

SVN: informações de merge ficam em propriedades do diretório

SVN: após o merge é preciso efetuar commit

20

Fast-forward

Simplesmente avança o branch atual para alcançar o outro branch

A B C

D E

new-feature

master

HEAD

$ git checkout master

$ git merge new-feature

21

Merge com conflito

O que fazer?• Editar arquivos resolvendo os conflitos• git add ARQUIVOS• git commit

// Beginfunction f(x) { return 7;}// End

function f(x) { return 2 * x;}

// Beginfunction f(x) {<<<<<<< HEAD return 7;======= return 2 * x;>>>>>>> other-branch}// End

function f(x) {}

main.js

$ git merge other-branchAuto-merging main.jsCONFLICT (content): Merge conflict in main.jsAutomatic merge failed; fix conflicts and then commit the result.

$ git status# On branch master# Unmerged paths:# (use "git add/rm <file>..." as appropriate to mark resolution)## both modified: main.js#no changes added to commit (use "git add" and/or "git commit -a")

merge

22

HEAD

HEAD é o estado do histórico sobre o qual se está trabalhandoImplementado como referência a um branch (o branch atual) ou diretamente a um commit

git checkout BRANCH• HEAD referencia o branch, que por sua vez referencia o commit• HEAD é o commit mais recente do branch• Ao fazer um commit, o branch avança

git checkout <COMMIT ou BRANCH-REMOTO ou TAG>• HEAD referencia diretamente um commit• Repositório fica em “detached HEAD”• Ao fazer um commit, HEAD avança• Cuidado! Garbage collector pode eliminar commits sem referência

A B C

master

HEAD

A B C

HEAD

23

Tags

Marcam uma versão do projetoSão implementadas como referências a commitsNão podem ser alteradasPodem ser assinadas com GPG

Listar• git tag

Criar• git tag NOME [COMMIT]

SVN: implementação idêntica a branches

RepositóriosRemotos

25

Repositórios Remotos

Identificados por uma URL ou caminho:Sistema de arquivos local:• /git/projeto.git• ../outro-projeto• file:///home/fulano/projeto

SSH (Git deve estar instalado no servidor):• ssh://usuario@servidor/caminho• usuario@servidor:caminho

Outros protocolos:• git://servidor/caminho – Serviço do Git no servidor• http[s]://servidor/caminho – Lento! Se for somente leitura, não precisa ter Git no servidor• ftp[s]://servidor/caminho• rsync://servidor/caminho

Usar um nome para referenciar um repositório remoto• git remote add NOME URL-OU-CAMINHO

Múltiplos repositórios podem ser referenciados – Afinal Git é distribuído!Listar repositórios remotos:• git remote –v # Lista repositórios remotos

Clonagem de repositório• git clone [--bare] URL-OU-CAMINHO [DIRETÓRIO]

Automaticamente define o nome “origin” para referenciar o repositório remoto

SVN: comando checkout

26

Operações com repositórios remotos

Somente duas operações básicas envolvem comunicação com repositório remoto

git fetch [--tags] NOME• Obtém branches e tags (e seus commits) do repositório remoto• Não toca nos branches locais• Cada branch remoto é identificado por REPOSITÓRIO/BRANCH• Para listar branches remotos:

– git branch –r # Lista somente branches remotos– git branch –a # Lista branches locais e remotos (o atual é marcado com “*”)

git push [--tags] NOME BRANCH-LOCAL:BRANCH-REMOTO• Atualiza (ou cria) o branch do repositório remoto com o estado do branch local• Só funciona se for um “fast-forward” (pois não há como fazer um merge remoto)

Extra:git pull NOME BRANCH-REMOTO• Executa um fetch do branch remoto e faz merge com o branch atual

27

Branches “seguidos” (track)

Cada branch local pode estar associado a um branch remotoOperações simplificadas no branch atual:• git pull # Sem mais parâmetros!• git push # Sem mais parâmetros!

Criar um branch a partir de um branch remoto faz a associação automaticamente:• git checkout -b NOVO-BRANCH-LOCAL REPOSITÓRIO/BRANCH-REMOTO• git branch NOVO-BRANCH-LOCAL REPOSITÓRIO/BRANCH-REMOTO

Associar branch já existente:• git branch --set-upstream BRANCH-LOCAL REPOSITÓRIO/BRANCH-REMOTO

Listar associações:• git branch -v -v # Mesmo parâmetro duas vezes!

Usando Gitcomo clientede SVN

29

Git como cliente de SVN

Git pode ser usado para interagir com servidor SVNTodas as funcionalidades locais do Git ficam disponíveis

Clonar repositório:• git svn clone [--username=USERNAME] [SUBDIRS] URL [DIRETÓRIO] # pode demorar!

Atualizar informações de branches do SVN:• git svn fetch # similar a “git fetch”

Atualizar branch atual com commits do SVN:• git svn rebase # similar a “git pull”

Enviar commits do branch atual ao SVN:• git svn dcommit # similar a “git push”

Criar branch ou tag no SVN:• git svn branch NOME• git svn tag NOME

30

Commits do SVN no Git

Commits do SVN no Git incluem revisão relacionada

Commits feitos no Git são substituídos pelo commit do SVN ao serem enviados ao SVN

• Após git commit:

• Após git svn dcommit:

commit 70391454621da3b6463aa270c9b75f16268909b4Author: Eduardo D'Avila <erdavila@gmail.com>Date: Thu Aug 30 19:38:02 2012 -0300

Commit criado com git-svn

commit 1c566c0d83d0efbd6fa65256827be5f2e23e9b2dAuthor: erdavila <erdavila@871847d0-d1a7-405d-8ece-d9976fa2c25e>Date: Thu Aug 30 22:41:33 2012 +0000

Commit criado com git-svn

git-svn-id: file:///home/erdavila/ll-git/svn-server@5 871847d0-d1a7-405d-8ece-d9976fa2c25e

31

Cuidados e restrições

Manter histórico linearInformações de merge do Git e do SVN não são compatíveis

Diretórios vaziosGit não versiona diretórios vazios.• Diretórios esvaziados no Git devem ser removidos do SVN com git svn dcommit --rmdir

• Diretórios vazios do SVN podem ser criados com git svn mkdirs

Associação entre branches locais e remotosGit tenta associar pelo commit mais recente em comum nos branches local e remoto

Tags do SVNAparecem como branches remotos no Git

Alteraçõesno Histórico

33

Alterações no histórico

Alteração no último commitgit commit --amend

RebaseDiversos usos:• Tornar linear parte do histórico• Alterar commits (editar, eliminar, juntar, separar) anteriores ao último• “Transplantar” commits para outro branch

Pode ser necessário resolver conflitos durante a operação

A B

C D

E F

master

HEAD

origin/master

A B

C D E’ F’

master

HEAD

origin/master

$ git checkout master

$ git rebase origin/master

34

Alterações no histórico

CUIDADO!Commits que já foram compartilhados com

outros repositórios não devem ser alterados!

Git vai achar que são commits novos e tentar fazer merge, aumentando os riscos de conflitos que cada usuário vai ter que resolver no seu repositório

Comandose OpçõesDiversas

37

stash

Guarda temporariamente alterações ainda não commitadasÚtil quando se começa uma tarefa e precisa-se alternar para outra tarefa no GitFunciona como uma pilha

Comandos• git stash [save [‘MENSAGEM’]]• git stash pop [--index] [STASH]• git stash apply [--index] [STASH]• git stash list• git stash drop [STASH]• git show STASH

Stashes são identificados como:• stash@{0} (ou simplesmente “stash”) – no topo da pilha. É o default para pop, apply e drop

• stash@{1}• stash@{2}• ...

SVN: comando shelve previsto para versão 1.10.0

38

log

Provê MUITAS opções de visualização do histórico

• git log [COMMIT ...] – Histórico a partir do commit mais recente (ou dos especificados)

• git log COMMIT1..COMMIT2 - Histórico do que o COMMIT2 tem de novo em relação ao COMMIT1

• git log -- ARQUIVO – Histórico de commits que incluem alterações no ARQUIVO• git log -S STRING – Seleciona commits que removeram ou incluíram STRING em algum

arquivo

Algumas opções:• --stat – Inclui lista de arquivos que foram alterados em cada commit• -p – Inclui as alterações de cada arquivo (diffs)• --graph – Mostra grafo de branches e merges• --oneline – Mostra somente hash e mensagem de cada commit• --decorate – Identifica outras referências (branches e tags) no histórico

39

Operações em linhas de arquivos

O parâmetro -p em alguns comandos permite selecionar interativamente partes de arquivos

Seleciona partes a serem adicionadas ao index (e posteriormente commitadas)• git add -p ARQUIVO

Seleciona partes a serem removidas do index• git reset -p ARQUIVO

Seleciona partes alteradas a serem descartadas• git checkout -p ARQUIVO

40

show / diff / blame

show – Exibe informações de um commit e/ou alterações e conteúdo de arquivos• git show [COMMIT] – Mostra dados do commit e suas alterações de arquivo• git show COMMIT -- ARQUIVO – Mostra alterações feitas no ARQUIVO no commit

especificado• git show COMMIT:ARQUIVO – Mostra conteúdo do ARQUIVO no commit especificado

diff - Mostra diferenças em conteúdos de arquivos• git diff – Mostra alterações que ainda não estão no index• git diff COMMIT1 [COMMIT2] – Mostra diferenças entre os commits• git diff -- ARQUIVO – Seleciona arquivo para mostrar diferenças

blame – Exibe informações de quando cada linha de um arquivo foi alterada• git blame ARQUIVO

SVN: comando cat

41

cherry-pick

Caso específico de rebase: re-aplica alterações de um único commit

Pode ser necessário resolver conflitos

A B C

D E

E’

F

new-feature$ git checkout master

$ git cherry-pick E

master

HEAD

SVN: cherry-pick é um tipo de merge

42

revert

Inverte as alterações feitas por um commit

Pode ser necessário resolver conflitos

A B C D EB

master

HEAD

$ git checkout master

$ git revert B

SVN: “git revert” não corresponde a “svn

revert”

43

bisect

Efetua uma busca binária para ajudar a identificar commit que introduziu um bugPode ser automatizadaFunciona com históricos não lineares

E F G H I J K L M N O

good bad

badgood bad

BUG!

44

Ferramentas gráficas

gitkCorrespondente ao comando git log, mas mais visual e navegável

git guiProvê funcionalidades de commit, merge, gerência de branches e de repositórios remotos, entre outras opções

Perguntas?Dúvidas?Sugestões?Críticas?Opiniões?