Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.43.1 → 2.47.0 no changes
- 2.43.0 11/20/23
- 2.40.1 → 2.42.3 no changes
- 2.40.0 03/12/23
- 2.39.1 → 2.39.5 no changes
- 2.39.0 12/12/22
- 2.37.1 → 2.38.5 no changes
- 2.37.0 06/27/22
- 2.36.1 → 2.36.6 no changes
- 2.36.0 04/18/22
- 2.34.1 → 2.35.8 no changes
- 2.34.0 11/15/21
- 2.27.1 → 2.33.8 no changes
- 2.27.0 06/01/20
- 2.25.1 → 2.26.3 no changes
- 2.25.0 01/13/20
- 2.22.1 → 2.24.4 no changes
- 2.22.0 06/07/19
- 2.18.1 → 2.21.4 no changes
- 2.18.0 06/21/18
- 2.17.0 → 2.17.6 no changes
- 2.16.6 12/06/19
- 2.15.4 no changes
- 2.14.6 12/06/19
- 2.13.7 05/22/18
- 2.2.3 → 2.12.5 no changes
- 2.1.4 12/17/14
- 2.0.5 12/17/14
RESUMO
git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefixo>) [-u | -i]] [--index-output=<arquivo>] [--no-sparse-checkout] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])
DESCRIÇÃO
Lê as informações da árvore informada através da <árvore>
no índice, mas na verdade não atualize nenhum dos arquivos que ele "armazena em cache". (consulte: git-checkout-index[1])
Opcionalmente, ele pode mesclar uma árvore no índice, executar uma mesclagem de avanço rápido (ou seja, de 2 vias) ou uma mesclagem de 3 vias, com a opção -m
. Quando usado com a opção -m
, a opção -u
faz com que ele também atualize os arquivos na árvore de trabalho com o resultado da mesclagem.
Apenas as mesclagens triviais são feitas pelo próprio comando git read-tree. Apenas os caminhos conflitantes estarão numa condição não mesclada durante o retorno do comando git read-tree.
OPÇÕES
- -m
-
Performa uma mesclagem e não apenas uma leitura. O comando se recusará a ser executado se o arquivo no índice tiver entradas não mescladas, indicando que você não concluiu uma mesclagem anterior que você iniciou.
- --reset
-
Igual a opção
-m
, exceto que as entradas não mescladas são descartadas em vez de falharem. Quando usado com a opção-u
, as atualizações que levam à perda das alterações na árvore de trabalho ou dos arquivos ou dos diretórios não rastreados não abortarão a operação. - -u
-
Após uma mesclagem bem-sucedida, atualize os arquivos na árvore de trabalho com o resultado da mesclagem.
- -i
-
Normalmente, para não perder as alterações locais, uma mesclagem exige que o arquivo no índice e os arquivos na árvore de trabalho estejam atualizados com o commit do cabeçalho atual. Esta opção desativa a verificação com a árvore de trabalho e deve ser usada ao criar uma mesclagem de árvores que não estejam diretamente relacionadas a condição atual da árvore de trabalho num arquivo temporário do índice.
- -n
- --dry-run
-
Verifique se o comando gera algum erro, sem atualizar de verdade, o índice ou os arquivos na árvore de trabalho.
- -v
-
Exiba o progresso da averiguação dos arquivos.
- --trivial
-
Restrinja a mesclagem de três vias através do comando git read-tree para que aconteça apenas caso não seja necessário a mesclagem no nível do arquivo, em vez de resolver a mesclagem para casos triviais e deixar os arquivos conflitantes não resolvidos no índice.
- --aggressive
-
Normalmente, uma mesclagem de 3 vias pelo git read-tree resolve a mesclagem nos casos realmente triviais e deixa outros casos não resolvidos no índice para que as porcelanas possam implementar diferentes políticas de mesclagem. Esta opção faz com que o comando resolva mais alguns casos internamente:
-
Quando um lado remove um caminho e o outro lado deixa o caminho inalterado. A resolução é remover aquele caminho.
-
Quando ambos os lados removem um caminho. A resolução é remover aquele caminho.
-
Quando ambos os lados adicionam um caminho igualmente. A resolução é adicionar aquele caminho.
-
- --prefix=<prefixo>
-
Mantenha o conteúdo do índice atual e leia o conteúdo da árvore mencionada sob o diretório em
<prefixo>
. O comando se recusará a substituir as entradas que já existiam no arquivo do índice original. - --index-output=<arquivo>
-
Em vez de gravar os resultados no
$GIT_INDEX_FILE
, grave o índice resultante no arquivo mencionado. Enquanto o comando estiver funcionando, o arquivo do índice original será bloqueado com o mesmo mecanismo de sempre. O arquivo deve permitir ser renomeado(2) a partir de um arquivo temporário criado ao lado do arquivo do índice usual; normalmente, isso significa que ele precisa estar no mesmo sistema de arquivos que o próprio arquivo de índice, e você precisa de permissão de gravação nos diretórios onde o arquivo do índice e o arquivo de saída do índice estão localizados. - --[no-]recurse-submodules
-
A utilização do --recurse-submodules atualizará o conteúdo de todos os submódulos ativos de acordo com o commit registrado no superprojeto ao chamar de forma recursiva o "read-tree" e também ao definir os submódulos HEAD para ser desanexados naquele commit.
- --no-sparse-checkout
-
Desative a compatibilidade com a verificação esparsa, mesmo que o
core.sparseCheckout
seja verdadeiro. - --empty
-
Em vez de ler o(s) objeto(s) da árvore no índice, apenas esvazie-a.
- -q
- --quiet
-
Silencioso, suprima as mensagens de feedback.
- <tree-ish#>
-
O ID do(s) objeto(s) da árvore que será lido/mesclado.
MESCLANDO
Se -m
seja utilizado, o comando git read-tree pode executar 3 tipos de mesclagem, uma única mesclagem na árvore caso apenas uma árvore seja informada, uma mesclagem de avanço rápido nas 2 árvores ou uma mesclagem de 3 vias caso 3 ou mais árvores sejam informadas.
Mesclagem Única da Árvore
Caso apenas 1 árvore seja informada, git read-tree funcionará como se o usuário não a tivesse informado -m
, exceto quando o índice original tiver uma entrada para um determinado nome do caminho e o conteúdo do caminho corresponder à árvore sendo lida, as estatísticas das informações do índice são utilizadas. (Em outras palavras, os stat() do índice têm precedência sobre os da árvore mesclada).
Significa que se você fizer um git read-tree -m <newtree>
seguido de um git checkout-index -f -u -a
, o comando git checkout-index verificará apenas o que realmente mudou.
É utilizado para evitar acertos falsos desnecessários quando git diff-files é executado após git read-tree.
Mesclagem de duas, três árvores
Normalmente, isso é invocado como git read-tree -m $H $M
, onde $H é o commit principal do repositório atual e o $M é o cabeçalho de uma árvore estrangeira, que está simplesmente à frente de $H ( ou seja, estamos numa situação de avanço rápido).
Quando duas árvores são definidas, o usuário informa ao git read-tree o seguinte:
-
O índice atual e a árvore de trabalho são derivadas de $H, mas o usuário pode ter alterações locais desde $H.
-
O usuário deseja avançar rapidamente para $M.
Nesse caso, o comando git read-tree -m $H $M
garante que nenhuma alteração local seja perdida como resultado dessa "mesclagem". Aqui estão as regras de "transporte", onde "I" indica o índice, "clean" significa que o índice e a árvore de trabalho coincidem e "exists"/"nothing" se referem à presença de um caminho no commit informado:
I H M Result ------------------------------------------------------- 0 nada nada nada (não acontece) 1 nada nada existe usa M 2 nada existe nada remove o caminho do índice 3 nada existe existe, usa M caso "averiguação inicial", H == M caso contrário, mantenha o índice existe, falha H != M clean I==H I==M ------------------ 4 sim N/A N/A nada nada mantenha o índice 5 não N/A N/A nada nada mantenha o índice 6 sim N/A sim nada existe mantenha o índice 7 não N/A sim nada existe mantenha o índice 8 sim N/A não nada existe falha 9 não N/A não nada existe falha 10 sim sim N/A existe nada remove o caminho a partir do índice 11 não sim N/A existe nada falha 12 sim não N/A existe nada falha 13 não não N/A existe nada falha limpa (H==M) ------ 14 sim existe existe mantenha o índice 15 não existe existe mantenha o índice clean I==H I==M (H!=M) ------------------ 16 sim não não existe existe falha 17 não não não existe existe falha 18 sim não sim existe existe mantenha o índice 19 não não sim existe existe mantenha o índice 20 sim sim não existe existe use M 21 não sim não existe existe falha
Em todos os casos de "manter o índice", a entrada do índice permanece como no arquivo original do índice. Se a entrada não estiver atualizada, o comando git read-tree manterá intacta a cópia na árvore de trabalho quando estiver operando com a opção -u
.
Quando essa forma de git read-tree for bem-sucedida, você poderá ver quais das "alterações locais" que você fez foram levadas adiante executando o comando git diff-index --cached $M
. Observe que isso não corresponde necessariamente ao que o comando git diff-index --cached $H
teria produzido antes dessa mesclagem de duas árvores. Isso ocorre devido aos casos 18 e 19 - se você já tivesse as alterações em $M (talvez você as tenha recebido como um patch por e-mail por exemplo), o git diff-index --cached $H
teria informado sobre a alteração antes dessa mesclagem, mas ela não seria exibida na saída do comando git diff-index --cached $M
após a mesclagem de duas árvores.
O caso 3 é um pouco complicado e precisa de explicação. O resultado dessa regra, logicamente, deve ser a remoção do caminho se o usuário tiver encenado a remoção do caminho e, em seguida, a alteração para um novo ramo. No entanto, isso impedirá a realização do verificação inicial, portanto, a regra é alterada para usar M (uma nova árvore) somente quando o conteúdo do índice estiver vazio. Caso contrário, a remoção do caminho é mantida, desde que $H
e $M
sejam os mesmos.
Mesclagem de 3 vias
Cada entrada no "índice" possui dois bits na condição "stage". o estágio 0 é o normal e é o único que você veria em qualquer tipo de uso normal.
No entanto, quando você executar o comando git read-tree com três árvores, o "estágio" começa em 1.
Isso significa que você pode fazer
$ git read-tree -m <tree1> <tree2> <tree3>
Você terá um índice com todas as entradas <árvore1>
em stage1, todas as entradas <árvore2>
em stage2 e todas as entradas <árvore3>
em stage3. Ao realizar uma mesclagem de outro ramo no ramo atual, usamos a árvore ancestral comum como <árvore1>
, o cabeçalho do ramo atual como <árvore2>
e o cabeçalho do outro ramo como <árvore3>
.
Além disso, o comando git read-tree possui uma lógica para caso especial que diz: caso você veja um arquivo que coincida em todos os aspectos nos seguintes condições, ele irá "retornar" novamente para "stage0":
-
Os estágios 2 e 3 são os mesmos; pegue um ou outro (não faz diferença, o mesmo trabalho foi feito em nosso ramo no estágio 2 e em seu ramo da fase 3)
-
o estágio 1 e o estágio 2 são iguais, o estágio 3 é diferente; pegue o estágio 3 (o nosso ramo no estágio 2 não fez nada desde no seu ancestral do estágio 1, enquanto o ramo no estágio 3 trabalhou nele)
-
os estágios 1 e 3 são iguais e o estágio 2 é diferente, tomamos o estágio 2 (fizemos algo enquanto eles não fizeram nada)
O comando git write-tree se recusa a escrever numa árvore sem sentido e irá reclamar das entradas que não foram mescladas caso veja uma única entrada que não seja o estágio 0.
OK, tudo isso soa como uma coleção de regras totalmente sem sentido, mas na verdade é exatamente o que você quer para fazer uma fusão rápida. Os diferentes estágios representam a "árvore de resultados" (estágio 0, também informado como "mesclado"), a árvore original (estágio 1, também informado como "orig") e as duas árvores que você está tentando mesclar (estágio 2 e 3, respectivamente).
A ordem dos estágios 1, 2 e 3 (portanto a ordem dos três argumentos da linha de comando <tree-ish>
) tem importância quando você inicia uma mesclagem de três vias com um arquivo do índice que já esteja preenchido. Aqui está um resumo de como o algoritmo funciona:
-
se um arquivo existir no formato idêntico em todas as três árvores, ele retornará automaticamente para a condição de "mesclado" através do comando git read-tree.
-
um arquivo que tenha qualquer diferença entre as três árvores permanecerá como lançamentos separados no índice. Cabe à "política da porcelana" determinar como remover os diferentes estágios não zerados e inserir uma versão mesclada.
-
o arquivo do índice salva e restaura com todas estas informações, para que você possa mesclar as coisas de maneira incremental, mas contanto que tenha as entradas nos estágios 1/2/3 (ou seja, "os lançamentos que não foram mesclados"), não será possível gravar o resultado. Então agora o algoritmo da mesclagem acaba sendo realmente simples:
-
você percorre o índice em ordem e ignora todas as entradas do estágio 0, pois elas já foram feitas.
-
caso encontre um "estágio1", que não coincida com o "estágio2" ou "estágio3", você sabe que ele foi removido das duas árvores (existia apenas na árvore original) e você remove essa entrada.
-
Se você encontrar uma árvore stage2 e stage3 correspondentes, remova uma delas e transforme a outra numa entrada stage0. Remova qualquer entrada stage1 correspondente, se ela também existir. .. Todas as regras triviais normais ..
-
Normalmente, você usaria o comando git merge-index
com o comando git merge-one-file
fornecido para realizar esta última etapa. O script atualiza os arquivos na árvore de trabalho à medida que mescla cada caminho e ao final de uma mesclagem bem-sucedida.
Quando você inicia uma mesclagem de três vias com um arquivo já preenchido no índice, presume-se que ele represente a condição dos arquivos na sua árvore de trabalho, e você pode até mesmo ter arquivos com alterações não registradas no arquivo do índice. Supõe-se ainda que esse estado seja "derivado" da árvore no estágio 2. A mesclagem de 3 vias se recusa a ser executada caso encontre uma entrada original no arquivo do índice que não corresponda ao estágio 2.
Isso é feito para evitar que você perca as suas alterações de trabalho que estão em andamento e misture as suas alterações aleatórias num commit mesclado não relacionado. Para ilustrar, imagine que você comece a partir do último commit em seu repositório:
$ JC=`git rev-parse --verify "HEAD^0"` $ git checkout-index -f -u -a $JC
Você faz edições aleatórias, sem executar o comando git update-index
. E então você percebe que o cume da sua árvore no topo (upstream) avançou desde que você se afastou dele:
$ git fetch git://.... linus $ LT=`git rev-parse FETCH_HEAD`
A sua árvore de trabalho ainda se baseia em seu HEAD
($JC
), mas você fez algumas edições desde então. A mesclagem de 3 vias garante que você não adicionou ou modificou as entradas no índice desde $JC
e, se não tiver feito, fará a coisa certa. Portanto, com a sequência a seguir:
$ git read-tree -m -u `git merge-base $JC $LT` $JC $LT $ git merge-index git-merge-one-file -a $ echo "Merge with Linus" | \ git commit-tree `git write-tree` -p $JC -p $LT
o commit que seria feito é uma mesclagem direta entre $JC e $LT sem as alterações em andamento e a sua árvore de trabalho seria atualizada para o resultado desta mesclagem.
No entanto, caso tenha alterações locais na árvore de trabalho que seriam substituídas através desta mesclagem, o comando git read-tree se recusará a executar evitando que as suas alterações sejam perdidas.
Em outras palavras, não há necessidade de se preocupar com o que existe apenas na árvore de trabalho. Quando você tem alterações locais numa parte do projeto que não está envolvida na mesclagem, as suas alterações não interferem na mesclagem e são mantidas intactas. Quando eles interferem, a mesclagem nem sequer começa (o comando git read-tree
reclama em voz alta e falha sem alterar nada). Nesse caso, você pode simplesmente continuar a fazer o que estava fazendo e, quando a árvore de trabalho estiver pronta (ou seja, você tiver concluído o trabalho em andamento), tente fazer a mesclagem novamente.
AVERIGUAÇÃO ESPARSA
Observação: Os recursos do skip-worktree do comando git-update-index[1] e read-tree
são anteriores à introdução do git-sparse-checkout[1]. Os usuários são incentivados a usar o comando sparse-checkout
em vez destes comandos que possam ser redirecionados para necessidades relacionadas a sparse-checkout
/ skip-worktree
. No entanto, as informações abaixo podem ser úteis para os usuários que tentam entender o estilo de predefinição usado no modo non-cone
do comando sparse-checkout
.
O aparse checkout permite preencher o diretório de trabalho de maneira esparsa. Ele usa o bit skip-worktree
(consulte git-update-index[1]) para informar ao Git se vale a pena examinar um arquivo no diretório de trabalho.
O git read-tree
e outros comandos com base em mesclagem (git merge
, git checkout
…) podem ajudar a manter o bitmap do skip-worktree
e a atualização do diretório de trabalho. O $GIT_DIR/info/sparse-checkout
é usado para definir o bitmap de referência do skip-worktree
. Quando o git read-tree
precisa atualizar o diretório de trabalho, ele redefine o bit skip-worktree
no índice com base nesse arquivo, que usa a mesma sintaxe dos arquivos .gitignore. Se uma entrada corresponder a uma predefinição nesse arquivo, ou se a entrada corresponder a um arquivo presente na árvore de trabalho, o skip-worktree
não será definido nessa entrada. Caso contrário, o skip-worktree
será definido.
Em seguida, ele compara o novo valor skip-worktree com o anterior. Caso o skip-worktree mude de definido para não definido, ele adicionará o arquivo correspondente novamente. Caso passe de não definido para definido, esse arquivo será removido.
Enquanto o $GIT_DIR/info/sparse-checkout
é normalmente utilizado para definir quais arquivos estão nele, também é possível definir quais arquivos não estão, utilizando padrões de negação. Como por exemplo, para remover o arquivo indesejado
:
/* !unwanted
Outra coisa complicada é repovoar totalmente o diretório ativo quando você não quiser mais uma verificação esparsa. Você não pode simplesmente desativar a "verificação esparsa" porque os bits skip-worktree ainda estão no índice e o seu diretório de trabalho ainda for escassamente preenchido. Você deve preencher novamente o diretório de trabalho com o conteúdo do arquivo $GIT_DIR/info/sparse-checkout
da seguinte maneira:
/*
Em seguida você pode desativar a averiguação esparsa. A predefinição da compatibilidade à averiguação esparsa no git read-tree e comandos similares é desativada. Você precisa ativar o core.sparseCheckout
para ter uma compatibilidade escassa da averiguação.
GIT
Parte do conjunto git[1]