Pergunta

A minha pergunta é sobre a maneira em que Git alças ramos:. Sempre que se ramificam a partir de um commit, este ramo nunca vai receber alterações do ramo pai a menos que você força com uma mesclagem

Mas em outros sistemas como nos Clearcase ou AccuRev, você pode especificar como ramos fiquem cheias de algum tipo de mecanismo de herança : Quero dizer, com Clearcase, usando um config_spec, você pode dizer “obter todas os arquivos modificados no ramo / main / issue001 e depois continuar com os que estão na / principal ou com essa linha de base específica”.

Em AccuRev você também tem um mecanismo semelhante que fluxos deixou-nos receber alterações de ramos superiores (córregos como eles chamam) sem fusão ou a criação de um novo commit no ramo.

Você não perca este enquanto estiver usando Git? você pode enumerar cenários onde esta herança é uma obrigação?

Graças

Atualizar Por favor, leia resposta VonC abaixo para realmente focar minha pergunta. Uma vez que estamos de acordo "de armazenamento linear" e DAG SCMs base têm capacidades diferentes, a minha pergunta é: que são os cenários da vida real (especialmente para empresas de mais de OSS), onde linear pode fazer as coisas não é possível para DAG? Será que eles valem?

Foi útil?

Solução

Para entender por que o Git não oferecer algum tipo de que você está se referindo a como um "mecanismo de herança" (não envolvendo um commit), você deve primeiro entender um dos core desses SCMs (Git vs. ClearCase por exemplo)

  • ClearCase utiliza um armazenamento versão linear : cada versão de um elemento (arquivo ou diretório) está ligada de forma direta linear relação com o da versão anterior do o mesmo elemento.

  • Git usa um DAG - Directed acíclico Graph : cada "versão" de um arquivo é na verdade parte de um conjunto global de mudanças em uma árvore que em si é parte de um commit. A versão anterior do que deve ser encontrado em um commit anterior, acessível através de um caminho único gráfico acíclico dirigido.

Em um sistema linear, uma configuração especificação pode especificar várias regras para a realização do "herança" que você vê (para um determinado arquivo, primeiro selecione uma determinada versão, e se não estiver presente, em seguida, selecione uma outra versão, e se não estiver presente, em seguida, selecione um terceiro, e assim por diante).

O ramo é um garfo em um linear história de uma determinada versão para uma determinada regra de seleção (todas as outras selecione regras antes que um ainda se aplicam, portanto, o efeito "herança")

Em um DAG, um commit representa toda a "herança" que você nunca vai chegar; não há seleção "cumulativa" de versões. Há apenas um caminho neste gráfico para selecionar todos os arquivos que você vai ver neste momento exato (commit).
Um ramo é apenas um novo caminho neste gráfico.

Para aplicar, em Git, algumas outras versões, você deve:

Mas desde que Git é um SCM-base DAG, ele vai sempre resultar em um novo commit.

O que você está "perdendo" com Git é algum tipo de "composição" (quando você está selecionando versões diferentes, com diferentes regras selecione sucessivas), mas isso não seria prático em um D VCS ( como em "distribuída"): quando você está fazendo um ramo com Git, você precisa fazê-lo com um ponto de partida e um teor claramente definida e facilmente replicado para outros repositórios

.

Em um VCS puramente central, você pode definir o seu espaço de trabalho (em ClearCase, a sua "visão", ou instantâneo ou dinâmico) com quaisquer regras que você deseja.


desconhecida-google acrescenta no comentário (e na sua pergunta acima):

Assim, uma vez que vemos os dois modelos pode conseguir coisas diferentes (linear vs DAG), a minha pergunta é: quais são os cenários da vida real (especialmente para empresas de mais de OSS), onde linear pode fazer coisas que não são possíveis de DAG? São eles vale a pena?

Quando se trata de "cenário da vida real" em termos de regras de seleção, o que você pode fazer em um modelo linear é ter vários regras de seleção para o mesmo conjunto de arquivos .

Considere isto "config spec" (ou seja, "especificação de configuração" para regras de seleção com ClearCase):

element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... aLabel2 -mkbranch myNewBranch

Ele seleciona todos os arquivos rotulados 'aLabel2' (e ramo de lá), exceto para aqueles rotulados 'aLabel3' - e ramo de lá - (porque essa regra precede the um mencionar 'aLabel2').

Vale a pena?

Não.

Na verdade, o sabor UCM do ClearCase (o " Unified Configuração Gestão " metodologia incluído com o produto ClearCase, e representando todas as 'melhores práticas' deduzidas do uso de base ClearCase) não permite que ele, por razões de simplificity . Um conjunto de arquivos é chamado de "componente", e se você quiser ramo para uma determinada etiqueta (conhecido como "linha de base"), que seria traduzido como este seguinte especificação de configuração:

element /aPath/... .../myNewBranch
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... /main/0 -mkbranch myNewBranch

Você tem que escolher um ponto de partida (aqui, 'aLabel3') e de lá ir. Se você quiser também os arquivos de 'aLabel2', você vai fazer uma mesclagem de todos os arquivos 'aLabel2' às de 'myNewBranch'.

Essa é uma "simplificação" você não tem que fazer com um DAG, onde cada nó do gráfico representa um "ponto de partida" definido exclusivamente para uma filial, qualquer que seja o conjunto de arquivos envolvidos.

Merge e rebase são suficientes para combinar esse ponto com outras versões de um determinado conjunto de arquivos, a fim de alcançar a "composição" desejado partida, mantendo que a história particular, em isolamento em um ramo .

O objetivo geral é a razão no " coerente operações de controle de versão aplicado a um coerente componente". Um conjunto "coerente" de arquivos é um em um estado coerente bem definida:

  • Se rotulados, todas seus arquivos são rotulados
  • se ramificado, todas seus arquivos vai ramificar da mesma única ponto de partida

Isso é feito facilmente em um sistema DAG; pode ser mais difícil em um sistema linear (especialmente com "ClearCase Base", onde o "config spec" pode ser complicado), mas ela é aplicada com a metodologia UCM dessa mesma ferramenta baseada linear.

Em vez de alcançar esse "composição" através de um "truque regra de seleção particular" (com ClearCase, alguns selecione ordem da regra), você alcançá-lo apenas com operações VCS (REBASE ou fusão), que deixam um rastro claro para todos a seguir (em oposição a uma configuração especificação privada para um desenvolvedor, ou compartilhado entre alguns, mas não todos os desenvolvedores). Mais uma vez, impõe um sentidos da coerência , em oposição a uma "flexibilidade dinâmica", que você pode ter um tempo difícil de reproduzir mais tarde .

Isso permite que você deixe o reino da VCS (Version Control System) e digite o reino da SCM (Software Configuration Management) , que se preocupa principalmente com " reprodutibilidade ". E que (recursos SCM) pode ser alcançado com uma linear baseada ou um VCS à base de DAG.

Outras dicas

Parece que o que você está procurando pode ser git rebase . Rebasing um ramo conceitualmente separa-lo de seu ponto de ramificação original e reata-lo em algum outro ponto. (Na realidade, o rebase é implementada através da aplicação de cada patch do ramo em sequência para o novo ponto de ramificação, criando um novo conjunto de patches.) No seu exemplo, você pode rebase um ramo para a ponta atual de um ramo superior, que será essencialmente "herdar" todas as mudanças feitas para o outro ramo.

Eu não estou totalmente claro sobre o que seu pedindo mas parece que o git semântica de rastreamento são o que você quer. Quando você ramificar de origem am você pode fazer algo como:

git -t -b my_branch origem / master

E então futuro "git pull" s origem vontade auto merge / master em sua ramo de trabalho. Você pode então usar "cereja git -v origem / master" para ver qual é a diferença. Você pode usar "git rebase" antes de publicar o mudanças para limpar a história, mas você não deve usar rebase uma vez sua história é público (ou seja, outras pessoas estão seguindo esse ramo).

Quanto ao esquema de herança utilizado por AccuRev: usuários GIT provavelmente "pegar" a coisa toda quando o olhada git-fluir (ver também: http://github.com/nvie/gitflow e http://jeffkreeftmeijer.com/2010/why-arent- you-usando-git-flow / )

Esta ramificação modelo GIT mais ou menos faz (manualmente / com a ajuda da ferramenta de git-fluxo) que AccuRev faz out-of-the-box automaticamente e com grande suporte GUI.

Assim, parece GIT pode fazer o que AccuRev faz. Desde que eu nunca realmente utilizado git / git-fluxo do dia-a-dia, eu realmente não posso dizer como ele funciona, mas ele faz parecem promissores. (Minus adequado suporte GUI: -)

Vou tentar responder-lhe perguntas. (Eu tenho que dizer aqui que eu não usei GIT ler sobre isso, por isso, se algo que eu menciono a seguir é errado, por favor me corrijam)

"Você pode enumerar cenários onde esta herança é uma obrigação?"

Eu não vou dizer que é uma obrigação, porque você pode resolver um problema com a ferramenta que você tem, e pode ser uma solução válida para o seu ambiente. Eu acho que é mais uma questão de processos do que a própria ferramenta. Ter certeza que seu processo é coerente e também permite que você voltar no tempo para reproduzir qualquer passo / estado intermediário é o objetivo, ea vantagem é que a ferramenta deixá-lo correr-lhe o seu processo e SCMP o mais simples possível

O único cenário que pode ver que é útil ter esta 'herança' comportamento e usar o poder da especificação de configuração, é quando você quiser que o seu conjunto de mudanças " isolado " mapeado para uma tarefa (devtask, CR, SR, ou o que define o objectivo / âmbito do seu aparelho de mudança)

Usando esta composição permite que você tenha o seu ramo de desenvolvimento limpo e ainda usam combinação diferente (usando composição) do resto do código, e ainda tem apenas o que é relevante para a tarefa isolado em um ramo durante o toda ciclo de vida da tarefa, apenas até a fase de integração.

Ser purista ter que cometer / merge / rebase apenas para ter um "ponto de partida definido", eu acho que seria ' polui ' seu ramo e você vai acabar com as alterações + outros mudanças na sua filial / conjunto de alterações.

Quando / Onde esse isolamento é útil? Os pontos abaixo só poderia fazer sentido no contexto das empresas que prossigam CMM e algumas certificações ISO, e pode ser de nenhum interesse para outro tipo de empresas ou OSS

  • Ser muito exigente, você pode querer contar com precisão as linhas de código (adicionado / modificado / eliminado) do conjunto de mudanças que corresponde a um único desenvolvedor, mais tarde usada como uma entrada para o código e esforço estimativas.

  • Pode ser mais fácil para rever o código em diferentes estágios, tendo apenas o seu código em um único ramo (não colados com outras mudanças)

Em grandes projetos com várias equipes e +500 desenvolvedores que trabalham ativamente simultaneamente no mesmo código base, (onde gráficos individuais elemento versão árvores parece um confuso emaranhado web com vários loadlines, um para cada grande cliente, ou um para cada tecnologia ) grandes características de configuração utilizando composição de vários graus de profundidade feitos esta quantidade de pessoas para trabalhar perfeitamente adaptar o / sistema (código de base mesmo produto) para fins diferentes. Usando esta especificação de configuração, de forma dinâmica deu a cada equipa equipe ou sub, uma visão diferente para o que eles precisam e de onde eles precisam ramo, (em cascata em vários casos) sem a necessidade de criação de ramos de integração intermediários, ou constantemente fusão e rebasing tudo os bits que você precisa para começar. Código da mesma tarefa / objetivo foi ramificação de etiquetas diferentes, mas fazia sentido. (Você pode discutir aqui o 'linha de base conhecida' como um princípio do SCM, mas rótulos simples contempladas no Plano de SCM escrito fez o trabalho) Deve ser possível para resolver isso com GIT (acho que de uma forma não dinâmica), mas eu acho realmente difícil de imagem sem este comportamento 'herança'. Eu acho que o ponto mencionado por VonC "se ramificados, todos os seus arquivos serão ramificar da mesma único ponto de partida" foi quebrado aqui, mas ao lado foi bem documentado na SCMP, eu me lembro havia razão de negócios forte para fazê-lo dessa maneira.

Sim construindo essas especificações de configuração que eu mencionei acima não era livre, no início lá onde 4-5 pessoas bem pagas por trás do SCM, mas foram posteriormente reduzido por scripts automatizados que você perguntou o que você quer em termos de rótulos / ramos / características e vai escrever o CS para você.

A reprodutibilidade aqui foi atingido por apenas salvar a configuração Spec juntamente com a tarefa nosistema devTask, de modo que cada tarefa a montante mapeado para requisitos, ea jusante mapeado para uma especificação de configuração, um conjunto de mudanças (arquivos de código, documentos de projeto, documentos de teste etc)

Assim, até aqui uma conclusão aqui pode ser, apenas se o seu projeto é grande / o suficiente complicado (e você pode pagar SC Managers ao longo da vida do projeto :)), então você só vai começar a pensar se você precisa do 'herança 'comportamento ou muito versátil ferramenta, caso contrário, você irá diretamente para aa ferramenta que é gratuito e já cuidar da coerência de vocês SCM ... mas pode haver outros fatores na ferramenta de SCM que podem fazer você furar a um ou a outro ... continue a ler ..

Algumas notas laterais, que podem estar fora de tópico, mas eu acho que em alguns casos como o meu precisam ser considerados.

Eu tenho que acrescentar aqui que nós usamos o "bom-ol CC" não UCM. Concordo totalmente com VonC no uma metodologia boa permite "guia" a flexibilidade no sentido de uma mais coerente de configuração . A coisa boa é que CC é bastante flexível e pode encontrar (não sem algum esforço) uma boa maneira de ter coisa coerente, enquanto em outra SCM que você pode tê-lo de graça. Mas, por exemplo aqui (e outros lugares que eu trabalhei com CC) para projetos C / C ++ não pode pagar o preço de não ter o winkin recurso (reutilizar os objetos Derivar), que reduzem vários X vezes compilar tempo. Pode-se argumentar que ter um projeto melhor, um código mais dissociado, e otimizar Makefiles pode reduzir a necessidade de compilar a coisa toda, mas há casos em que você precisa para compilar toda a besta muitas vezes ao dia, e compartilhando o DO salva montes de tempo / dinheiro. Onde eu estou agora tentamos usar o máximo ferramenta gratuita que pudermos, e acho que vai se livrar de CC se podemos encontrar uma ferramenta mais barata ou livre que implementa o winkin recurso.

Eu vou terminar com algo que Paul menção, diferentes ferramentas são melhores do que outros para fins diferentes , mas vou acrescentar que você pode ficar longe de algumas limitações da ferramenta por ter um processo coerente e sem escarificação reprodutibilidade, pontos-chave fora do SCM No final, eu acho que a resposta a vale a pena? depende do seu "problema", o SDLC você está executando, seus processos de SCM, e se houver qualquer recurso extra (como Winkin) que podem ser útil em seu ambiente.

meus 2 centavos

Teoria de lado, aqui está uma espécie de tomada prático óbvio sobre isso, na minha perspectiva usando AccuRev em um ambiente de produção comercial por um número de anos: O modelo de herança funciona muito bem enquanto fluxos criança não divergiram muito de antepassados ??que ainda estão em desenvolvimento. Ele quebra quando os fluxos herdando são muito diferentes.

Inheritance (versões posteriores como filhos dos anteriores) permite mudanças na ancestral fluxos de ser ativo na criança córregos sem ninguém fazendo nada (a menos que seja necessária uma fusão, caso em que ele aparece como sobreposição de profundidade, o que é bom para ser capaz de ver).

Isso soa muito bem, e na prática é, quando todos os fluxos envolvidos são relativamente semelhantes. Nós usamos esse modelo para fluxos de hotfix e service pack nível abaixo de uma determinada versão de produção. (É uma verdade um pouco mais complicado do que isso para nós, mas essa é a idéia geral.)

versões de produção são em paralelo, nenhuma herança, com essas correcções e service pack crianças abaixo de cada um deles. Iniciando um novo meio de libertação criando um novo fluxo de nível de lançamento, e empurrando manualmente tudo a partir do fluxo de manutenção mais recente para a versão anterior para ele. Depois disso, as alterações a versões anteriores que se aplicam a outros mais tarde tem que ser empurrado manualmente para cada um deles, exigindo mais trabalho, mas permitindo um controle muito maior.

Nós originalmente usado o modelo de herança em todas as versões, onde os posteriores eram filhos de anteriores. Isso funcionou bem por um tempo, mas tenho tempo mais incontrolável. As principais diferenças arquitetônicas entre os releases fez inevitavelmente herdar alterações uma má idéia. Sim, você pode colocar um instantâneo entre a herança bloco, mas, em seguida, todas as alterações têm de ser empurrado manualmente, e a única diferença real entre pai-snapshot-infantil e fluxos não herdados paralelas é que toda a visão corrente gráfica continuamente empurra para baixo e para a direita, que é um PITA.

Uma coisa realmente agradável sobre AccuRev é que você tem essa escolha, o tempo todo. Não é uma restrição inerente da arquitetura do seu programa de SCM.

Você já reparou que você pode verificar versões de arquivo specfific com GIT também?

Basta usar este:

git checkout [< tree-ish >] [--] < paths >

Como per configuração especificação qualquer versão existente de um arquivo (caminhos) podem ser carregados no worktree. Citar docs git-check-out:

As seguintes verificações sequência fora do branch master, reverte o Makefile para duas revisões de volta, exclui hello.c por engano, e recebe-lo de volta a partir do índice:

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            

ClearCase, sem MultiSite, é um único repositório Git, mas é distribuído. ClearCase compromete no nível de arquivo, mas Git compromete a nível repositório. (Esta última diferença significa a pergunta original é baseado em um mal-entendido, como fora apontado em outros posts aqui.)

Se estas são as diferenças que estamos falando, então eu acho 'linear' versus 'DAG' é uma forma confuso para distinguir estes sistemas de SCM. No ClearCase todas as versões de um arquivo são referidos como versão "árvore" do arquivo, mas realmente é um gráfico acíclico dirigido! A diferença real para Git é que DAGs do ClearCase existem por arquivo. Então eu acho que é enganador para se referir a ClearCase como não-DAG e Git como DAG.

(versões BTW ClearCase seus diretórios em uma maneira similar aos seus arquivos -. Mas isso é outra história)

Eu não tenho certeza se você está pedindo nada, mas você está demonstrando que os fluxos AccuRev são diferentes ferramentas do que Git (ou SVN) ramos. (Eu não sei Clearcase.)

Por exemplo, com AccuRev você forçada , como você diz, a utilização de determinados fluxos de trabalho, o que lhe dá uma história auditável de mudanças que não é suportado no Git. a herança de AccuRev faz certos fluxos de trabalho mais eficientes e outros impossível.

Com Git você pode ter exploratória codificação segregados em repos locais ou em ramos de novos recursos, o que não seria suportado muito bem pelo AccuRev.

Diferentes ferramentas são boas para finalidades diferentes; é útil perguntar o que cada um é bom para .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top