Git patch: Compartilhamento de commits além do remote
Published: 2021-09-13 12:41:10

Certa feita passei por uma situação corriqueira: Fiquei sem acesso ao repositório do projeto da equipe. Até aí nada de extraordinário, imagino que todos os devs que estão lendo isso já passaram por isso. O problema real era que eu precisava entregar uma tarefa urgente que iria para produção assim que ela estivesse revisada pelos meus pares (aquele pr básico).
Após passar o pânico inicial e solicitar novamente os acessos, comecei a pensar como poderia fazer esse commit sem precisar encaminhar todos os arquivos alterados para alguém que tivesse acesso ao repositório e pudesse subir o trabalho feito. Relembrando minha época de estudo mais aprofundado do git (leiam o [livro oficial do git](https://git-scm.com/book/en/v2)), lembrei que o kernel do Linux é versionado a partir de arquivos de commits, ou patch files, e enviados por e-mail para serem revisados e restaurados no repositório principal (que não possui acesso a partir da internet). Uma vez que a linha de raciocínio estava feita, fui para a [documentação oficial](https://git-scm.com/docs) pensando:
> *Isso vai dar trabalho*

Qual foi a minha surpresa ao descobrir que bastam 2 comandos para fazer tal operação.

## Gerando os arquivos
O primeiro comando que deve ser rodado é o [git format-patch](https://git-scm.com/docs/git-format-patch). Ele é responsável por gerar os arquivos .patch. Cada commit irá gerar um arquivo .patch.

```shell
git format-patch -<n> -o <diretorio-de-destino-arquivo> <hash-commit>
```
Explicando rápidamente cada parâmetro:
- **-\<n\>**: A quantidade de commits anteriores ao commit informado que devem ser exportados. 
- **\<hash-commit\>**: Representa o último commit que deve ser exportado. Commits acima dele não serão exportados.
- -o \<diretorio-de-destino-arquivo\> (opcional): Utilizado para informar onde o arquivo .patch deve ser salvo. O padrão é no próprio diretório.

## Inserindo os arquivos .patch na árvore de commits
Agora que os arquivos .patch foram gerados, o próximo passo é adicioná-los à árvore de commits. Para isso utilizamos o comando [git am](https://git-scm.com/docs/git-am)

```shell
git am patch-commits/0001-Adiconadas-mais-motoriza-es-a-base.patch
```

Se for mais de um arquivo
```shell
git am patch-commits/000*.patch
```

Caso seja necessário revisar o arquivo de patch antes de aplicálo na árvore basta adicionar a opção -i:
```shell
git am -i patch-commits/000*.patch
```
Assim, cada arquivo de patch vai ser exibido da seguinte forma:
```shell
Commit Body is:
--------------------------
Instrucoes de como rodar o mongo
--------------------------
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: 
```

## Impressões e Conclusão
É interessante ver como determinadas coisas que estudamos e não damos importância podem nos salvar algum dia. Quando li sobre o assunto de commits sendo enviados por e-mail achei cômico como o kernel do sistema operacional mais utilizado do mundo era versionado.No entanto, foi uma informação que se provou útil no final das contas.
Muitas vezes uma informação não vai ser a resolução do problema, mas é ela quem dará a linha de raciocínio para a solução.

No github (pasta patch-commits) deixei o passo a passo de como reproduzir esse post.
{%github https://github.com/julianopoveda/mongoblogposts no-readme %}

Enquanto revisava o material para este post me deparei com uma dúvida:
> E se eu não quiser aplicar os commits diretamente na árvore, mas quiser colocá-los em stage e revisar o código em uma ferramenta mais amigável que o console?

Essa dúvida vou responder no próximo post ;)

## Referências
https://git-scm.com/docs/git-format-patch
https://git-scm.com/docs/git-am