O git "Regra de Ouro da Remasterização" é tão essencial?


22

Recentemente, tive uma discussão com pessoas absolutamente opostas a uma estratégia de rebase de ramos de recursos no GIT. Parece ser um padrão aceito usar rebase apenas para ramificações locais e privadas, mas nunca usá-lo quando há várias pessoas trabalhando em um mesmo recurso e ramificação, conforme a chamada "Regra de Ouro da Rebasagem" (como explicado aqui: https : //www.atlassian.com/git/tutorials/merging-vs-rebasing/conceptual-overview )

Estou surpreso que haja um consenso sobre isso. Trabalhei 3 anos com uma estratégia de rebaseamento completa, com cerca de 20 desenvolvedores trabalhando juntos e, adivinhem, funcionou.

O processo é basicamente:

  • Você cria seu ramo de recursos, vamos chamá-lo de "myfeature" e empurrá-lo para origin / myfeature
  • Outras pessoas podem conferir e trabalhar nele
  • Às vezes, você pode refazê-lo do master: de "myfeature", git rebase origin / master ; e então, sim, você precisa forçá-lo.
  • O que acontece quando outras pessoas querem pressionar seus commits? Eles apenas o refazem: git rebase origin / myfeature . Portanto, eles estão agora avançando rapidamente e podem pressioná-lo sem forçar.

O único princípio a respeitar é que o ramo de recursos pertence a alguém . O proprietário é o único que pode forçar.

Então, admito: assim que houver uma força de empurrão, há o risco de cometer erros. Isso é verdade. Mas também existem muitas maneiras de se recuperar de erros e, realmente, em 3 anos de desenvolvimento, eu não vi muitos erros de força e, quando isso aconteceu, sempre encontramos uma maneira de se recuperar adequadamente.

Então, por que essa "Regra de Ouro da Rebase" está sendo tão amplamente aceita? Há algo mais que eu perdi com isso? Entendo que requer um mínimo de organização (toda estratégia requer alguma organização), mas funciona.


Algo que esqueci de contar, mas tem sua importância: em minha experiência anterior, estávamos usando o gerrit como uma ferramenta de revisão de código. Isso significa que, se alguém enviar uma confirmação enquanto o proprietário da filial estiver fazendo uma nova reformulação, não haverá risco de a confirmação ser perdida, porque ela é empurrada para gerritar em vez de diretamente para o repositório de origem. E como o proprietário da filial é o único que tem o direito de enviar confirmações da gerrit, o risco de cometer erros é muito baixo.
Joel

e se eu mesclar o ramo de recursos de outra pessoa no meu?
Winston Ewert

Se o seu recurso depende de outro, acho que você pode refazer o seu do outro: git rebase origin / otherFeature (digo refazer em vez de mesclar, pois o objetivo é manter o histórico linear). Admito que a complexidade de tudo isso aumenta muito quando você introduz cada vez mais dependências entre os ramos.
Joel

Respostas:


10

O problema com o envio forçado não é sobre o ramo de recursos e o mestre, mas sobre o envio do mestre ao mestre de outra pessoa - que a sincronização substituirá o mestre com as alterações, ignorando o que estiver na dica.

Considerando esse perigo, há uma razão pela qual você não deve usá-lo, a menos que as coisas tenham estragado tudo e você precise absolutamente, totalmente, usá-lo para efetuar reparos. Um sistema SCM nem sempre precisa ser forçado assim, se isso acontecer porque algo deu muito errado (e minha primeira abordagem nesses casos seria restaurar backups e repetir as operações para manter o histórico intacto).

Então, talvez a questão seja: por que você está se rebaixando? Para uma história 'limpa' ao trazer os recursos de volta ao mestre? Nesse caso, você está jogando fora toda a boa história relativa à ramificação por razões puramente de estilo. A mesclagem rápida de IMHO também não é uma prática recomendada. Você deve manter toda a história para poder ver o que realmente fez, e não uma versão higienizada posteriormente.


Você poderia, é claro, usar master, rebase e depois forçar push, mas isso não é atômico.
Kevin

@gbjbaanb você está absolutamente certo, a estratégia de rebasear tem tudo a ver com razões de estilo / história mais legível. Não estou tentando argumentar que é melhor ou não. Mas é possível fazê-lo, e é esse o ponto que quero levantar. É claro que eu não estava falando sobre empurrar com força o mestre, mas apenas nos ramos de recursos.
Joel

4
IMHO o recurso de design de ambos rebase e fusões de avanço rápido foi um erro. O SCM é sobre como manter o histórico para que você possa ver o que aconteceu quando necessário e tirar instantâneos para pontos relevantes no tempo. Pelo menos é o que a maioria das pessoas quer, acho que Linus queria que a história fosse tão simples para ele ler quanto possível e, portanto, colocá-las em seu benefício. IMHO ele deveria ter colocar mais esforço em fazer diffs entre 2 revisões mais manejável vez (ou seja, permitindo a visualização a ser mais simples, não a história subjacente)
gbjbaanb

2
Quando você publica um artigo, publica o primeiro rascunho? Existe alguma lei que diz que as ferramentas que você usa para escrever o primeiro rascunho não podem ser usadas para editá-lo para publicação? Git é uma ferramenta de desenvolvimento. Se você deseja preservar de forma confiável e verificável uma série, preserve-a. Se você deseja editá-lo para publicação, edite-o. Git é estelar nas duas tarefas.
jthill

5

Rebase não é essencial, como você diz, é principalmente cosmético. Às vezes é muito mais simples que uma mesclagem. Portanto, ele pode ter algum valor "real", mas apenas "às vezes"

O uso inadequado de rebase pode ser caro. É improvável que você perca dados se você souber o suficiente para não entrar em pânico e procurar procedimentos de recuperação, mas "ei, ninguém pressiona por um tempo, preciso corrigir ..." não é ótimo. Tampouco alguém está gastando tempo na recuperação e teste de pesquisas quando poderia estar adicionando recursos ou esmagando bugs (ou em casa com a família).

Com essa troca, os resultados de "muito poucas pessoas fazem um rebase e um empurrão forçado" não são muito surpreendentes.

Alguns fluxos de trabalho podem reduzir o risco, por exemplo, reduzi-lo para "zero, desde que você lembre quais ramificações você pode forçar e quais não pode". Na realidade, eles podem ser seguros o suficiente para justificar o risco, mas as pessoas freqüentemente fazem escolhas baseadas em folclore maior. Então, novamente, na realidade, os benefícios são bem pequenos, então, quão pequeno é realmente o risco?


3
"ei, ninguém pressiona por um tempo, eu tenho que consertar ..." .. soa como nos velhos tempos do Visual Source Safe. Eu pensei que o git era melhor que isso.
Gbjbaanb

Sim, portanto, as pessoas criam regras como "não brinque com as ferramentas afiadas! (Forçar força)", para evitar o tratamento de feridas evitáveis!
Stripes

2
@gbjbaanb Sim, o Git é melhor que isso - quando você o usa corretamente. Reclamar sobre o Git ser incapaz de lidar com o desenvolvimento simultâneo de maneira elegante quando você está constantemente refazendo e alterando os hashes de confirmação de tudo é como reclamar sobre os carros serem inferiores aos carros porque são muito mais pesados ​​para o cavalo puxar. Não é culpa da ferramenta que as pessoas insistem em usá-lo errado ...
Idan Arye

4
Bem, isso meio que é culpa da ferramenta. O Git expõe MUITAS arestas nítidas e, embora às vezes observe que elas são nítidas, isso frequentemente não ocorre. Se você compará-lo ao CVS, onde todos os bits afiados estão em um subcomando SINGLE ("cvs admin"? Há um tempo ...) que se esforça para dizer "isso pode te deixar mal, não use-o a menos que você tenha uma necessidade extrema ". Ou outros sistemas de controle de versão que omitem recursos que podem prejudicar.
Stripes

4
Isso não quer dizer que o git não fez escolhas válidas de design (função relacionada ao grupo por subcomando e prefere permitir que o git resolva coisas mais complexas nas mãos certas) ... mas elas são ESCOLHAS, e pode-se criticar o A escolha de ter tantas arestas nítidas, assim como um pode ser crítico na escolha de outros VCSs para deixar de fora tantos recursos úteis "apenas porque alguém pode se machucar".
Stripes

2

Para adicionar uma voz diferente:

Sim, se você trabalha como você descreve, não há problema em usar rebasee pressionar com força. O ponto crítico é: você tem um acordo em sua equipe.

Os avisos rebasee amigos são para o caso em que não há acordo especial. Normalmente, o git protege você automaticamente, por exemplo, não permitindo um push não-rápido. O uso rebasee a pressão forçada substituem essa segurança. Tudo bem se você tiver algo mais no lugar.

Na minha equipe, às vezes também refazemos as ramificações dos recursos se o histórico ficar confuso. Excluímos o ramo antigo e fazemos um novo com um novo nome, ou apenas coordenamos informalmente (o que é possível porque somos uma equipe pequena e ninguém mais trabalha em nosso repositório).


Observe que o próprio projeto git também faz algo semelhante: eles têm um ramo de integração que é recriado regularmente, chamado "pu" ("atualizações propostas"). Está documentado que esse ramo é recriado regularmente e que você não deve basear novos trabalhos nele.


1

Então, admito: assim que houver uma força de empurrão, há o risco de cometer erros. Isso é verdade. Mas também existem muitas maneiras de se recuperar de erros e, realmente, em 3 anos de desenvolvimento, eu não vi muitos erros de força e, quando isso aconteceu, sempre encontramos uma maneira de se recuperar adequadamente.

A razão pela qual os usuários do Git tendem a evitar o histórico mutável compartilhado é porque não há prevenção ou reparo automático desses problemas. Você precisa saber o que está fazendo e precisa consertar tudo manualmente, se errar. Permitindo exatamente um pessoa faça force-push não é intuitivo e contrário ao design distribuído do Git. O que acontece se essa pessoa sai de férias? Alguém possui temporariamente a filial? Como você sabe que eles não vão andar por tudo o que o proprietário original estava fazendo? E no mundo do código aberto, o que acontece se o proprietário da filial se afastar gradualmente da comunidade, sem sair oficialmente? Você pode perder muito tempo esperando para transferir a propriedade da filial para outra pessoa.

Mas o problema real é o seguinte: se você errar e não perceber imediatamente, os antigos commits desaparecerão depois que tiver decorrido tempo suficiente. Nesse ponto, o problema pode ser irrecuperável (ou pelo menos potencialmente muito difícil de recuperar, dependendo da aparência da sua história de backup - você faz backup de cópias antigas do seu repositório Git, ou seja, não apenas de clones?).

Compare isso com o trabalho de evolução do Changesur da Mercurial (que, devo observar, ainda não está concluído ou estável). Todos podem fazer as alterações desejadas no histórico, desde que os conjuntos de alterações não sejam marcados como públicos. Essas alterações e reparos podem ser empurrados e retirados com total impunidade, sem a necessidade de um proprietário de filial. Nenhum dado é excluído; todo o repositório local é apenas anexado. Os conjuntos de alterações que não são mais necessários são marcados como obsoletos, mas mantidos indefinidamente. Finalmente, quando você bagunça seu histórico (que é tratado como uma parte normal do seu fluxo de trabalho diário), há um comando bacana para limpá-lo automaticamente para você. Esse é o tipo de UX que as pessoas esperam antes de modificar o histórico compartilhado.


Eu concordo com essa "filosofia git" e também acho que as filosofias às vezes podem ser hackeadas :). Mais seriamente, como afirmei nos comentários, há 3 anos atrás, eu estava no caso particular de ter o gerrit como uma ferramenta de revisão de código que agia como uma ferramenta de backup de fato, evitando uma perda dramática potencial. Agora, ainda acho que a reformulação está correta quando você tem certeza de "controlar" uma ramificação. Mesmo em um projeto de código-fonte aberto, se estou desenvolvendo um recurso e abrindo uma solicitação de recebimento, eu "possuo" esse PR, considero que tenho o direito de refazer sua ramificação, cabe a mim não atrapalhar meu próprio trabalho durante o rebatização ... (1/2)
Joel

... e se algumas pessoas quiserem modificar esse PR, considero que devem me informar primeiro, e é uma questão de comunicação. (2/2)
Joel

PS: obrigado pelo link evolução Changeset, isso é interessante
Joel

Na verdade, rebase é como dizer: "vamos reescrever todo o meu trabalho do zero (do mestre mais recente), excluindo todo o meu trabalho anterior". Se você estiver pronto para fazer isso, poderá refazer a recuperação.
Joel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.