Hoje vou falar sobre algo bem interessante, que deixa o versionamento do nosso código bem organizado. Estão em dia com os assuntos `Semantic Version` e `Git flow`? Aposto que já utilizou essas regras, mas não tinha um conhecimento mais profundo sobre o assunto, ou já sempre utilizou seguindo à risca.Já conheço e sigo o `Git flow`, a um bom tempo. Inclusive um dos meus projetos no [github](https://github.com/doc-solutions/documentation-gitflow) é sobre a documentação do mesmo. Não reinventei a roda, é mais para ter um registro de fácil acesso, para futuras explicações ou consultas.Sobre `Semantic Version`, o [site oficial](http://semver.org/lang/pt-BR/) que está na versão `2.0.0`, explica com detalhes as regras.Estudando os conteúdos acima, basta ter uma disciplina inicial para os processos e regras.## Tomada de decisõesMuitas perguntas podem surgir na cabeça com algumas situações. Vou ilustrar algumas.1. Digamos que estamos na versão 2.2.0 na branch `master`. Estamos planejando um novo recurso (feature), então a próxima versão deve se tornar 2.3.0. Em seguida, o cliente relata um bug crítico, forçando-nos a preparar um `hotfix`. Nós corrigimos o bug e colidimos a versão para 2.2.1. Mas, dados os 'insights' obtidos com a correção do bug, agora percebemos que talvez precisamos quebrar a API pública para que a feature funcione da maneira que queremos. E se fizermos isso, não devemos mais colidir com a versão 2.3.0. Em vez disso, devemos mover para a versão 3.0.0.> **Regra:** A alteração de versão ocorre quando nós nos ramificamos do desenvolvimento para o release, ou quando nos ramificamos do master para a branch de hotfix.2. Convenção de nomenclatura na branch de `dev`. Uma vez que todas as mudanças nas outras branchs devem ser mescladas de volta para `dev`, acho que a nomeação deve refletir que `dev` é praticamente sempre a versão mais recente do produto. Por isso, é interessante usar a convenção `a.b.c-wip.d`, onde `wip` (work-in-progress) significa trabalho em andamento e `d` é o número da compilação (build).> **Regra:** Sempre certifique-se de que o número de versão na branch de dev está em sincronia com o número mais recente em qualquer branch de hotfix ou release.Exemplo:A branch de `dev` estava em 1.2.0-wip.123 quando criamos a branch `hotfix` (hotfix/1.2.1). Seguindo a última regra, quando nós juntamos de volta a branch de `dev`, ele é será 1.2.1-wip.x.Esta regra pode ficar complicada quando estamos trabalhando em um `hotfix` e uma branch de `release` simultaneamente. Na maioria dos casos, o número de versão da branch de `release` deve superar a de `hotfix`. Especialmente porque provavelmente queremos mesclar alterações da `hotfix` de volta para a branch de `release` antes de envolvê-lo.3. Convenções de nomenclatura nas branches de `release`. Eu não espero que os `releases` permaneçam nesta branch por muito tempo, então o ciclo de vida completo de alpha/beta/rc1/rc2 parece um exagero. No final, podemos usar o rc-prefixo, o que leva à seguinte notação: `a.b.c-rc.d`. Novamente, `d` é o número de compilação (build).Vamos continuar com o exemplo. Nós decidimos quebrar a API, então criamos uma nova branch de `release` (release/2.0.0). A primeira marca nesta branch deve então ser `2.0.0-rc.x`, onde `x` é o número de compilação. Mas o que deveria ser `x` neste caso? Isso traz a questão sobre quando o contador deve ser redefinido, se alguma vez.Vamos examinar uma alternativa:> **Alternativa:** Redefinir o contador de compilação sempre que o número de versão for colididoJuntamente com o número de versão, isso garante exclusividade. Também parece muito mais agradável, já que o número de compilação raramente atingirá além de três dígitos.No entanto, ele introduz um outro problema: lembrar de redefinir o contador sempre que você alterar o número da versão. Ou, se vamos para a automação completa, como detectar quando o número da versão mudou.> **Regra:** Assegure-se de que cada tag de controle de versão seja exclusivo no repositório.## Exemplo passo a passo| Atividade do projeto | Tag | | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | | O projeto começa, o master está vazio e estamos fazendo o commit do nosso primeiro recurso no desenvolvimento | 0.0.0-wip.1 | | É feito o commit da tarefa `A` na branch `develop` de uma branch `feature` | 0.0.0-wip.2 | | Correção rápida de erros diretamente no desenvolvimento | 0.0.0-wip.3 | | É feito o merge da tarefa `B` em `develop` de uma branch `feature` | 0.0.0-wip.4 | | Primeiro 'minor release'! Uma Branch é criada a partir de `develop` (release/0.1.0) e reseta o contador da compilação | 0.1.0-rc.1 | | Mais um commit foi necessário | 0.1.0-rc.2 | | Para manter o desenvolvimento sincronizado, fizemos o merge da branch 'release' de volta, criando um commit de mesclagem | 0.1.0-wip.3 | | Um membro da equipe faz um commit de um recurso `C` em `develop` | 0.1.0-wip.4 | | Release em produção: fizemos o merge de release/0.1.0 em `master` e `develop` | 0.1.0-release.5 0.1.0-wip.6 | | É feito um commit de uma pequena refatoração em `develop` | 0.1.0-wip.7 | | Um bug crítico é relatado na produção; Criar uma branch `hotfix` | hotfix/0.1.1 0.1.1-hotfix.1 | | É feito o merge da versão atualizada de volta para `develop` e assim evitar duplicação de tags (uma vez que o contador tem que ser redefinido) | 0.1.1-wip.2 | | Enquanto isso, outro commit de refatoração em `develop` | 0.1.1-wip.3 | | O `hotfix` é finalizado | 0.1.1-hotfix.4 | | A ser feito o merge para `master` e `develop` | 0.1.1-release.5 0.1.1-wip.6 | | É feito o merge de outra branch de `feature` em `develop` | 0.1.1-wip.7 | | Outra `minor release`. Criaremos a branch `release/0.2.0` de `develop` e resetamos o contador da compilação (build) | 0.2.0-rc.1 |## ConclusãoPode ficar confuso de início, se não estiver familiarizado com o processo. Mas nada melhor que a prática. Então, crie o seu repositório de testes e comece a praticar. Tendo mais exemplos para ilustrar, estarei atualizando esse artigo ou criando um novo sobre o assunto. Feedbacks e novos cenários, são bem-vindos.
Quando damos início a um projeto de programação, a primeira questão é aonde colocaremos os arquivos com os códigos. Quem nunca guardou em um disco externo ou em um disco virtual? O grande problema é quando temos mais de um desenvolvedor no projeto. Não temos um histórico de alterações e nem o autor, fora outras questões como revertar alguma implementação que estava com um `bug`.Para isso, temos o Git(o nome vem de uma gíria do Inglês Britânico para 'cabeça-dura', segundo a Git Wiki). O Git é um sistema de controle de versão(CVS), criado por Linus Torvalds, o criador do Linux.E temos o [Github](https://github.com/) e o [Bitbucket](https://bitbucket.org/), que são serviços de armazenamento de repositório Git. Assim, temos a ferramenta e onde armazenar. No **_Github_**, podemos ter repositórios gratuitamente, desde que sejam públicos, o serviço privado é pago. Quanto ao **_Bitbucket_**, podemos ter repositórios privados gratuitamente, desde que a equipe tenha no máximo 5 pessoas.O Git é baseado em linha de comando, para os amantes da utilização do terminal, ele agrada bastante. Mas se não é chegado, também tem ferramentas gráficas que ajudaram na utilização.Para utilizar o Git, primeiramente precisamos instalá-lo. Para mostrar as funcionalidades, vamos priorizar a linha de comando.## Instalação### WindowsPara a instalação, precisamos baixá-lo no [https://git-for-windows.github.io/](https://git-for-windows.github.io/).**_Uma dica_**: Eu instalo com o instalador [Rails Installer](http://www.railsinstaller.org/pt-BR), que ja vem com o `Ruby`, `Rails` e outros itens que já evitam o trabalho de instalá-los separadamente.### MacOSPara instalar no Mac OSX (Snow Leopard ou superior), basta baixá-lo em [http://sourceforge.net/projects/git-osx-installer/files/?source=navbar](http://sourceforge.net/projects/git-osx-installer/files/?source=navbar). Selecione a última versão.### LinuxPelo terminal, caso esteja no Fedora, você pode usar o yum:``` yum install git-core ```Ou se você estiver em um Debian, como o Ubuntu, use o apt-get:``` apt-get install git ```## Chave de segurançaVamos usar o `Github`, como exemplo. Crie uma conta se ainda não tiver.A chave de segurança será a identificação da máquina local que estará usando com o `Github`. Basta abrir o terminal(Git bash) e executar o commando:``` ssh-keygen -t rsa -C 'seu_email@seu_provedor.com' ```Irá aparecer:``` Enter file in which to save the key (/c/Users/tecnologia/.ssh/id_rsa): ```**_/c/Users/tecnologia/_**: na sua máquina aparecerá o caminho do seu usuário.Só pressionar a tecla `enter`, para manter no caminho padrão. Logo após, precisará informar a senha, que fica a seu critério informar ou não. E em seguida, a confirmação da mesma.``` Enter passphrase (empty for no passphrase): Enter same passphrase again: ```Aparecerá uma mensagem parecida com essa:``` Your identification has been saved in /c/Users/tecnologia/.ssh/id_rsa. Your public key has been saved in /c/Users/tecnologia/.ssh/id_rsa.pub. The key fingerprint is: ... ```Agora, precisaremos informar essa chave segura, na conta do `Github`. Nas configurações do seu perfil do `Github`, na seção [SSH Keys](https://github.com/settings/ssh), clique em `add SSH Key`. Basta informar um título e o conteúdo do seu arquivo `id_rsa.pub`, que foi gerado na sua máquina.Pronto! Temos o Git instalado e uma conta criada no `Github`. O processo para o `Bitbucket` é semelhante.## Clonando um repositórioSó é preciso criar um repositório no Github, para dar início e assim, clonar esse projeto criado.Digamos que criamos o repositório `teste`. No meu Github a url do projeto ficaria assim:``` https://github.com/ui2code/teste ```Pelo terminal(prompt de comando) na nossa máquina local, vamos entrar na pasta onde queremos que o projeto fique e iremos clonar(baixar os arquivos, juntamente com os arquivos de controle de versão do Git).``` cd /e/server/github/ git clone https://github.com/ui2code/teste.git ```No meu caso, a pasta ficará na minha unidade `E:`, dentro da subpasta `github`. Com o comando `git clone [url do projeto git]`, será baixado os arquivos. Agora precisamos entrar na pasta do projeto, que por padrão é o mesmo nome do projeto.``` cd teste ```Como acabamos de criar o repositório não tem nada nele, na pasta só terá uma pasta oculta `.git`.Você pode ver os arquivos do projeto navegando para a pasta 'repositorio' e listando os arquivos no prompt de comando:## Versionando alteraçõesTemos o nosso repositório na máquina e agora vamos criar algo, bem simples, como o `README.md`. Que é por padrão, onde colocamos as informações do projeto, por ser mostrado logo assim que entramos no respositório que fica no Github.Vamos agora brincar com o comando `touch` do Unix e criar o arquivo pelo terminal :``` touch README.md ```Com ele criado, faremos uma sequência de comandos para adicionar o novo arquivo ao `storage` e fazer o `commit` do mesmo para que seja criado um objeto com um `hash` de identificação da alteração no repositório.``` git add README.md git commit -m 'Primeiro commit' ```A flag `-m` com a mensagem entre aspas duplas, é para customizarmos a mensagem do commit.Agora precisamos jogar essa nossa alteração no repositório para o servidor. Para isso usaremos o comando `git push`( como é o nosso primeiro commit no repositório precisamos usar a flag `-u`, para fazer a ligação do branch local, com o branch remoto):``` git push -u origin master ```Por padrão o repositório principal é sempre o `master`, e quando jogamos para o servidor, precisamos informar qual é a origem. Criando outros branches a origem muda.``` // Branch dev git push origin dev ```ConclusãoEssa foi apenas uma introdução, onde vimos como instalar o Git na nossa máquina. Criar uma conta em um serviço de armazenamento Git. Clonar um projeto e fazer a nossa primeira alteração. Nos próximos artigos sobre o assunto, vamos ver mais os detalhes de como trabalhar com outros branches, fazer comparações, ver histórico, fluxo e etc..