Nota: uma das maiores diferenças entre Git e Mercurial é a presença explícita do índice ou área de teste .
Do Mercurial para o usuário Git :
Git é o único DistributedSCM que expõe o conceito de índice ou área de teste. Os outros podem implementá-lo e ocultá-lo, mas em nenhum outro caso o usuário está ciente e não tem que lidar com ele.
O equivalente bruto do Mercurial é o DirState
, que controla as informações de status da cópia de trabalho para determinar os arquivos a serem incluídos no próximo commit. Mas em qualquer caso, este arquivo é tratado automaticamente.
Além disso, é possível ser mais seletivo na hora do commit, especificando os arquivos que você deseja enviar na linha de comando ou usando oRecordExtension
.
Se você se sentiu desconfortável em lidar com o índice, está mudando para melhor ;-)
O truque é que você realmente precisa entender o índice para explorar totalmente o Git. Como este artigo de maio de 2006 nos lembra então (e ainda é verdade agora):
“Se você nega o Index, você realmente nega o próprio git.”
Agora, esse artigo contém muitos comandos que agora são mais simples de usar (então não confie muito em seu conteúdo;)), mas a ideia geral permanece:
Você está trabalhando em um novo recurso e começa a fazer pequenas modificações em um arquivo.
# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile
Neste ponto, seu próximo commit irá embarcar 2 pequenas modificações no branch atual
# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work
$ git commit
Registra apenas as alterações adicionadas à área de teste (índice) neste ponto, não as principais alterações atualmente visíveis em seu diretório de trabalho.
$ git branch newFeature_Branch
$ git add myFile
O próximo commit irá registrar todas as outras mudanças principais no novo branch 'newFrature_Branch'.
Agora, adicionar interativamente ou mesmo dividir um commit são recursos disponíveis no Mercurial, por meio do hg record
comando ' ' ou outras extensões: você precisará instalar RecordExtension
, ou o CrecordExtension
.
Mas isso não faz parte do fluxo de trabalho normal do Mercurial.
O Git vê um commit como uma série de " alterações no conteúdo do arquivo " e permite adicionar essas alterações uma de cada vez.
Você deve estudar esse recurso e suas consequências: A maior parte do poder do Git (como a capacidade de reverter facilmente uma fusão (ou dividir o problema ao meio, ou reverter um commit) , ao contrário do Mercurial ) vem desse paradigma de "conteúdo de arquivo".
tonfa (no perfil: "Hg dev, pythonist": figuras ...) entrou na conversa, nos comentários:
Não há nada fundamentalmente "git-ish" no índice, o hg poderia usar um índice se fosse considerado valioso, de fato mq
ou shelve
já fizesse parte disso.
Oh garoto. Aqui vamos nós novamente.
Em primeiro lugar, não estou aqui para fazer uma ferramenta parecer melhor do que outra. Acho o Hg ótimo, muito intuitivo, com um bom suporte (principalmente no Windows, minha plataforma principal, embora trabalhe no Linux e no Solaris8 ou 10 também).
O índice está realmente na frente e no centro da maneira como Linus Torvalds trabalha com um VCS :
Git usou atualizações de índice explícitas desde o dia 1, mesmo antes de fazer a primeira fusão. É simplesmente como sempre trabalhei. Eu costumo ter árvores sujas, com algum patch aleatório na minha árvore que não quero enviar, porque é apenas uma atualização do Makefile para a próxima versão
Agora, a combinação do índice (que não é uma noção vista apenas no Git) e o paradigma "o conteúdo é rei" o torna bastante único e "git-ish" :
git é um rastreador de conteúdo e um nome de arquivo não tem significado a menos que esteja associado ao seu conteúdo. Portanto, o único comportamento lógico para git add filename é adicionar o conteúdo do arquivo e também seu nome ao índice.
Nota: o "conteúdo", aqui, é definido da seguinte forma :
O índice do Git é basicamente definido como
- suficiente para conter o " conteúdo " total da árvore (e isso inclui todos os metadados: o nome do arquivo, o modo e o conteúdo do arquivo são todos partes do "conteúdo" e são todos sem sentido por si só! )
- informações adicionais de "estatísticas" para permitir as otimizações de comparação do sistema de arquivos óbvias e triviais (mas extremamente importantes!).
Portanto, você realmente deve ver o índice como sendo o conteúdo .
O conteúdo não é o "nome do arquivo" ou o "conteúdo do arquivo" como partes separadas. Você realmente não pode separar os dois .
Os nomes de arquivo por si só não fazem sentido (eles também precisam ter o conteúdo do arquivo), e o conteúdo do arquivo por si só não faz sentido (você precisa saber como acessá-lo).
O que estou tentando dizer é que o git fundamentalmente não permite que você veja um nome de arquivo sem seu conteúdo. Toda a noção é insana e inválida. Não tem relevância para a "realidade".
Desde o FAQ , as principais vantagens são:
- comprometa-se com granularidade fina
- ajudá-lo a manter uma modificação não comprometida em sua árvore por um tempo razoavelmente longo
- execute vários pequenos passos para um commit, verificando o que você fez com
git diff
e validando cada pequeno passo com git add
ou git add -u
.
- permite uma excelente gestão de conflitos de mesclagem:
git diff --base
, git diff --ours
, git diff --theirs
.
- permite
git commit --amend
alterar apenas a mensagem de registo se o índice não tiver sido modificado entretanto
Eu pessoalmente acho que esse comportamento não deveria ser o padrão, você quer que as pessoas cometam algo que foi testado ou pelo menos compilado
Embora você esteja certo em geral (sobre a parte "testada ou compilada"), a maneira como o Git permite ramificar e mesclar (seleção seletiva ou rebase) permite que você comprometa quantas vezes quiser em um branch privado temporário (empurrado apenas para o repositório de "backup" remoto), enquanto refaz aqueles "commits feios" em um branch público, com todos os testes corretos no local.