-
1. Primeiros Passos
- 1.1 Sobre Controle de Versão
- 1.2 Uma Breve História do Git
- 1.3 O que é Git?
- 1.4 A Linha de Comando
- 1.5 Instalando o Git
- 1.6 Configuração inicial do Git
- 1.7 Obtendo Ajuda
- 1.8 Resumo
-
2. Fundamentos do Git
-
3. Ramificação (Branching) no Git
-
4. Git no Servidor
- 4.1 Os Protocolos
- 4.2 Colocando o Git em um Servidor
- 4.3 Gerando a sua Chave Pública SSH
- 4.4 Configurando o Servidor
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Opções de Hospedagem de Terceiros
- 4.10 Resumo
-
5. Git Distribuído
-
6. GitHub
-
7. Ferramentas do Git
- 7.1 Seleção de Revisão
- 7.2 Área de Stage Interativa
- 7.3 Fazendo Stash e Limpando
- 7.4 Assinando Seu Trabalho
- 7.5 Pesquisando (Searching)
- 7.6 Reescrevendo o Histórico
- 7.7 Reset Desmistificado
- 7.8 Merging Avançado
- 7.9 Rerere
- 7.10 Depurando com Git
- 7.11 Submódulos
- 7.12 Empacotando (Bundling)
- 7.13 Substituir (Replace)
- 7.14 Armazenamento de Credenciais
- 7.15 Resumo
-
8. Customizando o Git
- 8.1 Configuração do Git
- 8.2 Atributos do Git
- 8.3 Hooks do Git
- 8.4 Uma Política de Exemplo Imposta pelo Git
- 8.5 Resumo
-
9. Git e Outros Sistemas
- 9.1 Git como Cliente
- 9.2 Migrando para o Git
- 9.3 Resumo
-
10. Git Internals (Por Dentro do Git)
- 10.1 Encanamento e Porcelana (Plumbing and Porcelain)
- 10.2 Objetos do Git
- 10.3 Referências do Git
- 10.4 Arquivos de pacote (Packfiles)
- 10.5 Refspec
- 10.6 Protocolos de Transferência
- 10.7 Manutenção e Recuperação de Dados
- 10.8 Variáveis de Ambiente
- 10.9 Resumo
-
A1. Appendix A: O Git em Outros Ambientes
- A1.1 Interfaces Gráficas
- A1.2 Git no Visual Studio
- A1.3 Git no Visual Studio Code
- A1.4 Git no IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git no Sublime Text
- A1.6 Git no Bash
- A1.7 Git no Zsh
- A1.8 Git no PowerShell
- A1.9 Resumo
-
A2. Appendix B: Incorporando o Git nos seus Aplicativos
- A2.1 Linha de Comando do Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Appendix C: Comandos do Git
- A3.1 Configuração e Ajustes
- A3.2 Obtendo e Criando Projetos
- A3.3 Snapshots Básicos
- A3.4 Branches e Merges
- A3.5 Compartilhando e Atualizando Projetos
- A3.6 Inspeção e Comparação
- A3.7 Depuração
- A3.8 Patches
- A3.9 E-mail
- A3.10 Sistemas Externos
- A3.11 Administração
- A3.12 Comandos de Encanamento
3.2 Ramificação (Branching) no Git - Ramificação (Branching) e Mesclagem (Merging) Básicas
Ramificação (Branching) e Mesclagem (Merging) Básicas
Vamos passar por um exemplo simples de ramificação (branching) e mesclagem (merging) com um fluxo de trabalho que você pode usar no mundo real. Você seguirá as seguintes etapas:
-
Fazer algum trabalho em um site.
-
Criar um branch para uma nova história de usuário (user story) na qual você está trabalhando.
-
Fazer algum trabalho naquele branch.
Nesta fase, você receberá uma chamada informando que outro problema é crítico e você precisa de um hotfix. Você fará o seguinte:
-
Mudar para o seu branch de produção.
-
Criar um branch para adicionar o hotfix.
-
Depois que for testado, mesclar (merge) o branch de hotfix e enviar (push) para produção.
-
Mudar de volta para a sua história de usuário original e continuar trabalhando.
Ramificação Básica
Primeiro, digamos que você esteja trabalhando no seu projeto e já tenha alguns commits no branch master.
Você decidiu que vai trabalhar na issue #53 em qualquer sistema de rastreamento de problemas (issue-tracking) que a sua empresa utilize.
Para criar um novo branch e mudar para ele ao mesmo tempo, você pode executar o comando git checkout com a chave (switch) -b:
$ git checkout -b iss53
Switched to a new branch "iss53"
Isso é um atalho para:
$ git branch iss53
$ git checkout iss53
Você trabalha no seu site e faz alguns commits.
Fazer isso move o branch iss53 para frente, porque você fez checkout dele (ou seja, seu HEAD está apontando para ele):
$ vim index.html
$ git commit -a -m 'Create new footer [issue 53]'
iss53 avançou com o seu trabalhoAgora você recebe a chamada de que há um problema com o site e você precisa corrigi-lo imediatamente.
Com o Git, você não precisa implantar (deploy) a sua correção junto com as alterações da iss53 que você fez, e não precisa fazer muito esforço para reverter essas alterações antes de poder trabalhar na aplicação da sua correção ao que está em produção.
Tudo o que você precisa fazer é mudar de volta para o seu branch master.
No entanto, antes de fazer isso, observe que se o seu diretório de trabalho ou a área de preparação tiverem alterações não commitadas que conflitam com o branch para o qual você está fazendo o checkout, o Git não deixará você mudar de branch.
É melhor ter um estado de trabalho limpo quando você muda de branch.
Existem maneiras de contornar isso (como, por exemplo, o stashing e a alteração de commits) que abordaremos mais tarde, em Fazendo Stash e Limpando.
Por enquanto, vamos assumir que você fez commit de todas as suas alterações, então você pode mudar de volta para o seu branch master:
$ git checkout master
Switched to branch 'master'
Neste ponto, o diretório de trabalho do seu projeto está exatamente da mesma forma que estava antes de você começar a trabalhar na issue #53, e você pode se concentrar no seu hotfix. Este é um ponto importante a ser lembrado: quando você muda de branch, o Git redefine (resets) seu diretório de trabalho para que ele fique como na última vez em que você fez commit naquele branch. Ele adiciona, remove e modifica arquivos automaticamente para garantir que a sua cópia de trabalho seja exatamente como o branch estava no seu último commit nele.
Em seguida, você tem um hotfix a fazer.
Vamos criar um branch hotfix no qual trabalharemos até que seja concluído:
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'Fix broken email address'
[hotfix 1fb7853] Fix broken email address
1 file changed, 2 insertions(+)
master
Você pode executar os seus testes, certificar-se de que o hotfix é o que você deseja, e, finalmente, mesclar o branch hotfix de volta para o seu branch master para implantar na produção.
Você faz isso com o comando git merge:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
Você notará a frase “fast-forward” (avanço rápido) nessa mesclagem.
Como o commit C4 apontado pelo branch hotfix que você mesclou estava diretamente à frente do commit C2 em que você está, o Git simplesmente move o ponteiro para a frente.
Em outras palavras, quando você tenta mesclar um commit com um commit que pode ser alcançado seguindo o histórico do primeiro commit, o Git simplifica as coisas movendo o ponteiro para a frente, pois não há trabalho divergente a ser mesclado — isso é chamado de “fast-forward.”
A sua alteração agora está no snapshot do commit apontado pelo branch master, e você pode implantar a correção.
master é avançado (fast-forwarded) para hotfix
Depois que sua correção superimportante for implantada, você estará pronto para voltar ao trabalho que estava fazendo antes de ser interrompido.
No entanto, primeiro você excluirá o branch hotfix, pois não precisa mais dele — o branch master aponta para o mesmo lugar.
Você pode excluí-lo com a opção -d do comando git branch:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
Agora você pode voltar ao seu branch de trabalho em andamento na issue #53 e continuar trabalhando nela.
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'Finish the new footer [issue 53]'
[iss53 ad82d7a] Finish the new footer [issue 53]
1 file changed, 1 insertion(+)
iss53
Vale ressaltar aqui que o trabalho que você fez no seu branch hotfix não está contido nos arquivos do seu branch iss53.
Se você precisar incorporá-lo (pull it in), você pode mesclar (merge) o seu branch master para dentro do seu branch iss53 executando git merge master, ou pode esperar para integrar essas alterações até decidir incorporar o branch iss53 de volta ao master mais tarde.
Mesclagem (Merging) Básica
Suponha que você decidiu que seu trabalho na issue #53 está completo e pronto para ser mesclado (merged) no seu branch master.
Para fazer isso, você mesclará seu branch iss53 no master, de forma semelhante à mesclagem do seu branch hotfix anteriormente.
Tudo o que você precisa fazer é fazer checkout do branch para o qual deseja mesclar (merge into) e depois executar o comando git merge:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Isso parece um pouco diferente da mesclagem do hotfix que você fez anteriormente.
Neste caso, o seu histórico de desenvolvimento divergiu de algum ponto anterior.
Como o commit do branch em que você está não é um ancestral direto do branch que você está mesclando, o Git tem que fazer algum trabalho.
Nesse caso, o Git faz uma simples mesclagem de três vias (three-way merge), usando os dois snapshots apontados pelas pontas dos branches (branch tips) e o ancestral comum aos dois.
Em vez de apenas mover o ponteiro do branch para a frente, o Git cria um novo snapshot que resulta dessa mesclagem de três vias (three-way merge) e cria automaticamente um novo commit que aponta para ele. Isso é conhecido como um merge commit (commit de mesclagem), e é especial porque tem mais de um pai.
Agora que o seu trabalho foi mesclado (merged), você não tem mais necessidade do branch iss53.
Você pode fechar a issue no seu sistema de rastreamento de problemas e excluir o branch:
$ git branch -d iss53
Conflitos Básicos de Mesclagem (Merge Conflicts)
Ocasionalmente, esse processo não ocorre sem problemas.
Se você alterou a mesma parte do mesmo arquivo de forma diferente nos dois branches que está mesclando, o Git não será capaz de mesclá-los de forma limpa (cleanly).
Se a sua correção para a issue #53 modificou a mesma parte de um arquivo que o branch hotfix, você terá um conflito de mesclagem (merge conflict) parecido com este:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
O Git não criou automaticamente um novo merge commit.
Ele pausou o processo enquanto você resolve o conflito.
Se você quiser ver quais arquivos não foram mesclados (unmerged) em qualquer ponto após um conflito de mesclagem, você pode executar o git status:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Qualquer coisa que tenha conflitos de mesclagem e não tenha sido resolvida é listada como não mesclada (unmerged). O Git adiciona marcadores de resolução de conflitos padrão aos arquivos que têm conflitos, para que você possa abri-los manualmente e resolver esses conflitos. O seu arquivo contém uma seção parecida com esta:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
Isso significa que a versão no HEAD (seu branch master, porque era esse que você havia feito checkout quando executou o comando merge) é a parte superior daquele bloco (tudo acima de =======), enquanto a versão no seu branch iss53 se parece com tudo o que está na parte inferior.
Para resolver o conflito, você deve escolher um lado ou o outro ou mesclar o conteúdo você mesmo.
Por exemplo, você pode resolver esse conflito substituindo o bloco inteiro por isso:
<div id="footer">
please contact us at email.support@github.com
</div>
Essa resolução tem um pouco de cada seção, e as linhas <<<<<<<, ======= e >>>>>>> foram completamente removidas.
Depois de resolver cada uma dessas seções em cada arquivo em conflito, execute git add em cada arquivo para marcá-lo como resolvido.
Preparar o arquivo (staging) marca-o como resolvido no Git.
Se você quiser usar uma ferramenta gráfica para resolver esses problemas, você pode executar o git mergetool, que aciona uma ferramenta de mesclagem visual apropriada e o guia através dos conflitos:
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
Se você quiser usar uma ferramenta de mesclagem diferente da padrão (o Git escolheu opendiff neste caso porque o comando foi executado no macOS), você pode ver todas as ferramentas suportadas listadas no topo após “one of the following tools.”
Basta digitar o nome da ferramenta que você prefere usar.
|
Note
|
Se você precisar de ferramentas mais avançadas para resolver conflitos de mesclagem complicados, cobriremos mais sobre mesclagem em Merging Avançado. |
Depois de sair da ferramenta de mesclagem, o Git pergunta se a mesclagem foi bem-sucedida.
Se você disser ao script que sim, ele prepara (stages) o arquivo para marcá-lo como resolvido para você.
Você pode executar git status novamente para verificar se todos os conflitos foram resolvidos:
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
Se você estiver satisfeito com isso e verificar que tudo o que tinha conflitos foi preparado (staged), você pode digitar git commit para finalizar o merge commit.
A mensagem de commit, por padrão, se parece com isto:
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
Se você acha que seria útil para outras pessoas analisarem essa mesclagem no futuro, você pode modificar esta mensagem de commit com detalhes sobre como você resolveu a mesclagem e explicar por que você fez as alterações que fez, se elas não forem óbvias.