Git mesclar no Windows com arquivos duplicados
Estou tendo problemas para sincronizar uma filial local com uma remota, sei por que e tenho uma solução alternativa - mas gostaria de saber se existe uma solução melhor.
Fatores relevantes:
- É para um branch compartilhado de páginas gh; portanto, nenhum desenvolvimento ativo no ramo
- Eu trabalho no Windows (e não consigo ativar facilmente o suporte Posix para nomes de arquivo com distinção entre maiúsculas e minúsculas).
- O repositório contém dois arquivos que diferem apenas no caso dos nomes dos arquivos, ou seja, eles se sobrescreverão!
- Eu quero adicionar alguns outros arquivos
- E sincronizar este branch com o remoto (usando merge / pull).
Os itens 2 e 3 significam que apenas fazer check-out dos arquivos cria uma mudança, já que uma variante de caso sobrescreve a outra.
No entanto, os itens 1 a 4 ainda podem ser tratados criando um novo branch local, testando e submetendo os novos arquivos - e ignorando os avisos.
Mas mesclar / puxar etc falhar; como os arquivos com conflitos de caso causam problemas.
Gambiarra:
Exclua a ramificação local e, em seguida, crie uma nova com base na remota (assumindo que não haja alterações locais).
Respostas
Você não precisa deletar nenhum branch, mas terá que ter cuidado com sua árvore de trabalho .
Lembre-se de que o que o Git realmente usa, tanto para verificar qualquer commit existente, quanto para fazer qualquer novo commit, é o índice do Git . O Git também chama essa entidade de área de teste , refletindo sua função em fazer novos commits e - embora atualmente você veja isso principalmente como um sinalizador --cached- o cache , refletindo a função do índice em fazer o Git ir mais rápido.
Os arquivos armazenados no índice diferenciam maiúsculas de minúsculas, então o índice do Git é capaz de conter dois arquivos separados com o nome a/readme.txte A/README.TXT, por exemplo. Observe que os arquivos no índice são representados com nomes de caminho que usam barras, e esse a/readme.txté um nome de arquivo - não há pastas no índice, apenas arquivos com barras incorporadas em seus nomes.
Os arquivos que estão no índice são armazenados na forma interna do Git. Isso não é útil para você: esses arquivos estão em um formato de dados compactado, somente leitura e somente Git. Assim, o Git expande cada um desses arquivos em um arquivo comum de leitura / gravação do dia a dia. Este arquivo de leitura / gravação comum vai para uma pasta e tem um nome de arquivo comum de uso diário. Mas isto significa que quando Git vai para escrever tanto a/readme.txt, o que requer a criação de uma pasta com o nome ae um arquivo chamado readme.txtnele, e A/README.TXT, o que requer a criação de uma pasta com o nome Ae um arquivo chamado README.TXTem que , você tem uma colisão nome. Apenas uma pasta, e apenas um arquivo, é realmente criado.
O índice continua a manter os dois arquivos , a/readme.txte A/README.TXT. Usando um dos chamados do Git comandos hidráulicos , git update-index, é possível (mas muito difícil e chato) para atualizar ambos os arquivos. Lembre-se que enquanto o índice mantém arquivos em frozen-e-comprimido do Git formato , você pode substituir estes índice de arquivos atacado, desde que:
- comprimir os dados no formato interno do Git, produzindo o que o Git chama de ID de hash de blob ;
- forneça
git update-indexo nome do arquivo, comoa/readme.txte o ID do hash do blob.
Os dados que vão para o objeto blob interno podem vir de qualquer arquivo em qualquer lugar do computador. Não precisa nem estar em sua árvore de trabalho: pode estar lá ou em outro lugar. Use git hash-object -wpara criar o objeto blob interno e salvar o hash ID resultante em uma variável. Em seguida, execute imediatamente git update-indexpara substituir a cópia do índice do arquivo.
Para saber como usar cada um desses dois comandos de encanamento de baixo nível, consulte sua documentação: git hash-objecte git update-index.
Observe que esses dois comandos não devem ser usados por humanos: eles devem ser executados por programas que são mais orientados para humanos e são apenas blocos de construção que os comandos gostam git adde git rmpodem usar. O problema de usar git adde git rmaqui é que esses programas querem trabalhar com seus arquivos de árvore de trabalho, usando os nomes encontrados em seu computador - como - A\README.TXTao invés de nomes de arquivos internos do Git. Então é por isso que você precisaria usar os comandos de baixo nível, para que possa armazenar os dados dos arquivos internos do Git ( a/readme.txte A/README.TXT) em arquivos com nomes diferentes e, em seguida, atualizar os arquivos internos do Git a partir desses nomes diferentes.
Edit: esqueci de mencionar que você precisará ler os dois arquivos. Existem várias maneiras de fazer isso, mas provavelmente a mais fácil é usar o git showredirecionamento no estilo shell. Em sh / bash, você executaria:
git show HEAD:a/readme.txt > lowercase-readme
git show HEAD:A/README.TXT > uppercase-readme
para obter os dois arquivos, com dois nomes diferentes, para sua árvore de trabalho. O Git irá de fato extrair ambos os arquivos durante git checkout, mas eles acabarão ocupando um único arquivo de árvore de trabalho, cujo nome pode ser readme.txtou README.TXT, dependendo de qual nome "ganha" a competição get-a-Windows-file-name; esse arquivo pode aparecer em uma pasta chamada a, ou uma com o nome A, dependendo de qual desses "vence" a competição get-a-windows-folder-name.