힘내 서브 모듈 헤드 '참조는 나무가 아닙니다'오류
잘못된 커밋을 가리키는 서브 모듈이있는 프로젝트가 있습니다. 서브 모듈 커밋은 로컬로 유지되었으며 다른 리포지토리에서 가져 오려고하면 다음과 같은 결과가 나타납니다.
$ git submodule update
fatal: reference is not a tree: 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
Unable to checkout '2d7cfbd09fc96c04c4c41148d44ed7778add6b43' in submodule path 'mysubmodule'
내가 로컬로 변경할 수있는 방법은,이 서브 모듈의 HEAD가의 repo에서 누르지 않고해야합니다 알고 않습니다 저지했다 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
?
내가 분명하고 있는지 확실하지 않습니다 ... 여기 내가 찾은 비슷한 상황이 있습니다.
서브 모듈의 리포지토리에 사용하려는 커밋이 포함되어 있다고 가정하면 (수퍼 프로젝트의 현재 상태에서 참조되는 커밋과 달리) 두 가지 방법이 있습니다.
첫 번째는 사용하려는 서브 모듈의 커밋을 이미 알고 있어야합니다. 하위 모듈을 직접 조정 한 다음 수퍼 프로젝트를 업데이트하여 "내부, 외부"에서 작동합니다. 두 번째는“외부에서”서브 모듈을 수정 한 수퍼 프로젝트의 커밋을 찾은 다음 다른 서브 모듈 커밋을 참조하도록 수퍼 프로젝트의 인덱스를 재설정하여 작동합니다.
뒤집어서
당신이 이미 알고있는 경우에는 사용에 서브 모듈, 원하는 커밋 된 cd
다음, 당신이 원하는 커밋 체크 아웃, 서브 모듈로를 git add
하고 git commit
는 다시 슈퍼 프로젝트이다.
예:
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
누군가가 서브 모듈에서 게시되지 않은 커밋을 나타내는 슈퍼 프로젝트 커밋을 만들었습니다 sub
. 어쨌든 우리는 이미 서브 모듈이 커밋되기를 원한다는 것을 알고 있습니다 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
. 거기 가서 직접 확인하십시오.
서브 모듈에서 체크 아웃
$ cd sub
$ git checkout 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Note: moving to '5d5a3ee314476701a20f2c6ec4a53f88d651df6c' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
git checkout -b <new_branch_name>
HEAD is now at 5d5a3ee... quux
$ cd ..
커밋을 체크 아웃하기 때문에 서브 모듈에서 HEAD가 분리됩니다. 서브 모듈이 브랜치를 사용하고 있는지 확인 git checkout -b newbranch <commit>
하려면 커밋에서 브랜치를 생성 및 체크 아웃하거나 원하는 브랜치를 체크 아웃하십시오 (예 : 원하는 커밋이있는 브랜치).
슈퍼 프로젝트 업데이트
하위 모듈의 체크 아웃은 작업 트리 변경으로 수퍼 프로젝트에 반영됩니다. 따라서 우리는 수퍼 프로젝트의 색인 변경을 준비하고 결과를 확인해야합니다.
$ git add sub
결과 확인
$ git submodule update
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
서브 모듈이 이미 지정된 커밋에 있으므로 서브 모듈 업데이트가 자동입니다. 첫 번째 diff는 인덱스와 작업 트리가 동일 함을 보여줍니다. 세 번째 차이점은 단계적 변경 만이 sub
서브 모듈을 다른 커밋으로 옮기는 것임을 보여줍니다 .
범하다
git commit
이것은 고정 서브 모듈 엔트리를 커밋한다.
밖에서
서브 모듈에서 어떤 커밋을 사용해야할지 확실하지 않은 경우 수퍼 프로젝트의 히스토리를보고 안내 할 수 있습니다. 수퍼 프로젝트에서 직접 재설정을 관리 할 수도 있습니다.
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'
위와 같은 상황입니다. 그러나 이번에는 서브 모듈에 담그지 않고 수퍼 프로젝트에서 수정하는 데 중점을 둘 것입니다.
슈퍼 프로젝트의 Errant Commit 찾기
$ git log --oneline -p -- sub
ce5d37c local change in sub
diff --git a/sub b/sub
index 5d5a3ee..e47c0a1 160000
--- a/sub
+++ b/sub
@@ -1 +1 @@
-Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
+Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
bca4663 added sub
diff --git a/sub b/sub
new file mode 160000
index 0000000..5d5a3ee
--- /dev/null
+++ b/sub
@@ -0,0 +1 @@
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
좋아,에서 잘못 된 것처럼 보이 ce5d37c
므로 하위 모듈을 부모 ( ce5d37c~
) 에서 복원 할 것 입니다.
또는 패치 텍스트 ( 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
) 에서 서브 모듈의 커밋을 가져 와서 위의 "내부, 외부"프로세스를 대신 사용할 수 있습니다.
슈퍼 프로젝트에서 체크 아웃
$ git checkout ce5d37c~ -- sub
이렇게하면 서브 프로젝트 항목이 수퍼 프로젝트 sub
에서 커밋 ce5d37c~
된 항목으로 재설정 됩니다.
서브 모듈 업데이트
$ git submodule update
Submodule path 'sub': checked out '5d5a3ee314476701a20f2c6ec4a53f88d651df6c'
하위 모듈 업데이트가 정상적으로 진행되었습니다 (분리 된 HEAD를 나타냄).
결과 확인
$ git diff ce5d37c~ -- sub
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
첫 번째 차이점 sub
은 현재와 동일 하다는 것을 보여줍니다 ce5d37c~
. 두 번째 diff는 인덱스와 작업 트리가 동일 함을 보여줍니다. 세 번째 차이점은 단계적 변경이 sub
서브 모듈을 다른 커밋으로 옮기는 것만 보여줍니다 .
범하다
git commit
이것은 고정 서브 모듈 엔트리를 커밋한다.
이 시도:
git submodule sync
git submodule update
이 오류는 서브 모듈에서 커밋이 누락되었음을 의미 할 수 있습니다. 즉, 저장소 (A)는 서브 모듈 (B)을 갖는다. A는 B를로드하여 특정 커밋을 가리 킵니다 (B). 커밋이 누락 된 경우 해당 오류가 발생합니다. 가능한 원인 : 커밋에 대한 참조는 A로 푸시되었지만 실제 커밋은 B에서 푸시되지 않았습니다.
권한 문제가 있고 커밋을 가져올 수 없습니다 (git + ssh를 사용하는 경우 가능).
.git / config 및 .gitmodules에서 하위 모듈 경로가 제대로 표시되는지 확인하십시오.
마지막으로 시도해야 할 것-서브 모듈 디렉토리 내부 : git reset HEAD --hard
가능한 원인
다음과 같은 경우에 발생할 수 있습니다.
- 서브 모듈이 제자리에서 편집되었습니다
- 서브 모듈이 커밋되었습니다. 이 모듈은 지정된 서브 모듈의 해시를 업데이트합니다.
- 하위 모듈이 푸시되지 않았습니다 .
예를 들어 이와 같은 일이 발생했습니다.
$ cd submodule
$ emacs my_source_file # edit some file(s)
$ git commit -am "Making some changes but will forget to push!"
이 시점에서 서브 모듈이 푸시되어야합니다.
$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git push origin master
결과적으로 누락 된 커밋은 여전히 로컬 디스크에 있기 때문에 원격 사용자가 찾을 수 없습니다.
해결책
Informa 하위 모듈을 밀어서 수정 한 사람, 즉
$ cd submodule
$ git push
내가 할 때이 오류가 발생했습니다.
$ git submodule update --init --depth 1
그러나 부모 프로젝트의 커밋은 이전 커밋을 가리 켰습니다.
하위 모듈 폴더를 삭제하고 실행 중 :
$ git submodule update --init
문제를 해결하지 못했습니다. 나는 repo를 삭제하고 깊이 플래그없이 다시 시도했으며 작동했습니다.
이 오류는 Ubuntu 16.04 git 2.7.4에서는 발생하지만 Ubuntu 18.04 git 2.17에서는 발생하지 않습니다. TODO는 정확한 고정 커밋 또는 버전을 찾습니다.
리베이스 된 리포지토리를 가리키는 하위 모듈이 있고 지정된 커밋이 "사라진"경우에도 발생할 수 있습니다. 커밋은 여전히 원격 리포지토리에있을 수 있지만 브랜치에는 없습니다. 새로운 브랜치를 만들 수 없다면 (예 : 저장소가 아닌), 새로운 커밋을 가리 키도록 수퍼 프로젝트를 업데이트해야합니다. 또는 서브 모듈 사본 중 하나를 다른 곳으로 푸시 한 다음 대신 해당 저장소를 가리 키도록 수퍼 프로젝트를 업데이트 할 수 있습니다.
이 답변은 터미널 git 환경이 제한된 SourceTree 사용자를위한 것입니다.
Git 프로젝트 (슈퍼 프로젝트)에서 문제가있는 하위 모듈을 엽니 다.
가져 오기 및 '모든 태그 가져 오기'가 선택되어 있는지 확인하십시오.
Git 프로젝트를 리베이스하십시오.
이것은 '참조는 나무가 아니다'문제를 10 번 중 9 번 해결한다. 1 번은 그렇지 않습니다. 최고의 답변으로 설명 된 터미널 수정입니다.
지사는 최신 상태가 아닌 간단한 해결책 일 수 있습니다. git fetch
하위 모듈 기록은 하위 모듈 git에 안전하게 유지됩니다.
그렇다면 왜 서브 모듈을 삭제하고 다시 추가하지 않습니까?
그렇지 않으면, 당신은 수동으로 편집하려고했던 HEAD
또는를 refs/master/head
서브 모듈 내에서.git
확실하게 git
바이너리를 업데이트하십시오 .
Windows 용 GitHub git version 1.8.4.msysgit.0
에는 문제 가있는 버전 이 있습니다. 업데이트하면 해결되었습니다.
내 경우에는 위의 답변 중 어느 것도 좋은 답변이라고해도 문제를 해결하지 못합니다. 따라서 솔루션을 게시합니다 (내 경우에는 클라이언트 A와 B의 두 가지 git 클라이언트가 있습니다).
하위 모듈의 디렉토리로 이동하십시오.
cd sub
마스터 체크 아웃 :
git checkout master
두 클라이언트 모두 볼 수있는 커밋 코드로 리베이스
부모의 디렉토리로 돌아갑니다.
마스터하다
다른 클라이언트로 변경하고
rebase
다시 수행 하십시오.마침내 이제는 잘 작동합니다! 어쩌면 몇 가지 커밋을 잃을 수도 있지만 작동합니다.
참고로, 서브 모듈을 제거하려고 시도하지 마십시오. 서브 모듈은
.git/modules
로컬에 반응하지 않으면 서브 모듈을 다시 읽을 수 없습니다.
git repo를 서브 모듈의 헤드와 동기화하기 위해 실제로 원하는 경우 서브 모듈을 제거한 다음 읽는 것이 히스토리와 땜질을 피한다는 것을 알았습니다. 불행히도 서브 모듈을 제거하려면 단일 git 명령이 아닌 해킹이 필요하지만 가능합니다.
https://gist.github.com/kyleturner/1563153 에서 영감을 얻은 하위 모듈을 제거하기 위해 수행 한 단계 :
- git rm --cached를 실행하십시오.
- .gitmodules 파일에서 관련 행을 삭제하십시오.
- .git / config에서 관련 섹션을 삭제하십시오.
- 이제 추적되지 않은 서브 모듈 파일을 삭제하십시오.
- .git / modules / 디렉토리를 제거하십시오
다시 말하지만, 서브 모듈의 헤드를 다시 가리키고 서브 모듈의 로컬 사본을 그대로 유지해야하는 복잡한 작업이없는 경우 유용 할 수 있습니다. 소스 모듈이 어디에 있든지 서브 모듈 "오른쪽"을 자체 리포지토리로 가지고 있다고 가정하고 서브 모듈로 포함시키기 만하면됩니다.
참고 : 간단한 커밋이나 푸시 이외의 조작이나 git 명령을 수행하기 전에 항상 프로젝트의 전체 사본을 만드십시오. 다른 모든 답변과 일반적인 git 지침으로 조언 할 것입니다.
이 문제에 대해 막 넘어서서 이러한 해결책 중 어느 것도 나를 위해 일하지 않았습니다. 내 문제에 대한 해결책으로 밝혀진 것은 실제로 훨씬 간단합니다 : 업그레이드 Git. 광산은 1.7.1 였고 2.16.1 (최신)로 업그레이드 한 후 문제는 흔적없이 사라졌습니다! 내가 여기에 떠날 것 같아, 누군가를 돕기를 바랍니다.
참고 URL : https://stackoverflow.com/questions/2155887/git-submodule-head-reference-is-not-a-tree-error
'Programing' 카테고리의 다른 글
Django가있는 AngularJS-템플릿 태그 충돌 (0) | 2020.03.15 |
---|---|
nativeGetEnabledTags에서 예기치 않은 값 : 0 (0) | 2020.03.15 |
C # Lambda 표현식 : 왜 사용해야합니까? (0) | 2020.03.15 |
Big-O와 Little-O 표기법의 차이점 (0) | 2020.03.15 |
누락 된 패키지를 확인하고 설치하는 우아한 방법? (0) | 2020.03.15 |