Como você coloca diferentes versões da sua biblioteca sob controle de versão? Você usa tags? Ou galhos? Ou outro método?

24

Recentemente, comecei a colocar meu código sob controle de versão (no laboratório em que estou trabalhando, no SVN, e meus próprios códigos no github (obviamente com o git)). Antes de usar o controle de versão, eu costumava fazer algo assim. Eu tinha uma pasta com o nome da biblioteca, dentro de muitas pastas com o número da versão. Toda vez que eu queria começar a trabalhar em uma versão mais recente, fazia uma cópia da última versão, mudava o nome para a nova versão e começava a implementar.

No entanto, isso parece redundante quando a pasta é colocada sob controle de versão. Além de redundância, se alguém quiser obter a versão mais recente, eles estariam baixando todas as versões se ele simplesmente imports / clones.

Agora vejo muitas maneiras de fazer isso com o controle de versão, mas, como sou novo, não sei qual seria mais sustentável.

Método 1: usando tags

Se eu entendesse as tags corretamente, você teria sua ramificação principal, confirmará qualquer alteração que tiver e as marcará com uma versão. Então, quando você deseja obter uma cópia de trabalho, obtém a que possui uma determinada tag. (Corrija-me se eu estiver errado)

Método 2: versões de ramificação

Nesse método, o ramo principal seria o ramo de desenvolvimento. De vez em quando é feita uma versão estável (digamos v1.2.0), você cria um ramo para essa versão e nunca se compromete com ela. Dessa forma, se você deseja fazer o download de uma determinada versão, obtém o código dessa ramificação. Embora eu tenha dito que você nunca se compromete com isso, talvez seja possível fazer correções de bugs e se comprometer com o ramo de uma versão antiga para manter a versão antiga em execução. Por exemplo, se a versão atual é v2.0, mas existem pessoas que desejam usar v1.2, você pode obter outro ramo v1.2, a saber, v1.2.1e confirmar as correções de bugs, ou apenas manter a versão igual v1.2e confirmar as correções.

Então os galhos ficariam assim:

                  v1.2.1  v1.2.2
                 /       /
 v1.0.0   v1.2.0---------     v2.0.0
/        /                   /
-------------------------------------- dev

Dessa forma, você tem ramificações para cada atualização de versão secundária. (Observe que, no gráfico acima, as v1.2.1 e v1.2.2 ou criadas após o lançamento da v2.0.0, elas não faziam parte do desenvolvimento entre as v1.2.0 e a v2.0.0. Pense nisso como suporte para versões mais antigas)

Método 3: desenvolvimento de ramificação

Este método é o oposto do anterior. O ramo principal seria a versão estável mais recente. Sempre que você estiver trabalhando em uma nova versão, crie uma ramificação (para desenvolvimento), trabalhe no seu código e, quando estiver estável, junte-a à ramificação principal.

Nesse caso, os ramos ficariam assim:

 ________  ____  ________________  _____ dev
/        \/    \/                \/
---------------------------------- latest_version

Provavelmente este precisa ser feito em conjunto com tags, certo?

A questão!

Enfim, minha pergunta é: com base na sua experiência, qual desses métodos se mostra mais prático? Existe um método melhor conhecido por aí (que possivelmente eu não tenha descoberto)? Como essas coisas são comumente feitas?

Shahbaz
fonte

Respostas:

17

Tags e ramificações não são mútuas, você pode (e a IMO geralmente deve) usá-las. As tags existem para marcar marcos no desenvolvimento. Por exemplo, você abrir uma filial para a versão 1.2 do seu produto, e você marcar v1.2 Beta, RC1, RC2, Final(e depois, se necessário, SP1etc.) com tags em que mesmo ramo.

Pessoalmente, prefiro o Método 2 como a abordagem padrão (embora tente evitar vários níveis de ramificações, para manter a vida o mais simples possível). O método 1 simplesmente não funciona na vida real - as tags não são suficientes, você precisa de ramificações. E o método 3 é inflexível, pois possui apenas uma única versão estável o tempo todo, portanto (a menos que você o combine com o Método 2), não é possível manter várias versões (mais recentes e mais antigas) em paralelo. Isso é necessário para quase todos os projetos na vida real - enquanto você trabalha na versão 2, você ainda deve poder publicar patches / atualizações para a v1.9 e, muitas vezes, até versões anteriores. Depende muito do tipo de aplicação, é claro. Desenvolvemos um aplicativo Web, para que exista apenas uma versão de produção em um determinado momento, ainda assim fazemos malabarismos com três versões diferentes (uma em produção, um está no UAT se preparando para implantação, um é a versão mais recente no tronco). Pode ser muito mais complexo para um aplicativo de desktop / cliente, com várias versões mais antigas sendo usadas - e mantidas - em paralelo.

Péter Török
fonte
Bem, como eu disse, o Método 3 pode ser combinado com tags, então você tem tags para confirmações estáveis. Não tenho certeza, se eu tenho as tags corretas, mas você marca uma confirmação e pode obter o repositório com a confirmação que tem essa marca? Se assim for, você tem muitas versões estáveis, mas eles estão no mesmo ramo (sob diferentes marcas)
Shahbaz
@ Shahbaz, sim, mas o ponto é que as versões marcadas são somente leitura, você não pode fazer alterações nelas. Isso significa que você não pode corrigir erros em versões mais antigas enquanto desenvolve novos recursos no tronco.
Péter Török
Não se esqueça, você pode usar apenas tags e, se precisar voltar e consertar algo para uma versão antiga, poderá converter essa tag em um ramo quando precisar.
Chloe
6

Eu tinha uma pasta com o nome da biblioteca, dentro de muitas pastas com o número da versão.

Isso é efetivamente, como você observa, uma abordagem errada, já que você já possui o controle de versão para ... controlar as versões.

Agora, diferentes técnicas que você enumera parecem todas igualmente corretas. Você pode ler um artigo muito detalhado, Source Control Done Right , que inclui informações sobre tags e ramificações.

Arseni Mourzenko
fonte
Sim, o primeiro método era o que eu fazia antes de colocar meu código sob controle de versão. Vou ler o seu link e que você saiba
Shahbaz
O link foi ótimo. Eu tenho a sensação de que o método 2 é melhor (pelo menos para mim, que sou basicamente o único desenvolvedor das bibliotecas)
Shahbaz
3

Os três métodos não são mutuamente exclusivos e você deve combinar os três para tirar o máximo proveito do seu controle de versão.

Da minha parte, eu usaria uma combinação dos métodos 1 e 3 por padrão, ou seja, desenvolva em um recurso ou ramo de desenvolvimento até que um recurso esteja pronto para produção e depois volte ao tronco. Dessa maneira, o tronco sempre representa o estado atual do desenvolvimento estável a ser usado e pode ser vinculado com segurança por svn: projetos externos. Ao liberar uma versão, marque-a.

Gostaria apenas de ramificar sob demanda, ou seja, quando versões mais antigas da sua biblioteca têm um bug que precisa ser corrigido. Você pode criar facilmente esse ramo a partir da tag da versão quebrada. Ao não ramificar desnecessariamente, você mantém o número de galhos baixo e tem uma visão geral rápida das bordas sangrantes que devem ser mantidas (tronco e todos os galhos).

thiton
fonte
2

Eu usaria o método 2 . Usei isso e descobri que é uma maneira eficaz de gerenciar e manter várias versões, enquanto ainda permite que o desenvolvimento atual avance. Você também pode usar tags em conjunto com esse método, se precisar delas.

Veja minha resposta aqui para obter mais informações sobre o uso da ramificação para manter várias versões de lançamento.

Bernard
fonte