-
1. Começando
- 1.1 Sobre Controle de Versão
- 1.2 Uma Breve História do Git
- 1.3 O Básico do Git
- 1.4 A Linha de Comando
- 1.5 Instalando o Git
- 1.6 Configuração Inicial do Git
- 1.7 Pedindo Ajuda
- 1.8 Sumário
-
2. Fundamentos de Git
-
3. Branches no Git
-
4. Git on the Server
- 4.1 The Protocols
- 4.2 Getting Git on a Server
- 4.3 Generating Your SSH Public Key
- 4.4 Setting Up the Server
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Third Party Hosted Options
- 4.10 Summary
-
5. Distributed Git
-
6. GitHub
- 6.1 Configurando uma conta
- 6.2 Contribuindo em um projeto
- 6.3 Maintaining a Project
- 6.4 Managing an organization
- 6.5 Scripting GitHub
- 6.6 Summary
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Summary
-
8. Customizing Git
- 8.1 Git Configuration
- 8.2 Git Attributes
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Summary
-
9. Git and Other Systems
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Summary
-
10. Funcionamento Interno do Git
- 10.1 Encanamento e Porcelana
- 10.2 Objetos do Git
- 10.3 Referências do Git
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Variáveis de ambiente
- 10.9 Sumário
-
A1. Appendix A: Git em Outros Ambientes
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in Powershell
- A1.7 Resumo
-
A2. Appendix B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
3.1 Branches no Git - Branches em poucas palavras
Quase todo Sistema de Controle de Versionamento tem alguma forma de suporte a ramificações (Branches). Ramificação significa que você diverge da linha principal de desenvolvimento e continua a trabalhar sem alterar essa linha principal. Em muitas ferramentas versionamento, este é um processo um tanto difícil, geralmente exigindo que você crie uma nova cópia do diretório do código-fonte, o que pode demorar muito em projetos maiores.
Algumas pessoas se referem ao modelo de ramificação do Git como seu “recurso matador” e certamente diferencia o Git na comunidade de sistemas de versionamento. Por que isso é tão especial? A forma como o Git cria branches é incrivelmente leve, tornando as operações de ramificação quase instantâneas, alternando entre os branches geralmente com a mesma rapidez. Ao contrário de muitos outros sistemas, o Git incentiva fluxos de trabalho que se ramificam e se fundem com frequência, até mesmo várias vezes ao dia. Compreender e dominar esse recurso oferece uma ferramenta poderosa e única e pode mudar totalmente a maneira como você desenvolve.
Branches em poucas palavras
Para realmente entender como o Git trabalha com Branches, precisamos dar um passo atrás e examinar como o Git armazena seus dados.
Como você deve se lembrar de << ch01-introdução >>, o Git não armazena dados como uma série de mudanças ou diferenças, mas sim como uma série de snapshots (instantâneos de um momento) .
Quando você faz um commit, o Git armazena um objeto de commit que contém um ponteiro para o snapshot do conteúdo que você testou. Este objeto também contém o nome do autor e o e-mail, a mensagem que você digitou e ponteiros para o commit ou commits que vieram antes desse commit (seu pai ou pais): sem pai para o commit inicial, um pai para um commit normal, e vários pais para um commit que resulta de uma fusão de dois ou mais branches.
Para verificar isso, vamos assumir que você tem um diretório contendo três arquivos, e você seleciona todos eles e efetua o commit. Ele Prepara os arquivos e calcula uma verificação para cada um (o hash SHA-1 que mencionamos em << ch01-introdução >>), armazena essa versão do arquivo no repositório Git (Git se refere a eles como blobs), e adiciona esse hash de verificação à área de preparação (staging area):
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'
Quando você faz um commit executando git commit
, o Git verifica cada subdiretório (neste caso, apenas o diretório raiz do projeto) e armazena esses objetos no repositório do Git.
O Git então cria um objeto de commit que possui os metadados e um ponteiro para a raiz do projeto para que ele possa recriar aquele snapshots quando necessário.
Seu repositório Git agora contém cinco objetos: um blob para o conteúdo de cada um dos seus três arquivos, uma árvore que lista o conteúdo do diretório e especifica quais nomes de arquivo são armazenados e quais seus blobs e um commit com o ponteiro para essa árvore e todos os metadados de commit.
Se você fizer algumas mudanças e confirmar novamente, o próximo commit armazena um ponteiro para o commit que veio imediatamente antes dele.
Um branch no Git é simplesmente um ponteiro móvel para um desses commits.
O nome do branch padrão no Git é master
.
Conforme você começa a fazer commits, você recebe um branch master
que aponta para o último commit que você fez.
Cada vez que você faz um novo commit, ele avança automaticamente.
Note
|
O branch ‘` master '’ no Git não é um branch especial.
É exatamente como qualquer outra ramificação.
A única razão pela qual quase todo repositório tem um é que o comando |
Criando um Novo Branch
O que acontece se você criar um novo branch?
Bem, fazer isso cria um novo ponteiro para você mover.
Digamos que você crie um novo branch chamado: testing.
Você faz isso com o comando git branch
:
$ git branch testing
Isso cria um novo ponteiro para o mesmo commit em que você está atualmente.
Como o Git sabe em qual branch você está atualmente?
Ele mantém um ponteiro especial chamado HEAD
.
Note que isso é muito diferente do conceito de HEAD
em outros sistemas de versionamento com os quais você pode estar acostumado, como Subversion ou CVS.
No Git, isso é um ponteiro para o branch local em que você está.
Neste caso, você ainda está em master
.
O comando git branch
apenas criou um novo branch - ele não mudou para aquele branch.
Você pode ver isso facilmente executando um simples comando git log
que mostra para onde os ponteiros do branch estão apontando.
Esta opção é chamada de --decorate
.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project
Você pode ver os branches ‘` master ’ e `` testing ' que estão bem ali ao lado do commit f30ab
.
Alternando entre Branches
Para mudar para um branch existente, você executa o comando git checkout
.
Vamos mudar para o novo branch testing
:
$ git checkout testing
Isso move o HEAD
e o aponta para o branch` testing`.
O que isso significa? Bem, vamos fazer outro commit:
$ vim test.rb
$ git commit -a -m 'made a change'
Isso é interessante, porque agora seu branch testing
avançou, mas seu branch` master` ainda aponta para o commit em que você estava quando executou git checkout
para alternar entre os branches.
Vamos voltar para o branch master
:
$ git checkout master
Esse comando fez duas coisas.
Ele moveu o ponteiro HEAD de volta para apontar para o branch master
, e reverteu os arquivos em seu diretório de trabalho de volta para o snapshots para o qual` master` aponta.
Isso também significa que as alterações feitas a partir deste ponto irão divergir de uma versão mais antiga do projeto.
Essencialmente, ele retrocede o trabalho que você fez em seu branch testing
para que você possa ir em uma direção diferente.
Note
|
A troca de branches muda os arquivos em seu diretório de trabalho
É importante notar que quando você muda de branches no Git, os arquivos em seu diretório de trabalho mudam. Se você mudar para um branch mais antigo, seu diretório de trabalho será revertido para se parecer com a última vez que você fez commit naquele branch. Se o Git não puder fazer, ele não permitirá que você faça a troca. |
Vamos fazer algumas mudanças e confirmar novamente:
$ vim test.rb
$ git commit -a -m 'made other changes'
Agora o histórico do seu projeto divergiu (consulte Histórico de diferenças).
Você criou e mudou para um branch, fez algum trabalho nele e, em seguida, voltou para o seu branch principal e fez outro trabalho.
Ambas as mudanças são isoladas em branches separados: você pode alternar entre os branches e mesclá-los quando estiver pronto.
E você fez tudo isso com comandos simples branch
,` checkout` e commit
.
Você também pode ver isso facilmente com o comando git log
.
Se você executar git log --oneline --decorate --graph --all
, ele mostrará o histórico de seus commits, exibindo onde estão seus ponteiros de branch e como seu histórico divergiu.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
Como um branch no Git é na verdade um arquivo simples que contém a verificação SHA-1 de 40 caracteres do commit para o qual ele aponta, branches são fáceis para criar e destruir. Criar um novo branch é tão rápido e simples quanto escrever 41 bytes em um arquivo (40 caracteres e uma nova linha).
Isso está em nítido contraste com a forma como as ferramentas de Versionamento mais antigas se ramificam, o que envolve a cópia de todos os arquivos do projeto em um segundo diretório. Isso pode levar vários segundos ou até minutos, dependendo do tamanho do projeto, enquanto no Git o processo é sempre instantâneo. Além disso, como estamos gravando os pais quando fazemos o commit, encontrar uma base adequada para a mesclagem é feito automaticamente para nós e geralmente é muito fácil de fazer. Esses recursos ajudam a incentivar os desenvolvedores a criar e usar branches com frequência.
Vamos ver por que você deve fazer isso.