Git이 심볼릭 링크를 따르도록하려면 어떻게해야합니까?


217

심볼릭 링크를 복사본으로 대체하는 쉘 스크립트가 최선입니까? 아니면 Git에게 심볼릭 링크를 따르도록 지시하는 다른 방법이 있습니까?

추신 : 나는 그것이 매우 안전하지 않다는 것을 알고 있지만 몇 가지 특별한 경우에만하고 싶습니다.


5
이런 식으로 하드 링크를 사용하는 데 단점이 있습니까?
Ehtesh Choudhury 2016 년

12
Windows 7에서는 "mklink / d"(디렉토리 심볼릭 링크)가 git에서 작동하지 않지만 "mklink / j"(juction)는 제대로 작동합니다.
yoyo

1
파일을 삭제하고 새 파일을 생성하는 방식으로 파일을 재생성하는 응용 프로그램에서 파일을 자동 생성하면 파일에 대한 하드 링크가 해결되지 않는 문제입니다.
Martin Pecka

1
@EhteshChoudhury 디렉토리에 대한 하드 링크를 만들 수 없습니다
Gaurav Kansal

답변:


46

참고 : 이 조언은 Git 1.6.1 이후 주석에 따라 오래되었습니다. 힘내는 이런 식으로 행동했지만 더 이상하지 않습니다.


Git은 기본적으로 심볼릭 링크를 따르지 않고 저장하려고합니다 (압축성을 위해 일반적으로 사람들이 원하는 것입니다).

그러나 실수로 symlink가 디렉토리 인 경우 symlink 이외의 파일을 추가하도록했습니다.

즉 :

  /foo/
  /foo/baz
  /bar/foo --> /foo
  /bar/foo/baz

함으로써

 git add /bar/foo/baz

내가 시도했을 때 작동하는 것처럼 보였습니다. 그러나 그 당시에는 그 행동이 원치 않았으므로 그 이상으로 정보를 줄 수는 없습니다.


72
, 당신은 심볼릭 링크 디렉토리를 넘어 파일을 추가 멈췄다 725b06050a083474e240a2436121e0a80bb9f175 및 806d13b1ccdbdde4bbdfb96902791c4b7ed125f6 소개 변경을 커밋 그래서 1.6.1 이후 자식의 버전이하지 않습니다 일
마크 Longair

1
$ git add src / main / path / ConvertSymlinkToDir 치명적 : 'src / main / path / ConvertSymlinkToDir'은 기호 링크를
벗어났습니다

2
@ user1767316 모든 내용과 의견을 읽으십시오. 그것은 더 이상 작동하지 않습니다. 소프트웨어가 변경되었지만 스택 오버플로 허용 답변은 그렇지 않습니다. 나는 이것이 작동하지 않는다는 것을 분명히했다. 다른 대답을보십시오.
Kent Fredric

예 @KentFrederic을 반환했지만 정확한 오류 메시지를 표시하면 사용자가 해당 문제에 대한 솔루션 검색을 검색하는 데 도움이됩니다. 한편으로는 경고에 대한 귀하의 답변이 옳습니다. 반면에 귀하는 과거가 아니라 현재의 답변에 우선 순위를 두어야합니다.
user1767316

144

심볼릭 링크 내의 파일을 Git으로 가져 오기 위해 추가 한 것 (심볼릭 링크는 사용하지 않았지만) :

sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Git 관리 디렉토리에서이 명령을 수행하십시오. TARGETDIRECTORYSOURCEDIRECTORY마운트 하기 전에 생성해야합니다 .

Linux에서는 잘 작동하지만 OS X에서는 작동하지 않습니다! 그 트릭은 Subversion에도 도움이되었습니다. 웹 디자이너가 자신의 작업을 수행하는 Dropbox 계정의 파일을 포함하는 데 사용합니다.


8
sudo가 필요하지 않은 경우 매우 좋은 접근 방식입니다.
MestreLion

13
이 바인딩을 취소하려면을 사용하십시오 umount [mydir]. (@ user252400의 훌륭한 팁은 +1)
JellicleCat

10
세션 중에 만 작동합니다. 그것을 "영원히"만드는 가장 좋은 방법은 무엇입니까?
Adobe

17
@Adobe : / etc / fstab에 다음과 같이 넣습니다 : / sourcedir / targetdir none bind
Alexander Garden

8
sshfs는 여기에 sudo를 요구하지 않고도 그러한 종류의 트릭을 얻을 수 있습니다.
PypeBros

75

다른 방법으로 심볼릭 링크를 만들지 않겠습니까? Git 리포지토리에서 응용 프로그램 디렉토리로 연결하는 대신 다른 방법으로 연결하면됩니다.

예를 들어, ~/application구성 파일이 필요한 응용 프로그램을 설치한다고 가정 해 보겠습니다 config.conf.

  • config.conf예를 들어, Git 리포지토리에 추가 합니다 ~/repos/application/config.conf.
  • 그런 다음 ~/application을 실행 하여 심볼릭 링크를 만듭니다 ln -s ~/repos/application/config.conf.

이 방법이 항상 효과가있는 것은 아니지만 지금까지는 효과가있었습니다.


5
유일한 길인 것 같고, 그렇게 나쁘지는 않습니다 ... 나는 당신의 것이 매우 우아한 접근법이라고 생각합니다. git은 파일이 아닌 컨텐츠를 추적합니다. 따라서 모든 콘텐츠를 함께 유지하고 거기에서 다른 장소로 연결하는 것이 합리적입니다.
MestreLion

12
필자의 경우 하나의 git repo에서 다른 git repo 로의 링크를 원했기 때문에 어느 위치에서나 파일을 편집하고 해당 리모콘으로 다시 커밋 할 수 있습니다. Windows 7에서 정션 ( "mklink / j")이 트릭을 수행했습니다.
yoyo

3
물론이야. 때로는 대답이 그렇게 간단합니다.
BBW 전에 Windows

소스와 대상을 모두 표시하려면 어떻게해야합니까? (두 가지 모두 다른 저장소에 원하는 다른 코드에 속하기 때문에)
DrGC

1
질문에 대답하지 않습니다. symlinks : \
Jerry Green

49

대신 하드 링크를 사용하십시오. 이것은 소프트 (기호) 링크와 다릅니다. 를 포함한 모든 프로그램 git은 파일을 일반 파일로 취급합니다. 내용이 변경에 의해 변경 될 수 있습니다 하나 의 소스 또는 대상을.

macOS에서 (10.13 High Sierra 이전)

git 및 Xcode가 이미 설치되어 있으면 hardlink를 설치하십시오 . 하드 링크를 만드는 미세한 도구 입니다.

하드 링크를 만들려면 다음을 수행하십시오.

hln source destination

macOS High Sierra 업데이트

Apple File System은 디렉토리 하드 링크를 지원합니까?

Apple File System은 디렉토리 하드 링크를 지원하지 않습니다. macOS에서 HFS +를 APFS 볼륨 형식으로 변환하면 모든 디렉토리 하드 링크가 기호 링크 또는 별명으로 변환됩니다.

에서 APFS 자주 묻는 질문 developer.apple.com에

따라 https://github.com/selkhateeb/hardlink/issues/31을 미래의 대안을.

Linux 및 기타 Unix 버전에서

ln명령은 하드 링크를 만들 수 있습니다.

ln source destination

Windows에서 (Vista, 7, 8,…)

누군가 mklink 를 사용 하여 Windows에서 접합을 만들 것을 제안 했지만 시도하지 않았습니다.

mklink /j "source" "destination"

7
참고 사항 : 이것은 기본적으로 내가 찾던 것이지만 Linux에서는 하드 링크가 불행히도 파일 시스템 경계 (내 사용 사례)를 넘을 수 없다는 것을 알게되었습니다.
sdaau

26
디렉토리에 하드 링크 할 수 없습니까?
Nanne

1
ln source destinationOS X에서도 작동합니다. 엘 캐피 탄에서 테스트되었습니다.
Mahdi Dibaiee

7
@Nanne 아니오,하지만 당신은 할 수 있습니다 : cp -al source destination. `-l '은 복사하는 대신 하드 링크 파일을 의미합니다.
Paolo

6
불행히도 디렉토리 또는 파일 시스템 경계를 하드 링크 할 수 없습니다. 이것은이 솔루션을 두 가지로 사용할 수 없게 만듭니다.
Konrad Rudolph

25

이것은 인덱스의 symlink blob을 해당 symlink의 내용으로 대체 하는 사전 커미트 후크 입니다.

이에 넣어 .git/hooks/pre-commit, 그리고 그것을 실행합니다

#!/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

노트

POSIX 호환 기능을 최대한 많이 사용합니다. 그러나 diff -aPOSIX와 호환되지 않을 수도 있습니다.

이 코드는 다소 테스트되었지만 오류 / 오류가있을 수 있습니다.


4
디렉토리가 아닌 파일에 대한 질문에 실제로 대답하려는 시도를 보는 것이 좋습니다. 그러나 위의 내용 은 실제로 심볼릭 링크 인 파일 typechangegit status대해서는 여전히 표시 되지만 지금은 그렇지 않습니다.
David Fraser

1
이것에 감사합니다; 알고 싶었던 것은 무엇 process_links_to_nondir입니까?
sdaau

@sdaau 프로세스 argv[0]의 명령 이름으로 사용되는 이름 / 입니다 sh. (내가 ☺😃 무엇인지 기억하지 못했기 때문에 알아낼 약간의 정보를 얻었습니다)
Abbafei

3
@Abbafei 우분투 (14.04)에서 작동하도록 스크립트를 수정할 수 있습니까? 보여주고 find: missing argument to -exec'있습니다. 모든 것을 단일 라인으로 파이핑 및 결합하는 대신 단계별 명령 실행이 필요할 수 있습니다.
Khurshid Alam

1
@KhurshidAlam 나를 위해 명령 줄 사이에 주석 처리 된 줄을 제거했습니다. 그러나 후크가 예상대로 작동하지 않습니다 ( typechange@DavidFraser와 비슷하지만 링크 된 파일이 더 이상 준비되지 않는 것 같습니다)
Scz

14

MacOS(내가 모하비 / 10.14,가 git, 사용 버전 2.7.1)를 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>

다른 의견에서 암시되었지만 다른 답변에서는 명확하게 제공되지 않았습니다. 바라건대 이것은 누군가를 시간을 절약 해줍니다.


Mac OS에서 모두 실행되는 팀에게는 좋을 것 같습니다. 아래에 설명 된 하드 링크는 Windows 및 Linux에서 작동해야한다고 생각합니다.
Devin G Rhode

이것은 도움이되었으며, MacOS에서 유용하지만 놓칠 수있는 기능을위한 최고의 솔루션이라고 생각합니다. 그러나 명령에 전체 경로 이름 을 사용 하지 않으면Failed to resolve ... No such file or directory오류가 발생 합니다 . bindfs
전자석

감사합니다 @electromaggot. 전체 경로가 필요하다는 설명을 추가 함
ijoseph

1
macos Catalina에서 잘 작동합니다!
Jerry Green

13

나는 꽤 오랫동안 심볼릭 링크를 넘어 파일을 추가했었다. 이것은 특별한 조치를 취하지 않고 잘 작동했습니다. Git 1.6.1로 업데이트 한 후에는 더 이상 작동하지 않습니다.

이 작업을 수행하기 위해 Git 1.6.0으로 전환 할 수 있습니다. 향후 버전의 Git이 git-add심볼릭 링크를 다시 따르 도록 허용 하는 플래그가 있기를 바랍니다.


12

구식이거나 루트가 필요한 모든 솔루션에 질려서 LD_PRELOAD 기반 솔루션을 만들었습니다 (Linux 만 해당).

그것은 Git의 내부에 연결되어 '이것이 심볼릭 링크입니까?'를 재정의합니다. 심볼릭 링크를 내용으로 취급 할 수 있습니다. 기본적으로 리포지토리 외부에 대한 모든 링크는 인라인됩니다. 자세한 내용은 링크를 참조하십시오.


LD_PRELOAD라이브러리 기능을 재정의 하는 데 사용 하는 매우 창의적인 솔루션 !
iBug

그렇습니다. 그러나 여기에서 자세히 설명해야합니다. 그렇게 할 수 있습니까?
Peter Mortensen

얼마나 많은 정교함이 도움이 될지 확실하지 않습니다. 전체 소스 코드를 복사하여 붙여 넣지 않으면이 답변은 항상 해당 링크에 의존하며 추가 정보를 찾을 수 있습니다. 그러나 예, 나는 readme의 중요한 부분을 재현 할 수 있다고 생각합니다.
Alcaro

OS X (Mojave 10.14.2)에서는 컴파일되지 않습니다. 'strchrnul'( 'strchr'을 의미 했습니까?)과 '__xstat64'( '__ lxstat64'를 의미 했습니까?)에 대해 불평하는 네 가지 오류가 발생합니다. 마지막으로 "불완전한 유형 'dirent64'에 대한 멤버 액세스"오류가 발생합니다. "make", "make OPT = 1"또는 "sh install.sh"를 사용하든 관계없이 발생합니다.
Erik Veland

@ErikVeland 조금 시도했지만 OSX가 LD_PRELOAD 또는 이와 유사한 것을 지원하지 않는 것 같습니다. 다양한 문서가 다양한 것을 제안하지만 모두 몇 년이 지났으며 Apple은 더 이상 사용되지 않는 것을 좋아합니다. 나는 그들 중 누구도 일할 수 없었습니다. 죄송합니다.
Alcaro

6

힘내 함께 2.3.2+ (Q1 2015) 힘내 것 이상의 다른 경우가 없는 이상 심볼릭 링크를 따라가 : 참조 e0d201b 투입 하여 Junio C 하마노 ( gitster) (주 힘내 테이너)

apply: 심볼릭 링크를 넘어 파일을 만지지 마십시오

망할 놈의 심볼릭 링크로 심볼릭 링크, 자사의 주요 부분에 대한 기호 링크가있는 경로를 추적하기 때문에 (예를 들어 path/to/dir/file, path/to/dir유효하게 적용하는 패치에 표시되지 않을 수 있습니다 다른 곳으로 심볼릭 링크입니다, 내부 또는 작업 트리 외부 될) 동일한 패치가 먼저 심볼릭 링크를 제거하여 디렉토리를 만들 수없는 경우가 아닙니다.

이러한 패치를 감지하고 거부하십시오.

마찬가지로 입력이 심볼릭 링크 path/to/dir를 만든 다음 파일을 path/to/dir/file만들 때 실제로 path/to/dir파일 시스템에서 심볼릭 링크를 만들지 않고 오류로 플래그를 지정해야합니다 .

대신, 결과에 경로를 남기는 입력 (즉, 삭제되지 않은) 패치의 경우 입력의 모든 패치와 패치 대상을 검사하여 패치가 생성하는 결과 트리에 대해 모든 선행 경로를 검사합니다. 응용 프로그램 (인덱스 또는 작업 트리).

이런 식으로, 우리는 :

  • 상징적 링크 path/to/dir와 파일 path/to/dir/file을 동시에 추가하기 위해 장난이나 실수를 저지르고
  • 유효한 패치를 허용하면서 기호를 제거한 link path/to/dir다음 파일을 추가합니다 path/to/dir/file.

즉,이 경우 오류 메시지는와 같은 일반적인 메시지가 아니라 "%s: patch does not apply"보다 구체적인 메시지입니다 .

affected file '%s' is beyond a symbolic link

4

흠, mount --bind다윈에서는 작동하지 않는 것 같습니다.

누구든지 그 트릭을 가지고 있습니까?

[편집]

좋아, Mac OS X의 답은 하드 링크를 만드는 것입니다. API가를 통해 노출되지 않는다는 점을 제외하고는 ln이를 위해 작은 프로그램을 사용해야합니다. 해당 프로그램에 대한 링크는 다음과 같습니다.

Mac OS X에서 디렉토리 하드 링크 생성

즐겨!


1
이 하드 링크의 대상 디렉토리가 다른 git repo의 서브 디렉토리 인 경우 혼란이됩니다. 하드 링크에서 git 작업을 수행하면이 다른 git repo에 적용됩니다. 하고있는 일을 다시 확인하십시오.
yegle

4
포트를 사용하여 설치할 수있는 code.google.com/p/bindfs 를 통해이 작업을 수행 할 수 있습니다.
Kit Sunde 2013

0

Git 1.5.4.3을 사용하고 있으며 슬래시가 있으면 전달 된 symlink를 따릅니다. 예 :

# Adds the symlink itself
$ git add symlink

# Follows symlink and adds the denoted directory's contents
$ git add symlink/

5
적어도 OSX에서는 다음과 같은 결과가 나타납니다.fatal: 'src/' is beyond a symbolic link
Dan Rosenstark

2
@Mark Longair가 설명했듯이 이것은 git 1.6.1까지만 작동했습니다.
MestreLion

그게 내 문제 였어, 고마워!
Mike Q

0

심볼릭 링크에서의 변환이 유용 할 수 있습니다. 스크립트 로 심볼릭 링크 대신 Git 폴더에 링크하십시오 .


답변에 더 자세한 내용을 추가 하시겠습니까?
Devin G Rhode
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.