44
Git Author: Eduardo R. D’Avila <[email protected]> Date: Fri Aug 31 12:00:00 2012 -0300

Git

Embed Size (px)

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

Page 1: Git

GitAuthor: Eduardo R. D’Avila <[email protected]>Date: Fri Aug 31 12:00:00 2012 -0300

Page 2: Git

2

Tópicos

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

Page 3: Git

Repositórios

Page 4: Git

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

Page 5: Git

5

repositório

compartilhado

desenvolvedores

Workflows

tenentes

ditador

desenvolvedores

repositório

público

Page 6: Git

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

Page 7: Git

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

Page 8: Git

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

Page 9: Git

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

Page 10: Git

Commits

Page 11: Git

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 <[email protected]>Date: Sat Jul 28 13:48:56 2012 -0300

Force loading order of test scripts

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

Page 12: Git

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

Page 13: Git

13

Comando status

index / staging area / cache

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

ARQUIVO”

Page 14: Git

Branchese Tags

Page 15: Git

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

Page 16: Git

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

Page 17: Git

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

Page 18: Git

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

Page 19: Git

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

Page 20: Git

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

Page 21: Git

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

Page 22: Git

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

Page 23: Git

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

Page 24: Git

RepositóriosRemotos

Page 25: Git

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

Page 26: Git

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

Page 27: Git

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!

Page 28: Git

Usando Gitcomo clientede SVN

Page 29: Git

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

Page 30: Git

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 <[email protected]>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

Page 31: Git

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

Page 32: Git

Alteraçõesno Histórico

Page 33: Git

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

Page 34: Git

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

Page 35: Git

Comandose OpçõesDiversas

Page 36: Git

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

Page 37: Git

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

Page 38: Git

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

Page 39: Git

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

Page 40: Git

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

Page 41: Git

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”

Page 42: Git

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!

Page 43: Git

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

Page 44: Git

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