Link simbólico para um gancho no git


86

Eu escrevi meu próprio gancho pós-mesclagem personalizado, agora adicionei um diretório "ganchos" à pasta principal do meu projeto (já que o git não rastreia as alterações em .git / ganchos), em algum lugar li que posso fazer um link simbólico a partir de ganchos para .git / hooks para não ter que copiar o arquivo de uma pasta para a outra toda vez que alguém o altera, então tentei:

ln -s -f hooks/post-merge .git/hooks/post-merge

Mas não parece funcionar, alguma ideia por quê? "ln hooks / post-merge .git / hooks / post-merge" funciona bem, mas criar um link físico é o mesmo que copiar, eu acho ...


22
Porque o link simbólico é resolvido em relação à sua localização. Um link simbólico .git/hooks/que aponta para hooks/post-mergeé resolvido para .git/hooks/hooks/post-merge, que não existe. Você quer ln -s -f ../../hooks/post-merge .git/hooks/post-merge. Ou facilitar a sua vida: ln -s -f ../hooks .git/hooks. Seu problema não tem nada a ver com o git.
Aristóteles Pagaltzis


Corrija-me se eu estiver errado, mas um Symlink ainda precisa ser configurado por estação de trabalho. A única coisa que isso salva é copiá-lo manualmente ou escrever outro comando que copie o arquivo de gancho rastreado para o .git/hooks.
adi518 de

Respostas:


161

você acabou de usar o caminho errado, deveria ser:

ln -s -f ../../hooks/post-merge .git/hooks/post-merge

10
Não entendo por que preciso subir dois diretórios para vincular um recurso que reside na pasta em que eu coloquei cd. Não deveria ser ln -s ./hooks/?
Droogans

45
Isto. Quando o git está avaliando o link simbólico, ele aparentemente o faz usando .git/hookscomo seu diretório de trabalho, então os caminhos relativos devem ser relativos a esse diretório. Isso é mais evidente se você primeiro cdem .git/hooksantes de fazer a ligação simbólica, e descobrir o caminho relativo de lá.
Eliot de

12
@Eliot nem a criação nem a resolução de links simbólicos são afetados pelo diretório de trabalho. O que quer que você forneça lnserá armazenado como o destino e resolvido em relação à localização do link.
Joó Ádám

2
@ JoóÁdám Você está certo. Portanto, o problema aqui é que o comando original especifica um caminho relativo incorreto. Ainda assim, cdentrar no .git/hooksantes de fazer o link o ajudará a escrever o comando, já que você pode preencher automaticamente para o caminho correto.
Eliot

1
Tudo isso funcionou para mim no final. A única diferença é que estou me ligando ao meu prepare-commit-msg. O problema é se eu estou editando a mensagem de commit usando nano, então Ctl + X sai para abortar, git ainda completa um commit de qualquer maneira ao invés de abortar como costumava fazer antes de eu fazer essa mudança. Existe uma maneira de fazer o nano sair sem fazer com que esse commit seja concluído?
frakman1 de

15

Embora você possa usar links simbólicos, também pode alterar a pasta de ganchos para seu projeto nas configurações do git com:

git config core.hooksPath hooks/

Que é local por padrão, então não vai arruinar os ganchos do git para seus outros projetos. Ele funciona para todos os ganchos neste repositório, então é especialmente útil se você tiver mais de um gancho.

Se você já tem ganchos personalizados .git/hooks/que não deseja compartilhar com sua equipe, pode adicioná-los aos ganchos / e adicionar um .gitignorepara que não sejam compartilhados.


Muito agradável! Um truque útil :) Parece muito mais à prova de futuro do que vinculá-los um por um.
jkp de

2

Mudar de diretório antes de vincular

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge

Ainda mais simples, após cd:ln -s -f ../../hooks/post-merge
jamesdlin

0

O cálculo do caminho é feito em relação ao link simbólico. Vamos entender usando um exemplo,

ln -s path/to/file symlink/file

Aqui, o caminho para o arquivo deve realmente ser o caminho relativo do caminho do link simbólico.
O sistema realmente calcula o caminho do arquivo como symlink/path/path/to/file
O comando acima deve ser reescrito como

ln -s ../path/to/file symlink/path

A estrutura da pasta sendo,

/ code
------ link simbólico / arquivo
------ caminho / para / arquivo


0

Utilizando o comentário de Michael Cihar, aqui está um exemplo de um script bash que escrevi para simplesmente criar esses links simbólicos. Este script está localizado em git_hooks / dir, que está na raiz do projeto. Meu .git / pasta também está no mesmo nível de diretório.

#!/usr/bin/env bash

pwd=$(pwd);

# Script is designed to be ran from git_hooks/ dir
if [[ "$pwd" == *"git_hooks"* ]]; then

  files=$(ls | grep -v -e '.*\.');

   while read -r file; do

     ln -s ../../git_hooks/$file ../.git/hooks/
     echo "Linked $file -> ../.git/hooks/$file"

   done <<< "$files";

else

  echo "";
  echo "ERROR: ";
  echo "You must be within the git_hooks/ dir to run this command";
  exit 1;

fi

Meu script deve ser executado de dentro do diretório git_hooks / real. Você pode modificá-lo para se comportar de maneira diferente, se desejar.

Este script criará um link simbólico para qualquer arquivo que não tenha uma extensão de arquivo no diretório git_hooks /. Eu tenho um README.txt neste diretório + este script (chamado symlink.sh). Todos os git hooks atuais são nomeados 'pre-commit', 'pre-push', etc., então eles serão vinculados simbolicamente.


-1

por que não apenas cp ./hooks/* .git / hooks /

isso funcionou para mim no Mac OS


15
PorqueI don't have to copy the file from one folder to the other every time someone changes
George Dimitriadis
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.