Meu melhor será um script de shell que substitua os links simbólicos por cópias, ou existe outra maneira de dizer ao Git para seguir os links simbólicos?
PS: Eu sei que não é muito seguro, mas só quero fazê-lo em alguns casos específicos.
Meu melhor será um script de shell que substitua os links simbólicos por cópias, ou existe outra maneira de dizer ao Git para seguir os links simbólicos?
PS: Eu sei que não é muito seguro, mas só quero fazê-lo em alguns casos específicos.
Respostas:
NOTA: Este conselho está desatualizado de acordo com o comentário desde o Git 1.6.1. O Git costumava se comportar dessa maneira, e não o faz mais.
O Git, por padrão, tenta armazenar links simbólicos em vez de segui-los (por compacidade, e geralmente é o que as pessoas querem).
No entanto, acidentalmente, consegui que ele adicionasse arquivos além do link simbólico quando o link simbólico é um diretório.
Ou seja:
/foo/
/foo/baz
/bar/foo --> /foo
/bar/foo/baz
fazendo
git add /bar/foo/baz
parecia funcionar quando eu tentei. No entanto, esse comportamento era indesejável para mim na época, então não posso fornecer informações além disso.
O que fiz para adicionar para obter os arquivos dentro de um link simbólico no Git (eu não usei um link simbólico, mas):
sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY
Execute este comando no diretório gerenciado pelo Git. TARGETDIRECTORY
precisa ser criado antes de o SOURCEDIRECTORY
ser montado nele.
Funciona bem no Linux, mas não no OS X! Esse truque também me ajudou com o Subversion. Eu o uso para incluir arquivos de uma conta do Dropbox, onde um webdesigner faz suas coisas.
umount [mydir]
. (+1 para o seu grande dica, @ user252400)
Por que não criar links simbólicos de maneira inversa? Ou seja, em vez de vincular o repositório Git ao diretório do aplicativo, basta vincular o contrário.
Por exemplo, digamos que estou configurando um aplicativo instalado ~/application
que precise de um arquivo de configuração config.conf
:
config.conf
ao meu repositório Git, por exemplo, em ~/repos/application/config.conf
.~/application
executando ln -s ~/repos/application/config.conf
.Essa abordagem pode nem sempre funcionar, mas funcionou bem para mim até agora.
Use links físicos. Isso difere de um link suave (simbólico). Todos os programas, inclusive git
, tratarão o arquivo como um arquivo regular. Note que o conteúdo pode ser modificado alterando tanto a origem ou o destino.
Se você já possui o git e o Xcode instalados, instale o hardlink . É uma ferramenta microscópica para criar links físicos .
Para criar o link físico, basta:
hln source destination
O Apple File System suporta links físicos de diretório?
Links físicos de diretório não são suportados pelo Apple File System. Todos os links físicos do diretório são convertidos em links simbólicos ou aliases quando você converte dos formatos de volume HFS + para APFS no macOS.
Siga https://github.com/selkhateeb/hardlink/issues/31 para futuras alternativas.
O ln
comando pode criar links físicos:
ln source destination
Alguém sugeriu o uso do mklink para criar uma junção no Windows, mas eu não tentei:
mklink /j "source" "destination"
ln source destination
também funciona no OS X Testado em El Capitan.
cp -al source destination
. `-l 'significa arquivos de link físico em vez de copiar.
Este é um gancho de pré-confirmação que substitui os blobs de link simbólico no índice pelo conteúdo desses links simbólicos.
Coloque isso .git/hooks/pre-commit
e torne-o executável:
#!/bin/sh
# (replace "find ." with "find ./<path>" below, to work with only specific paths)
# (these lines are really all one line, on multiple lines for clarity)
# ...find symlinks which do not dereference to directories...
find . -type l -exec test '!' -d {} ';' -print -exec sh -c \
# ...remove the symlink blob, and add the content diff, to the index/cache
'git rm --cached "$1"; diff -au /dev/null "$1" | git apply --cached -p1 -' \
# ...and call out to "sh".
"process_links_to_nondir" {} ';'
# the end
Usamos a funcionalidade compatível com POSIX, tanto quanto possível; no entanto, diff -a
não é compatível com POSIX, possivelmente entre outras coisas.
Pode haver alguns erros / erros neste código, mesmo que tenha sido testado um pouco.
typechange
nos git status
arquivos que são realmente links simbólicos, embora o git agora seja o que não é.
process_links_to_nondir
?
argv[0]
que é usado como o nome do comando para o sh
processo. (Levei um pouco para descobrir isso, já que eu não me lembro o que era ou ☺😃)
find: missing argument to -exec'
. Pode ser necessário executar um comando passo a passo em vez de canalizar e combinar tudo em uma única linha.
typechange
como @DavidFraser, mas o arquivo vinculado parece não ser encenado anymore)
Ativado MacOS
(eu tenho o Mojave / 10.14, git
versão 2.7.1), use bindfs
.
brew install bindfs
cd /path/to/git_controlled_dir
mkdir local_copy_dir
bindfs </full/path/to/source_dir> </full/path/to/local_copy_dir>
Isso foi sugerido por outros comentários, mas não claramente fornecido em outras respostas. Espero que isso economize tempo para alguém.
Failed to resolve
... No such file or directory
erros, a menos que eu usasse nomes de caminhos completos com o bindfs
comando
Eu costumava adicionar arquivos além dos links simbólicos há algum tempo. Isso costumava funcionar muito bem, sem fazer nenhum arranjo especial. Desde que atualizei para o Git 1.6.1, isso não funciona mais.
Você pode mudar para o Git 1.6.0 para fazer isso funcionar. Espero que uma versão futura do Git tenha um sinalizador para git-add
permitir que ele siga os links simbólicos novamente.
Eu cansei de todas as soluções aqui desatualizadas ou exigindo root, por isso criei uma solução baseada em LD_PRELOAD (somente Linux).
Ele se prende aos internos do Git, substituindo o 'isso é um link simbólico?' , permitindo que os links simbólicos sejam tratados como seu conteúdo. Por padrão, todos os links para fora do repositório são incorporados; veja o link para detalhes.
LD_PRELOAD
para substituir as funções da biblioteca!
Com o Git 2.3.2+ (primeiro trimestre de 2015), há outro caso em que o Git não segue mais o link simbólico: consulte commit e0d201b de Junio C Hamano ( gitster
) (principal mantenedor do Git)
apply
: não toque em um arquivo além de um link simbólicoComo o Git rastreia links simbólicos como links simbólicos, um caminho que possui um link simbólico em sua parte principal (por exemplo
path/to/dir/file
, ondepath/to/dir
existe um link simbólico para outro lugar, seja dentro ou fora da árvore de trabalho) nunca pode aparecer em um patch que se aplica validamente , a menos que o mesmo patch remova primeiro o link simbólico para permitir que um diretório seja criado lá.Detecte e rejeite esse patch.
Da mesma forma, quando uma entrada cria um link simbólico
path/to/dir
e, em seguida, cria um arquivopath/to/dir/file
, precisamos sinalizá-lo como um erro sem realmente criarpath/to/dir
um link simbólico no sistema de arquivos.Em vez disso, para qualquer patch na entrada que deixe um caminho (ou seja, sem exclusão) no resultado, verificamos todos os caminhos iniciais na árvore resultante que o patch criaria, inspecionando todos os patches na entrada e depois o destino do patch aplicação (o índice ou a árvore de trabalho).
Dessa forma, nós:
- pegar uma travessura ou um erro para adicionar um link simbólico
path/to/dir
e um arquivopath/to/dir/file
ao mesmo tempo,- enquanto permite um patch válido que remove um simbólico
link path/to/dir
e adiciona um arquivopath/to/dir/file
.
Isso significa que, nesse caso, a mensagem de erro não será genérica "%s: patch does not apply"
, mas mais específica:
affected file '%s' is beyond a symbolic link
Hmmm, mount --bind
parece não funcionar em Darwin.
Alguém tem um truque que tem?
[editado]
OK, achei que a resposta no Mac OS X é criar um link físico. Exceto que essa API não é exposta via ln
, você deve usar seu próprio programa minúsculo para fazer isso. Aqui está um link para esse programa:
Criando links físicos de diretório no Mac OS X
Aproveitar!
Estou usando o Git 1.5.4.3 e está seguindo o link simbólico passado, se houver uma barra final. Por exemplo
# Adds the symlink itself
$ git add symlink
# Follows symlink and adds the denoted directory's contents
$ git add symlink/
fatal: 'src/' is beyond a symbolic link
A conversão de links simbólicos pode ser útil. Vincule uma pasta Git em vez de um link simbólico por um script .