É errado git push force branches?

10

Quando estou trabalhando em uma ramificação de recursos, tenho a tendência de limpar as confirmações na ramificação usando uma rebase interativa antes que meu trabalho seja revisado e integrado na ramificação principal.

Durante o desenvolvimento do recurso, desejo enviar meu trabalho intermediário para o repositório remoto como uma medida de backup. Ou seja, quando meu disco rígido falha, não quero que todo o meu ramo de recursos seja perdido.

No entanto, isso leva ao fato de que muitas vezes tenho que fazer um git push --forceno repositório remoto após uma nova refazer, uma ação que geralmente é desaprovada. Ou como a página vinculada do github diz:

Como alterar seu histórico de consolidação pode dificultar as coisas para todos os outros que usam o repositório, é considerado uma prática recomendada refazer a consolidação quando você já enviou por push a um repositório.

Existe uma política (geralmente aceita) que resolva esse conflito?

Por que essa não é uma duplicata de O git "Regra de Ouro do Rebasamento" é tão essencial?

Minha pergunta aqui pede uma política para resolver o conflito entre querer fazer backup do seu trabalho no repositório remoto e refazer o seu trabalho , enquanto a outra pergunta tenta negar a existência de um conflito e pergunta por que algumas pessoas pensam que o conflito existe, e, portanto, pergunta por que "é essencial" não pressionar rebotes de força?

Chiel ten Brinke
fonte
1
@gbjbaanb Se você fizer confirmações no WIP, uma reorganização é muito útil para evitar muitas confirmações por um único dia de trabalho. Costumo fazer confirmações para pequenas alterações, apenas para que eu tenha a opção "desfazer para um estado em que me lembro", se necessário - a maioria delas é irrelevante / ruído para o histórico principal do repo (é por isso que a rebase é tão útil).
Enderland
1
@gbjbaanb Essa é uma questão de opinião, eu acho. Muitas equipes usam uma estratégia de reformulação para manter seu histórico limpo.
Chiel ten Brinke,
1
@enderland Todo mundo quer uma linda história, ainda é a coisa errada (e perigosa) a ser feita, como mostra o link. Torvalds nunca deveria colocá-lo, ele deveria ter permitido que os commits fossem "compactados" em exibição.
precisa
1
@gbjbaanb mas ... ele não fez, e por isso temos que trabalhar com o que temos. Para mim, é muito mais útil ter uma única confirmação na ramificação principal em vez de mais de 30 confirmações individuais e incrementais de cada ramificação de recurso. Mas todo mundo vai ter um fluxo de trabalho diferente, eu acho ...
enderland

Respostas:

5

A principal pergunta a se fazer:

  • Você mantém sua ramificação remota após a fusão novamente no mestre?

Se você excluir sua ramificação de recurso remoto após mesclar no master, você já estará perdendo o histórico. Supondo que você esmague / refaça o ramo antes de fazer sua mesclagem / RP, você perderá esse histórico. Todo o seu esforço de força está fazendo neste caso, permitindo que você use o github como um backup.

A situação em que você deseja manter o histórico e não forçar o envio é se o seu ramo remoto persistir após a mesclagem e não existir apenas por um período temporário.

Suponho que você esteja perguntando se eu manteria o ramo não-baseado. Não, AFAIC. Ainda assim, forçar o push pode resultar em perda de confirmações de outros usuários que enviaram para o mesmo ramo

Parece que você tem várias pessoas empurrando para esse ramo simultaneamente. Isto significa que você fazer se preocupam com a história no ramo.

O que você poderia fazer no seu trabalho intermediário é criar uma bifurcação desse ramo. Você pode fazer isso e, em seguida, refazer todas as suas confirmações em uma única confirmação antes da mesclagem; portanto, quando você as mescla em seu ramo de recursos, você tem apenas 1 confirmação (com o histórico recuperado de todo o ramo).

enderland
fonte
"Você mantém sua ramificação remota após se fundir novamente à master?" Suponho que você esteja perguntando se eu manteria o ramo não-baseado. Não, AFAIC. Ainda assim, forçar forçosamente, teoricamente, pode resultar na perda de confirmações de outros usuários que enviaram para a mesma ramificação.
Chiel ten Brinke,
@ChieltenBrinke Eu editei um pouco sobre isso. FYI
enderland 14/03
Eu acho que o bifurcação como uma medida para evitar a destruição de commits quando forçar push é realmente uma sugestão muito boa. Mas o AFAIK não é realmente um conceito git, e você precisa de um wrapper de serviço para fazer isso facilmente (como o github). Estou correto sobre isso? Ou talvez eu confunda o uso do termo "bifurcação" por apenas criar um ramo separado?
Chiel ten Brinke,
@ChieltenBrinke bem, você pode realizar a mesma coisa de várias maneiras. Se a ramificação de recursos estiver no repositório remoto, você poderá bifurcar o repositório e ter sua versão dessa ramificação. E, em seguida, mesclar esse ramo em seu ramo remoto após a compactação. Ou você pode simplesmente criar um ramo local diferente (talvez featurebranch-local) e, em seguida, criar um desenvolvedor ativo nesse ramo, com o número de confirmações que desejar. Depois que você deseja mesclar, esmague essas confirmações e depois mesclá-las no recurso. Basicamente, basta fazer o dev em um ramo temporário real e depois esmagar / mesclar com o seu recurso.
Enderland
Supondo que a criação de um repo não esteja disponível porque não se usa o github, trabalharíamos com um develop-featureramo "privado" . É claro que a privacidade é puramente por convenção e não é imposta por nada, mas pode fazer parte de uma política, especialmente se certas convenções de nomenclatura de filial forem introduzidas para isso. (Talvez eu esteja ansioso demais agora, talvez não :) A combinação de --force-with-leasenão pode machucar, embora não deva ser considerada, como apontado em meu outro post.
Chiel ten Brinke 14/03
3

Estou listando aqui algumas possibilidades que me passam pela cabeça.

Sempre rebase em uma nova ramificação

Ao ter uma ramificação bagunçada some-feature, redefina-a em uma nova ramificação. Por exemplo

$ git checkout -b some-feature-rebase
$ git rebase -i master # etc..

Em seguida, some-feature-rebasereviram e integraram.

Problema: Uma grande desvantagem aqui é que, estritamente falando, você precisa de uma nova ramificação para cada rebase. (Você pode ter várias refazer as análises se fizer alterações após uma revisão de código, por exemplo)

Usar git push --force-with-lease

Acabei de aprender sobre a git push --force-with-leasealternativagit push --force , que

se recusa a atualizar uma ramificação, a menos que seja o estado que esperamos; ou seja, ninguém atualizou o ramo a montante.

Problema : isso parece melhorar diretamente a situação em que usamos apenas --force, mas ainda tem algumas ressalvas, principalmente quando eu faço um em git fetchvez de um git pull, que atualiza nossas filiais locais de upstream, tentando --force-with-leasepensar que nenhuma alteração imersa foi feita no controle remoto ramo.

Chiel ten Brinke
fonte