O objetivo da área de preparação é ter um espaço flexível para sua confirmação. Eu acho que isso ficará mais claro se você comparar o git aos sistemas de controle de versão centralizados, como o subversion.
Subversão
No subversion, você pode optar por confirmar certos arquivos da sua cópia de trabalho. Mas apenas os arquivos completos. Agora: e se você quiser preparar o arquivo A
, não o arquivo B
, e as partes do arquivo C
relacionadas ao arquivo, A
mas não as partes que dependem de alterações no arquivo B
(desde então, você teria um problema com a consistência da confirmação).
Git
O Git resolve isso fornecendo a preparação como segunda cópia de trabalho. Na área de preparação, você está montando uma captura instantânea que irá confirmar (grosso modo).
Portanto, na área de preparação, você pode criar um instantâneo que inclua alterações A
e uma versão do arquivo C
que reflita apenas as alterações A
.
Para perguntas específicas
Você pode encenar a qualquer momento que desejar. Eu pessoalmente prefiro encenar logo antes de iniciar o commit.
Ao fazer alterações em um arquivo em etapas e depois alterá-lo na cópia de trabalho, você não alterou o arquivo em etapas, é claro. Você pode decidir se deseja realizá-las também ou não, essas mudanças. git gui citool
Ou seja, se você executar , verá diferenças nas versões preparadas e não preparadas (ferramentas agradáveis e simples para preparação e confirmação em linha).
Git é cauteloso aqui, o que provavelmente é uma coisa boa.
Estratégia de confirmação geral: confirmações granulares
Acho que quando se fala da pergunta "Quando devo encenar", também se deve falar sobre hábitos de cometer.
VCS centralizado
Nos sistemas centralizados de controle de versão em que você se compromete com um servidor central, era importante para seus colegas de trabalho que suas confirmações fossem completas e bem testadas. Assim, as pessoas tentariam confirmar não tão frequentemente e depois confirmariam o estado dos arquivos completos para minimizar a possibilidade de um erro. Assim, um commit tende a ser blocos muito grandes que incluem muitas alterações (se não forem correções simples). As alterações em uma confirmação podem ser totalmente independentes.
Git
No Git, um commit é realizado localmente, apenas enviando-os para um servidor os torna públicos. Portanto, um commit é barato em um sentido. Um commit no sentido de subversão é bastante comparável a vários git commit
seguidos por git push
. Essa diferença importa.
O Git permite que você confirme linhas de código únicas, mesmo que você tenha alterado outras linhas no mesmo arquivo. Isso oferece muitos benefícios, pois é possível, por exemplo, cometer uma correção de bug de segurança na linha 100, ao alterar as linhas 300-350, introduzindo um novo recurso.
- Você pode separar diferentes alterações em diferentes confirmações. Isso os separa muito bem no histórico de versões e até permite reverter um, mas não o outro.
- Seu commit não precisa necessariamente refletir um estado de "compilação" da sua cópia de trabalho (embora eu tente mantê-lo dessa maneira).
Então, onde está o "controle de qualidade" e a garantia de construção em um commit que um usuário do subversion esperaria? Ele é deslocado para outras ações no git. Você ainda deseja enviar um estado de funcionamento do programa para um repositório público. Portanto, verifique se os testes foram bem-sucedidos e se o programa funciona antes de enviar suas alterações.
Além disso, tente utilizar ramificações ao máximo. Ao confirmar muitas pequenas alterações, você terá um histórico de versões bastante grande. Se você trabalha em ramificações, pode categorizar essas confirmações granulares pelo nome da ramificação e depois mesclá-las novamente (a opção --no-ff
também preservará que esses recursos residam em uma ramificação exclusiva).
Ou seja, você pode manter o hábito de mesclar master
apenas ao ramo, se o ramo estiver em bom estado. Você também pode usar tags para rastrear marcos e lançamentos.
Agora, voltando à preparação: Depois de confirmar algumas linhas por confirmação, você fará o estágio diretamente antes de confirmar. (Pelo menos é assim que eu faço).
git diff
egit diff --cached
são bons, mas às vezes eu quero mais).