Qual é o benefício do processo de consolidação em dois estágios do git (teste)?

174

Estou aprendendo o git e notei que ele tem um processo de confirmação em duas etapas:

  1. git add <files>
  2. git commit

O primeiro passo coloca as revisões no que é chamado de "área intermediária" ou "índice".

O que me interessa é por que essa decisão de design é tomada e quais são seus benefícios?

Além disso, como usuário git, você faz isso ou apenas usa git commit -a?

Eu pergunto isso porque venho do bzr (Bazaar) que não possui esse recurso.

thomasrutter
fonte
3
+1 para perguntar. Eu uso o Tortoise SVN, que tem a mesma abordagem e nunca entendi o porquê.
DPD
3
A área de preparação não é tão incomum. O equivalente em, digamos, o TFS estaria marcando ou desmarcando a caixa ao lado de um arquivo antes de fazer o check-in. Somente os arquivos marcados são confirmados. A diferença com o Git é que, se você usar git add -p, poderá optar por confirmar um pedaço de um arquivo sem comprometer outro pedaço do mesmo arquivo .
Kyralessa
Descobri que esse link resume a maior parte do que foi respondido aqui e adiciona mais alguns casos de uso para justificar a necessidade de teste.
Veverke 04/04
2
Esta questão já está realmente respondida, mas aqui está também uma boa explicação: stackoverflow.com/questions/4878358/…
guitar_freak 7/16
1
Não esqueça git statuse possivelmente git push. Para todo o hype sobre o git, (e o código de compartilhamento do GitHub é maravilhoso), as partes são muito irritantes #
user949300 17/17/17

Respostas:

83

Divida o trabalho em confirmações separadas. Você provavelmente já abriu muitas vezes um arquivo para escrever uma correção de linha única, mas, ao mesmo tempo, percebeu que a formatação estava incorreta, alguma documentação poderia ser aprimorada ou outra correção não relacionada. Com outros RCSs, você teria que anotá-lo ou enviá-lo para a memória, concluir a correção pela qual veio, confirmar e depois retornar para consertar as outras coisas (ou criar uma confirmação de bola de lama com coisas não relacionadas) . Com o Git, você apenas corrige tudo de uma só vez e estágio + confirma a linha única separadamente, com git add -iou git-gui.

Não quebre a construção. Você está trabalhando em uma modificação complicada. Então você tenta coisas diferentes, algumas das quais funcionam melhor que outras, outras que quebram. Com o Git, você prepararia as coisas quando a modificação melhorasse as coisas e checkout(ou ajustaria um pouco mais) quando a modificação não funcionasse. Você não precisará confiar na funcionalidade de desfazer do editor, pode checkoutrepo inteiro, em vez de apenas arquivo por arquivo, e qualquer erro no nível do arquivo (como remover um arquivo que não foi confirmado ou salvar + fechar após uma modificação incorreta) não leva a muito trabalho perdido.

l0b0
fonte
3
Vindo de um DVCS (bzr) que não possui esse recurso, parece muito com o que atualmente alcanço com uma combinação de uso liberal dos buffers "desfazer" do meu editor, o comando "reverter <arquivo>" e os commit seletivos (" confirmar <arquivo> "). Parece que esse recurso do git tem o potencial de ser mais metódico.
thomasrutter
1
Em relação a "outras RCSes", isso não é necessariamente verdade. De fato, você pode obter essas mesmas funcionalidades no Mercurial usando patches .
Lucio Paiva
1
@ l0b0, sobre o seu segundo ponto. Se houvesse apenas uma confirmação de estágio único, você poderia apenas confirmar as alterações (usadas com o git add) diretamente como confirmação. Se você descobrisse que fez algo errado, teria excluído o commit e retornado ao local em que estava antes de fazer o commit. Com o conceito de preparação, você não está apenas fazendo isso, mas adicionando mais complexidade?
alpha_989
Seu primeiro ponto faz sentido, embora eu não o tenha usado até agora. Teoricamente, por que você não pode fazer algo como um git add -icommit de estágio único? Você apenas seleciona um monte de arquivos (ou linhas dentro de arquivos) relacionados a um único recurso e faz um commit. Então você teria que voltar e fazer uma segunda cometer relacionada com uma outra característica ..
alpha_989
@thomasrutter, Na sua declaração, parece que você está sugerindo que a área de preparação crie "pontos de desfazer manuais". No VIM com desfazer persistente, você pode obter um histórico ilimitado com muita confiabilidade. Isso também é rastreado automaticamente de uma git-branchmaneira do tipo ( jovicailic.org/2017/04/vim-persistent-undo ). Além disso, seu histórico de desfazer é rastreado automaticamente sempre que você entra no modo normal. Portanto, reduz a carga mental de ter que criar "pontos de desfazer manuais". Por que o uso de seus editores "desfazer" os buffers não é tão metódico?
alpha_989
65

Um dos benefícios para mim é a capacidade de "adicionar" arquivos progressivamente. Antes de confirmar, reviso cada arquivo. Depois que o arquivo é revisado, eu o adiciono. Quando eu git statusou git diff, o git mostra apenas os arquivos que foram modificados e ainda não foram adicionados. Depois de revisar todos os arquivos e adicioná-los, posso confirmar.

Então, sim, acho a área de preparação muito útil.

E não, eu nunca uso git commit -a. No entanto, eu costumo usar git add -u. Dessa forma, ainda posso visualizar o que deve ser comprometido.

David
fonte
2
Exatamente. A vantagem é um controle muito mais refinado sobre exatamente o que você está enviando.
18711 Josh K
o que acontece quando você monta um arquivo várias vezes? ele é "mesclado" na área de preparação?
M4l490n
21

O benefício é bastante simples: fornece controle total sobre quais arquivos você deseja confirmar quando. Nesse caso, você pode usar git add -ppara controlar quais linhas você deseja confirmar.

Rein Henrichs
fonte
2
Eu sempre me perguntei como fazer isso. Gostaria que houvesse um arquivo .gitignorelinespara que você pudesse fazer alterações locais em linhas individuais que pudessem sobreviver às confirmações e permanecer intactas.
Alex Gray
3
@ ReinHenrichs, pense nos arquivos de configuração que precisam ser alterados por cada desenvolvedor.
Ian
1
@Ian Então, parte do arquivo muda com pouca frequência e é compartilhada e parte do arquivo muda frequentemente, de maneiras incompatíveis, e não é compartilhada? Apoiar essa falsa conascência definitivamente soa como um anti-recurso.
precisa saber é o seguinte
1
@ ReinHenrichs, sim, e é muito comum quando o arquivo contém o nome do servidor de banco de dados e cada desenvolvedor possui seu próprio banco de dados.
31414 Ian
4
@Ian Seu problema está realmente aí: você tem um arquivo que deveria ser a configuração do aplicativo e também contém algumas configurações específicas da máquina / dev. Todos os sistemas de configuração que eu conheço permitem que você divida isso em vários arquivos. Por exemplo, você tem o app.confque contém as coisas que deseja compartilhar e, em seguida, db.confcoloca as que você acabou de colocar na lista .gitignore. Problema resolvido. Se você estiver usando algo proprietário, deve realmente procurar algo tão simples lá. Ou coloque-o através de um pré-processador em um evento de pré-construção. Muitas soluções lá.
Aidiakapi 28/02
1

Um dos benefícios que eu gosto é a capacidade de cometer uma parte de uma mudança. Ou seja, usando git add -e. Eu não cometo com a frequência que deveria às vezes, e o comando git add -e me permite desvendar minhas alterações até certo ponto.

leed25d
fonte