GIT - Commits Semânticos
Tags: git, commits, beginners, programming
Published: 2022-01-24 14:11:50

![Commits Semânticos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6x77n0t160o5xabgy2l.png)
 

Uma pequena mudança no seu estilo de inserir uma mensagem em seus `commits` pode torná-lo um programador melhor.‎... é com frase que começamos este post

Um dos grandes desafios que a área de tecnologia enfrenta atualmente é prestar manutenção em um ambiente heterogêneo de equipe, onde diversos desenvolvedores implementam novas funcionalidades e correções a todo instante. A sustentação de uma aplicação é tão complexa quanto o seu desenvolvimento.

Para ajudar nesse cenário e facilitar o atendimento de tarefas, é fundamental processos padronizados de execução, que podem ser obtidos através da utilização de conceitos de **Clean Architecture** e **Patterns**. Porém, tais processos não se limitam somente a utilização de melhores práticas na arquitetura de desenvolvimento, mas sim, em um conceito claro que deve estar impregnado na cultura do time de desenvolvimento.

### A padronização de Commits

Então, nada melhor do que implantar métodos consistentes e organizados desde as execuções iniciais, os quais incluem a padronização de `commits` nos processos de versionamento e alterações no código. Com esse intuito, que se definiu a especificação de **Commits Semânticos** (em inglês Conventional Commits) para permitir uma organização no processo de `commits` dos códigos no desenvolvimento de softwares. E caso você não saiba do que estamos falando, vamos voltar uma casa e explicar, afinal de contas, o que é `commit`:

Em ciência da computação e gerenciamento de dados, um `commit` é a realização de um conjunto de mudanças provisórias permanentes, marcando o fim de uma transação e proporcionando durabilidade às transações ACID.

### O que é Commit num Sistema de Controle de Versão?

Em sistemas de controle de versão, como o Git, um `commit` adiciona as alterações mais recentes do código-fonte para o repositório, tornando essas alterações parte da revisão principal do repositório.

É importante ressaltar que os `commits` nos sistemas de controle de versão são mantidos no repositório **indefinidamente, a**ssim, quando outros usuários fizerem uma atualização ou `check-out`  no repositório, eles receberão a última versão confirmada.

Os sistemas de controle de versão permitem reverter facilmente para versões anteriores. Nesse contexto, **um** `commit` **dentro de um sistema de controle de versão é protegido**, pois é facilmente revertido, mesmo após o `commit` ter sido aplicado.

### Como fazer Commit no Git

Para “commitar” no git, basta executar o comando:

```bash
$ git commit -m 'mensagem do commit'
```

Isso também pressupõe que os arquivos no diretório atual foram testados da seguinte forma:

```bash
$ git add .
```

O comando acima adiciona todos os arquivos no diretório de trabalho a serem testados para o git commit. 

Depois que o `commit` foi aplicado, a última etapa é enviar o `commit` para o repositório, no caso abaixo nomeado ‘Jhony’, para o `branch`  `master` :

```bash
$ git push Jhony master
```

Você também pode optar por um atalho e adicionar todos os arquivos não testados e fazer um commit ao mesmo tempo com o comando:

```bash
$ git commit -a -m 'commit message'
```

### Como começou esta história de Commits Semânticos?

Convém ressaltar que não existe uma única fonte que defina o início deste conceito. Mas, as especificações do *Conventional Commits* é inspirada nas diretrizes do  *Angular Commit Guidelines*, que definiu normativas para confirmações no Git introduzidas no Angular Project. Sendo que o primeiro rascunho desta especificação visava possibilitar a análise de mensagens de confirmação convencionais nos históricos do Git, de maneira ordenada e estruturada.

Entre os projetos atuais, que procuram alavancar o conceito e normatizar o processo, se destaca o Conventional Commits, uma iniciativa que traz consigo uma tentativa de oficializar essa convenção na padronização de `commits` .

Em sua apresentação inicial, disponível no site mantido pela comunidade, o Commit Semântico se define como: “**uma especificação que possui o intuito de adicionar significado legível para humanos e máquinas no commit de mensagens**”..

### O que são Commits Semânticos?

**Commit semântico** ou **conventional commit**, em sua especificação formal, é uma das formas que se pode fazer padronização de commits dentro de um projeto de desenvolvimento de software.

Isso, utilizando regras simples e claras, que apesar de introduzirem uma pequena carga adicional de trabalho, irá contribuir para que seja reduzido o tempo gasto em compreender como e por que algo foi feito em um alteração ou correção posterior.

E o melhor de tudo: mesmo que por outro membro do time de desenvolvedores.

### Por que usar Commits Semânticos?

É importante saber que toda metodologia necessita estar alinhada a cultura e processos do time, e para tanto sempre se prioriza a análise de adaptações que se façam necessárias para que melhor se encaixe nas necessidades de sua equipe de desenvolvedores.

Conceitualmente, para o processo de maturação, é fundamental que as diretrizes sejam objetivas e de rápida absorção proporcionando a equipe de desenvolvimento uma experiência transparente de compreensão.

A partir da abstração de prefixos e tipos comuns dos processos executados a utilização do ***pattern*** se torna intrínseco a equipe de forma natural e consistente.

Com isso resulta, como principal valor, em uma metodologia clara e organizada para a estrutura de `commits` no repositório de versionamento.

### Ganho de produtividade em equipes

Na rotina de um programador único, que trabalha sozinho em seus projetos, pode não parecer um grande ganho de produtividade.

Entretanto, em um contexto onde diversos programadores trabalham simultaneamente em um repositório centralizado a adoção de um padrão em todas as práticas do time, converge para um grande aumento de agilidade no atendimento das tarefas rotineiras.

A especificação do **Conventional Commits** é uma convenção simples para se utilizar nas mensagens de commit. Define-se um conjunto de regras para criar um histórico de commit explícito, o que facilita a criação de ferramentas automatizadas.

Esta convenção descreve os recursos, correções e modificações que estabelecem a compatibilidade nas mensagens de commit.

### Vantagens de se usar Commits Semânticos

Em sua página oficial, o Conventional Commits, enumera algumas das vantagens em sua adoção, são elas:

- Possibilitar a adoção de processos automatizados na geração de um *CHANGELOG* ou de release, o que resulta em uma documentação estruturada e consistente;
- Determinar automaticamente um aumento de versionamento semântico (com base nos tipos de `commits`).
- Comunicar a natureza das mudanças para colegas de equipe, o público e outras partes interessadas.
- Disparar processos de build e deploy.
- Facilitar a contribuição de outras pessoas em seus projetos, permitindo que eles explorem um histórico de commits mais estruturado
- O **Conventional Commit** encoraja a se realizar mais commits de tipos específicos, por exemplo correções.
- A flexibilidade do Conventional Commits permite que sua equipe crie seus próprios tipos e altere ao longo do tempo.

### Commits Atômicos

Uma das principais definições da metodologia é de que as tarefas devem ser divididas em átomos: **atomic commits**, que se consistem de unidades objetivas que implementam uma única funcionalidade, ou tratam a correção de um único erro.

Ou seja, a cada correção ou implantação individual se deve executar um processo de commit, algo que segue outro conceito do **Clean Architecture**, o *Single Responsiblity Principle do SOLID*.

### A estrutura dos Commits Semânticos

A estrutura de um commit semântico é claro e de fácil identificação, pois utiliza um formato definido na sua sintaxe, possuído partes obrigatórias e outras opcionais.

Abaixo, descreve-se uma estrutura básica de um commit semântico, contendo as partes obrigatórias: tipo e descrição; e as partes opcionais: escopo, corpo e rodapé.

Quanto mais completo o formato do commit maior será o tempo em seu processamento.

Portanto, recomenda-se seu uso simplificado, não utilizando suas partes opcionais. Há casos específicos que necessitam um maior descritivo do processo executado.

```bash
<tipo>[escopo opcional]: <descrição>
<corpo opcional>
<rodapé opcional>
```

### Tipos

A primeira e principal descrição de um commit semântico, refere-se a seu tipo, os quais possuem a finalidade de comunicar a intenção de processamento que o utilizador teve em sua execução.

Abaixo será enumerado os principais types descritos na documentação do *Angular Commit Message Guidelines*:

1. `build:`Alterações que afetam o sistema de construção ou dependências externas (escopos de exemplo: gulp, broccoli, npm),
2. `ci:` Mudanças em nossos arquivos e scripts de configuração de CI (escopos de exemplos: Travis, Circle, BrowserStack, SauceLabs);
3. `docs:` referem-se a inclusão ou alteração somente de arquivos de documentação;
4. `feat:` Tratam adições de novas funcionalidades ou de quaisquer outras novas implantações ao código;
5. `fix:` Essencialmente definem o tratamento de correções de bugs;
6. `perf:` Uma alteração de código que melhora o desempenho;
7. `refactor:` Tipo utilizado em quaisquer mudanças que sejam executados no código, porém não alterem a funcionalidade final da tarefa impactada;
8. `style:` Alterações referentes a formatações na apresentação do código que não afetam o significado do código, como por exemplo: espaço em branco, formatação, ponto e vírgula ausente etc.);
9. `test:` Adicionando testes ausentes ou corrigindo testes existentes nos processos de testes automatizados (TDD);
10. `chore:` Atualização de tarefas que não ocasionam alteração no código de produção, mas mudanças de ferramentas, mudanças de configuração e bibliotecas que realmente não entram em produção;
11. `env:` basicamente utilizado na descrição de modificações ou adições em arquivos de configuração em processos e métodos de integração contínua (CI), como parâmetros em arquivos de configuração de containers.

Também, o Guidelines, recomenda o tipo improvement para commits que melhoram uma implementação atual sem adicionar um novo recurso ou consertar um bug.

Observe que esses tipos não são obrigatórios pela especificação do Conventional Commits.

Reforço que estes são os principais tipos utilizados, mas existem outros diversos que podem ser empregados e também serem adequados a necessidade de sua equipe de desenvolvimento.

### Escopos

Um escopo pode ser adicionado ao tipo do commit, sendo um parâmetro opcional, para fornecer informações contextuais adicionais e está contido entre parênteses, por exemplo feat(parser): adiciona capacidade de interpretar arrays.

Normalmente, a utilização do escopo acontece em commits específicos e pontuais, os quais necessitam especificar o contexto imediato da mudança executada pelo commit, como em um módulo de login, middleware ou profile.

Por exemplo, um processo de refactor nas configurações de rotas do módulo de login de seu projeto. Poderíamos descrever, utilizando o escopo, da seguinte forma o nosso commit semântico:

```bash
feat(login/routes): change in route settings for the login
```

### Descrições

As descrições se trata de um dos parâmetros obrigatórios da sintaxe, e devem ser preferencialmente apresentadas com letras minúsculas, e obrigatoriamente iniciando com letra minúscula, suportando letras maiúsculas em descrição de arquivos ou classes específicas.

Também devem ser suficientemente claras, utilizando seu espaço até o máximo permitido da linha.

```bash
test: ensure DbLoadSurveys throws if LoadSurveysRepository throws
```

### Corpo

O corpo, por sua vez, caracteriza-se por ser opcional e raramente recomendado sua utilização.

Resumindo-se em casos que necessitem de uma apresentação mais completa do conteúdo implantado no commit, o qual a descrição anterior não foi o suficiente para elucidar e esclarecer.

Podendo conter descrições mais precisas do que está contido no commit, apresentando impactos e os motivos pelos quais foram empregadas as alterações no código, como também instruções essenciais para intervenções futuras.

O corpo DEVE iniciar com uma linha em branco após a descrição. Um corpo de confirmação é de forma livre e pode consistir em qualquer número de parágrafos separados por nova linha.

```bash
feat: ensure LoadSurveysController returns 204 if there is no content
- Returns code 204 if the search load method does not return content
```

### Rodapé

Por fim o rodapé também não possui uso obrigatório. Restringindo-se às alterações de estado via smart *commit*, como resoluções de problemas (issues), através de chamados de atendimentos, ou sprints de projetos de implantação os quais podem ser descritos no rodapé.

Pode ser fornecido um ou mais rodapés, o primeiro sempre iniciando uma linha em branco após o corpo. Cada rodapé deve consistir em um token de palavra, seguido pelo símbolo **“:”** (dois pontos) e posteriormente um espaço em branco e o símbolo **“#”** (sustenido) como separador da string descritiva do rodapé (conceito inspirado na convenção do Git Trailer).

O token de um rodapé DEVE usar o símbolo **“-”** (hífen) no lugar de caracteres de espaço em branco, por exemplo, **Reviewed-by**, permitindo uma diferenciação de um rodapé em relação a um corpo com vários parágrafos.

```bash
fix: correct minor typos in code
see the issue for details
on typos fixed.
Reviewed-by: Elisandro Mello
Refs #133
```

Pronto, agora você já sabe o que precisa sobre commits semânticos!

⚠ Vale ressaltar que, de forma gradativa, pode-se introduzir e adequar a padronização à cultura de seu time de desenvolvimento, ou mesmo ao seu uso pessoal.

Fontes onde pesquisei esse conteúdo:

- https://www.conventionalcommits.org/en/v1.0.0/