Git 🌙
Português (Brasil) ▾ Topics ▾ Latest version ▾ git-read-tree last updated in 2.43.0

NOME

git-read-tree - Lê as informações da árvore no índice

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:

  1. O índice atual e a árvore de trabalho são derivadas de $H, mas o usuário pode ter alterações locais desde $H.

  2. 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]

scroll-to-top