Git Submodule 포인터를 포함하는 저장소에 저장된 커밋으로 되 돌리는 방법은 무엇입니까?


128

내 기본 git repo에 git 하위 모듈이 있습니다. 내가 이해하는대로 메인 저장소는 SHA 값 (어딘가에 ...)을 저장하여 "연결된"하위 모듈의 특정 커밋을 가리 킵니다.

내 하위 모듈로 이동하여 git checkout some_other_branch. 나는 내가 어떤 커밋에서 왔는지 전혀 모른다.

주 저장소와 하위 모듈이 다시 동기화되도록 해당 포인터를 되돌리고 싶습니다.

나의 첫 번째 (아마 순진한) 본능은 git reset --hard다른 모든 것에 효과가있는 것 같다고 말하는 것이 었습니다. 놀랍게도이 시나리오에서는 작동하지 않았습니다.

그래서 내가 입력 할 수 있다는 것을 알아 냈고 git diff, 서브 모듈 포인터가 가지고 있던 SHA ID를 적어 둔 다음 서브 모듈로 이동하고 git checkout [SHA ID]...하지만 더 쉬운 방법이 있어야합니까?

아직 git 하위 모듈에 대해 배우는 중이므로 모르는 개념에 대한 단어가 있으면 내 용어를 자유롭게 수정하십시오.

답변:


167

하위 모듈을 업데이트하여 상위 저장소가 필요하다고 생각하는 것과 동기화되도록하고 싶습니다. 다음은 업데이트 명령의 용도입니다.

서브 모듈 맨 페이지에서 :

등록 된 하위 모듈을 업데이트합니다. 즉, 누락 된 하위 모듈을 복제하고
포함의 색인에 지정된 커밋을 체크 아웃하십시오.
저장소. 이렇게하면 서브 모듈 HEAD가
--rebase 또는 --merge가 지정되었거나 키 하위 모듈. $ name.update
리베이스 또는 병합하도록 설정됩니다.

이것을 실행하면 모든 것이 잘 될 것입니다.

git submodule update

4
어떻게 든 나를 위해 --init. 그것이 없으면 서브 모듈은 (new commits). 내 하위 모듈이 이미 초기화되었지만.
Ambidex

@Ambidex 예, --init옵션은이 모든 것에서 중요합니다. 내 하위 모듈이 https를 통해 복제 되었기 때문에 사용자 이름과 암호를 입력하라는 메시지가 표시되었습니다. 두 폴더에 모두 들어가서 ssh체크 아웃에 프로토콜 을 사용하도록 리모컨을 설정했습니다 .
A-Dubb

1
하위 모듈 커밋 해시가 수정되고 준비되지 않은 경우 작동하지 않음
tribbloid

--recursive를 추가 할 수 있으므로 모든 하위 모듈로 이동할 필요가 없습니다.
Gaspa79

21

서브 모듈이 가리키는 커밋을 변경하려면 서브 모듈에서 해당 버전을 체크 아웃 한 다음 포함 된 저장소로 돌아가서 변경 사항을 추가하고 커밋해야합니다.

또는 하위 모듈이 최상위 저장소가 가리키는 버전에 있도록하려면 git submodule update --recursive. --init방금 복제 한 경우 추가하십시오 .

또한 git submodule하위 모듈 명령이 없으면 가리키는 커밋이 표시됩니다. 동기화되지 않은 경우 커밋 앞에-또는 +가 있습니다.

하위 모듈이있는 트리를 살펴보면 하위 모듈이 commitblob 또는 트리 인 나머지와 반대로 표시되어 있음을 알 수 있습니다 .

특정 커밋이 하위 모듈을 가리키는 wrt를 보려면 다음을 수행 할 수 있습니다.

git ls-tree <some sha1, or branch, etc> Submodule/path

그런 다음 로그 등에 전달하여 커밋이나 다른 것을 볼 수 있습니다 ( git-dirgit 명령 수준 의 옵션을 사용하면 하위 모듈로 이동하지 않아도됩니다).

git --git-dir=Submodule/path log -1 $(<the above statement>)

아래 명령이 도움이되었습니다 (하위 모듈과 모듈의 변경 사항도 무시하고 싶었습니다). git submodule update --init --recursive
Rajesh Goel

6

방금 만난 또 다른 경우는 삭제하려는 하위 모듈에 단계적이지 않은 변경 사항이있는 경우입니다. git 하위 모듈 업데이트는 해당 변경 사항을 제거하지 않으며 부모 디렉토리에서 git reset --hard도하지 않습니다. 하위 모듈 디렉토리로 이동하여 git reset --hard를 수행해야합니다. 따라서 부모 모듈과 하위 모듈 모두에서 단계 화되지 않은 변경 사항을 완전히 삭제하려면 다음을 수행합니다.

부모 :

git reset --hard

git submodule update

서브 모듈에서 :

git reset --hard

5

git ls-tree HEAD"superproject"폴더에서 사용 하여 서브 모듈이 원래 있던 커밋을 확인합니다. 그런 다음 하위 모듈 디렉토리로 변경하고 사용 git log --oneline --decorate하여 원래 커밋이있는 브랜치를 확인합니다. 마지막으로 git checkout original-commit-branch.

내가 설정 한 일부 테스트 디렉토리를 사용하여 다음과 같은 명령을 사용할 수 있습니다.

$ git --version
git version 1.7.4.1
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   sm2 (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git ls-tree HEAD
100644 blob 76813a07ae558db274cefc6d903ec24323fdeb0d    .gitmodules
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    main
160000 commit 7c5889497938cd5699a9234a98ee93947e52b1ed  sm1
160000 commit f68bed61cba6f94cef57554f2cf46a45a4a0d337  sm2
$ cd sm2
$ git log --oneline --decorate
5b8d48f (HEAD, foo1) foo1.1
f68bed6 (origin/master, origin/HEAD, master) Initial commit.
$ git checkout master
Switched to branch 'master'
$ cd ..
$ git status
# On branch master
nothing to commit (working directory clean)

"superproject"는 커밋시 sm2 하위 모듈을 보여 f68bed6주지만 sm2는 HEAD에 HEAD가 5b8d48f있습니다. 서브 모듈 커밋 f68bed6에는 서브 모듈 디렉토리에서 체크 아웃하는 데 사용할 수있는 세 가지 분기가 있습니다.


DAN, PERFECTO에게 감사드립니다!
Alec


1

하위 모듈과 내 모듈의 변경 사항을 무시하고 싶었습니다.

아래 명령이 도움이되었습니다.

git submodule update --init --recursive
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.