Git: Trabalhando em mais de uma branch simultaneamente com o comando git worktree

Há vezes em que estamos trabalhando numa branch e precisamos corrigir algo em outra sem perder o que foi feito na que estamos, e para isso o fluxo é simples:
“stash” na atual, checkout para a outra, modificar, commitar, depois checkout para a antiga, “stash pop”, continuar o trabalho.
Mas, apesar de ser simples, esse fluxo pode dar alguns problemas, como por exemplo fazer com que você perca tempo resolvendo conflitos na hora do “stash pop” dentre outras chateações.
Justamente para ajudar nisso existe o comando “git worktree”, que nos permite trabalhar em mais de uma branch por vez, cada uma em uma pasta separada.

Sem mais delongas, vamos criar um repositório de teste:

$ mkdir teste
$ cd teste
$ git init .
Initialized empty Git repository in /home/josiel/teste/.git/
$ echo "teste">a.txt
$ git add a.txt
$ git commit -a -m 'Primeiro commit'
[master (root-commit) 7e4df68] Primeiro commit
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt
$ mkdir branches

Até aí nenhum segredo:

  • Criamos e mudamos para o diretório “teste”
  • Iniciamos um repositório
  • criamos e adicionamos o arquivo “a.txt”
  • Commitamos esse arquivo
  • Criamos um diretório para armazenar os branches separados; lembre-se de não adicioná-lo ao git com o comando git add.

Adicionando uma worktree: git worktree add

Para adicionar uma worktree, usamos o comando git worktree add:

git worktree add <diretório> <branch existente>
git worktree add -b <nova branch> <diretório>

Como você pode notar coloquei acima duas sintaxes para o comando:
A primeira você cria a worktree para uma branch que já existe.
Já a segunda você cria a worktree e a branch.

Vamos para a linha de comando adicionar uma worktree:

$ git status
On branch master
nothing to commit, working tree clean
$ git worktree add -b b1 branches/b1
Preparing branches/b1 (identifier b1)
HEAD is now at 7e4df68 Primeiro commit
$ cd branches/b1
$ git status
On branch b1
nothing to commit, working tree clean

Bom, apartir daí já estamos trabalhando em duas branches ao mesmo tempo: master e b1.
Se quiser ir para a master, só usar o comando cd ../...
Se quiser ir para a b1, só digitar cd branches/b1.

$ echo "modificado apartir de b1">a.txt
$ git status
On branch b1
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
        modified:   a.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'Gravada modificacao'
[b1 00f66c5] Gravada modificacao
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git status
On branch b1
nothing to commit, working tree clean
$ cd ../..
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        branches/
nothing added to commit but untracked files present (use "git add" to track)

Na verdade, a raiz do repositório pode estar em qualquer branch. Aqui estamos na master.
Repare que na raiz o comando git status diz que temos o diretório “branches” e que ele não foi adicionado ao projeto.
Eu prefiro criar o diretório que irá guardar os branches separados dentro do diretório do repositório e tomar o cuidado de não adicioná-lo, mas você pode criar onde quiser e não ter essa preocupação.

Listando as worktrees: git worktree list

Para ver as worktrees, basta usar o comando git worktree list:

$ git worktree list
/home/josiel/teste              7e4df68 [master]
/home/josiel/teste/branches/b1  00f66c5 [b1]

A tabela é simples: A primeira coluna é o diretório, a segunda é o hash do último commit e a terceira é o nome da branch.

Para um formato mais legível, use a opção --porcelain do comando:

$ git worktree list --porcelain
worktree /home/josiel/teste
HEAD 7e4df68df280ea6b0a2af5aae09d99ab511b4aa8
branch refs/heads/master
worktree /home/josiel/teste/branches/b1
HEAD 00f66c58f4c5e5e3dd68b30d8195e3cf2c1603ff
branch refs/heads/b1

Removendo uma worktree: git worktree prune

Para remover uma worktree, primeiro remova a pasta e depois use o comando git worktree prune na raiz do repositório:

$ rm -rf branches/b1
$ git worktree prune

Repare que a branch “b1” não foi removida.

$ git branch
  b1
* master

Então você pode fazer o merge pra master, fazer checkout, criar outra worktree, etc.

Fim

Bom, é isso. Espero que esse post tenha sido útil.
O comando git worktree tem algumas particularidades que não coloquei no texto. Para conhecê-las digite git help worktree e veja a documentação completa do comando.

Qualquer dúvida, sugestão, erro ou elogio, deixe nos comentários, e aproveite também para contar em quais casos você acha útil trabalhar em mais de uma branch ao mesmo tempo!
Até a próxima!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *