Git 서브 모듈을 추가 할 때 브랜치 / 태그를 어떻게 지정할 수 있습니까?
어떻게 git submodule add -b
작동합니까?
특정 분기가있는 하위 모듈을 추가하면 새 복제 저장소 (이후 git submodule update --init
)가 분기 자체가 아닌 특정 커밋에있게됩니다 ( git status
하위 모듈에서 "현재 분기에 없음"으로 표시됨).
나는에 대한 정보 찾을 수없는 .gitmodules
나 .git/config
, 서브 모듈의 지점 또는 특정 커밋에 대한을 어떻게 수행 망할 놈의 그림을 알아?
또한 분기 대신 태그를 지정할 수 있습니까?
버전 1.6.5.2를 사용하고 있습니다.
참고 : Git 1.8.2에는 분기 추적 기능이 추가되었습니다. 아래 답변 중 일부를 참조하십시오.
이것에 익숙해지는 것은 약간 혼란 스럽지만 서브 모듈은 브랜치에 없습니다. 당신이 말했듯이 그것들은 단지 서브 모듈 저장소의 특정 커밋에 대한 포인터 일뿐입니다.
즉, 다른 사람이 저장소를 체크 아웃하거나 코드를 가져 와서 git 하위 모듈을 업데이트하면 해당 특정 커밋에 하위 모듈이 체크 아웃됩니다.
프로젝트의 모든 사람이 동일한 커밋에서 하위 모듈을 가질 수 있기 때문에 자주 변경되지 않는 하위 모듈에 적합합니다.
하위 모듈을 특정 태그로 이동하려면 :
cd submodule_directory
git checkout v1.0
cd ..
git add submodule_directory
git commit -m "moved submodule to v1.0"
git push
그런 다음 submodule_directory를 해당 태그로 변경하려는 다른 개발자가
git pull
git submodule update --init
git pull
서브 모듈 디렉토리가 가리키는 변경 사항. git submodule update
실제로 새 코드에 병합됩니다.
여기에 다른 답변의 대기업에 불과한 답변을 추가하고 싶지만 더 완벽 할 것이라고 생각합니다.
이 두 가지가 있으면 Git 하위 모듈이 있다는 것을 알고 있습니다.
다음
.gitmodules
과 같은 항목이 있습니다.[submodule "SubmoduleTestRepo"] path = SubmoduleTestRepo url = https://github.com/jzaccone/SubmoduleTestRepo.git
Git 리포지토리에 하위 모듈 개체 (이 예제에서는 SubmoduleTestRepo라고 함)가 있습니다. GitHub 는이를 "하위 모듈"개체로 표시합니다. 또는
git submodule status
명령 줄에서 수행하십시오 . Git 하위 모듈 객체는 특별한 종류의 Git 객체이며 특정 커밋에 대한 SHA 정보를 보유합니다.를 할 때마다
git submodule update
커밋의 콘텐츠로 서브 모듈을 채 웁니다. 의 정보 때문에 커밋을 찾을 위치를 알고.gitmodules
있습니다.이제 파일에
-b
한 줄을 추가하면.gitmodules
됩니다. 따라서 동일한 예를 따르면 다음과 같습니다.[submodule "SubmoduleTestRepo"] path = SubmoduleTestRepo url = https://github.com/jzaccone/SubmoduleTestRepo.git branch = master
참고 :
.gitmodules
파일 에서 분기 이름 만 지원 되지만 SHA 및 TAG는 지원되지 않습니다! (그 대신 각 모듈의 브랜치 커밋은 "git add .
"를 사용하여 추적하고 업데이트 할 수 있습니다 ( 예 :)git add ./SubmoduleTestRepo
..gitmodules
매번 파일 을 변경할 필요가 없습니다. )서브 모듈 객체는 여전히 특정 커밋을 가리키고 있습니다.
-b
옵션이 구매 하는 유일한 것은--remote
Vogella의 답변에 따라 업데이트에 플래그를 추가하는 기능입니다 .git submodule update --remote
서브 모듈이 가리키는 커밋에 서브 모듈의 내용을 채우는 대신 해당 커밋을 마스터 브랜치의 최신 커밋으로 대체 한 다음 해당 커밋으로 서브 모듈을 채 웁니다. 이것은 djacobs7 답변으로 두 단계로 수행 할 수 있습니다. 이제 서브 모듈 객체가 가리키는 커밋을 업데이트 했으므로 변경된 서브 모듈 객체를 Git 저장소에 커밋해야합니다.
git submodule add -b
브랜치로 모든 것을 최신 상태로 유지하는 마법 같은 방법이 아닙니다..gitmodules
파일 의 분기에 대한 정보를 추가 하고 채우기 전에 지정된 분기의 최신 커밋으로 하위 모듈 객체를 업데이트하는 옵션을 제공합니다.
(Git 2.22, 2019 년 2 분기 출시 git submodule set-branch --branch aBranch -- <submodule_path>
)
참고 당신이 경우 기존의 서브 모듈 되지 않은 아직 지점을 추적 (다음을, 당신은 자식 1.8.2+이있는 경우 ) :
상위 저장소가 하위 모듈이 이제 분기를 추적한다는 것을 알고 있는지 확인하십시오.
cd /path/to/your/parent/repo git config -f .gitmodules submodule.<path>.branch <branch>
서브 모듈이 실제로 해당 분기의 최신 버전인지 확인하십시오.
cd path/to/your/submodule git checkout -b branch --track origin/branch # if the master branch already exist: git branch -u origin/master master
( "원산지"의 이름으로 되 REPO 상류 원격 서브 모듈.로부터 클로닝되었다 해당 서브 모듈을 표시 안에. 일반적으로, 그것이 '원점')git remote -v
상위 저장소에 하위 모듈의 새 상태를 기록하는 것을 잊지 마십시오.
cd /path/to/your/parent/repo git add path/to/your/submodule git commit -m "Make submodule tracking a branch"
해당 하위 모듈에 대한 후속 업데이트는 다음
--remote
옵션 을 사용해야합니다 .# update your submodule # --remote will also fetch and ensure that # the latest commit from the branch is used git submodule update --remote # to avoid fetching use git submodule update --remote --no-fetch
Note that with Git 2.10+ (Q3 2016), you can use '.
' as a branch name:
The name of the branch is recorded as
submodule.<name>.branch
in.gitmodules
forupdate --remote
.
A special value of.
is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository.
If you want to update all your submodules following a branch:
git submodule update --recursive --remote
Note that the result, for each updated submodule, will almost always be a detached HEAD, as Dan Cameron note in his answer.
(Clintm notes in the comments that, if you run git submodule update --remote
and the resulting sha1 is the same as the branch the submodule is currently on, it won't do anything and leave the submodule still "on that branch" and not in detached head state.)
To ensure the branch is actually checked out (and that won't modify the SHA1 of the special entry representing the submodule for the parent repo), he suggests:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git checkout $branch'
Each submodule will still reference the same SHA1, but if you do make new commits, you will be able to push them because they will be referenced by the branch you want the submodule to track.
After that push within a submodule, don't forget to go back to the parent repo, add, commit and push the new SHA1 for those modified submodules.
Note the use of $toplevel
, recommended in the comments by Alexander Pogrebnyak.
$toplevel
was introduced in git1.7.2 in May 2010: commit f030c96.
it contains the absolute path of the top level directory (where
.gitmodules
is).
dtmland
adds in the comments:
The foreach script will fail to checkout submodules that are not following a branch.
However, this command gives you both:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch' –
The same command but easier to read:
git submodule foreach -q --recursive \
'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
[ "$branch" = "" ] && \
git checkout master || git checkout $branch' –
umläute refines dtmland's command with a simplified version in the comments:
git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
multiple lines:
git submodule foreach -q --recursive \
'git checkout \
$(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
Git 1.8.2 added the possibility to track branches.
# add submodule to track master branch
git submodule add -b branch_name URL_to_Git_repo optional_directory_rename
# update your submodule
git submodule update --remote
See also Git submodules
An example of how I use Git submodules.
- Create a new repository
- Then clone another repository as a submodule
- Then we have that submodule use a tag called V3.1.2
- And then we commit.
And that looks a little bit like this:
git init
vi README
git add README
git commit
git submodule add git://github.com/XXXXX/xxx.yyyy.git stm32_std_lib
git status
git submodule init
git submodule update
cd stm32_std_lib/
git reset --hard V3.1.2
cd ..
git commit -a
git submodule status
Maybe it helps (even though I use a tag and not a branch)?
In my experience switching branches in the superproject or future checkouts will still cause detached HEADs of submodules regardless if the submodule is properly added and tracked (i.e. @djacobs7 and @Johnny Z answers).
And instead of manually checking out the correct branch manually or through a script git submodule foreach can be used.
This will check the submodule config file for the branch property and checkout the set branch.
git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'
Git submodules are a little bit strange - they're always in "detached head" mode - they don't update to the latest commit on a branch like you might expect.
This does make some sense when you think about it, though. Let's say I create repository foo with submodule bar. I push my changes and tell you to check out commit a7402be from repository foo.
Then imagine that someone commits a change to repository bar before you can make your clone.
When you check out commit a7402be from repository foo, you expect to get the same code I pushed. That's why submodules don't update until you tell them to explicitly and then make a new commit.
Personally I think submodules are the most confusing part of Git. There are lots of places that can explain submodules better than I can. I recommend Pro Git by Scott Chacon.
To switch branch for a submodule (assuming you already have the submodule as part of the repository):
cd
to root of your repository containing the submodules- Open
.gitmodules
for editing - Add line below
path = ...
andurl = ...
that saysbranch = your-branch
, for each submodule; save file.gitmodules
. - then without changing directory do
$ git submodule update --remote
...this should pull in the latest commits on the specified branch, for each submodule thus modified.
I have this in my .gitconfig file. It is still a draft, but proved useful as of now. It helps me to always reattach the submodules to their branch.
[alias]
######################
#
#Submodules aliases
#
######################
#git sm-trackbranch : places all submodules on their respective branch specified in .gitmodules
#This works if submodules are configured to track a branch, i.e if .gitmodules looks like :
#[submodule "my-submodule"]
# path = my-submodule
# url = git@wherever.you.like/my-submodule.git
# branch = my-branch
sm-trackbranch = "! git submodule foreach -q --recursive 'branch=\"$(git config -f $toplevel/.gitmodules submodule.$name.branch)\"; git checkout $branch'"
#sm-pullrebase :
# - pull --rebase on the master repo
# - sm-trackbranch on every submodule
# - pull --rebase on each submodule
#
# Important note :
#- have a clean master repo and subrepos before doing this !
#- this is *not* equivalent to getting the last committed
# master repo + its submodules: if some submodules are tracking branches
# that have evolved since the last commit in the master repo,
# they will be using those more recent commits !
#
# (Note : On the contrary, git submodule update will stick
#to the last committed SHA1 in the master repo)
#
sm-pullrebase = "! git pull --rebase; git submodule update; git sm-trackbranch ; git submodule foreach 'git pull --rebase' "
# git sm-diff will diff the master repo *and* its submodules
sm-diff = "! git diff && git submodule foreach 'git diff' "
#git sm-push will ask to push also submodules
sm-push = push --recurse-submodules=on-demand
#git alias : list all aliases
#useful in order to learn git syntax
alias = "!git config -l | grep alias | cut -c 7-"
We use Quack to pull a specific module from another Git repository. We need to pull code without the whole code base of the provided repository - we need a very specific module / file from that huge repository and should be updated every time we run update.
So we achieved it in this way:
Create configuration
name: Project Name
modules:
local/path:
repository: https://github.com/<username>/<repo>.git
path: repo/path
branch: dev
other/local/path/filename.txt:
repository: https://github.com/<username>/<repo>.git
hexsha: 9e3e9642cfea36f4ae216d27df100134920143b9
path: repo/path/filename.txt
profiles:
init:
tasks: ['modules']
With the above configuration, it creates one directory from the provided GitHub repository as specified in first module configuration, and the other one is to pull and create a file from the given repository.
Other developers just need to run
$ quack
And it pulls the code from the above configurations.
The only effect of choosing a branch for a submodule is that, whenever you pass the --remote
option in the git submodule update
command line, Git will check out in detached HEAD mode (if the default --checkout
behavior is selected) the latest commit of that selected remote branch.
You must be particularly careful when using this remote branch tracking feature for Git submodules if you work with shallow clones of submodules. The branch you choose for this purpose in submodule settings IS NOT the one that will be cloned during git submodule update --remote
. If you pass also the --depth
parameter and you do not instruct Git about which branch you want to clone -- and actually you cannot in the git submodule update
command line!! -- , it will implicitly behave like explained in the git-clone(1)
documentation for git clone --single-branch
when the explicit --branch
parameter is missing, and therefore it will clone the primary branch only.
With no surprise, after the clone stage performed by the git submodule update
command, it will finally try to check out the latest commit for the remote branch you previously set up for the submodule, and, if this is not the primary one, it is not part of your local shallow clone, and therefore it will fail with
fatal: Needed a single revision
Unable to find current origin/NotThePrimaryBranch revision in submodule path 'mySubmodule'
git submodule add -b develop --name branch-name -- https://branch.git
'developer tip' 카테고리의 다른 글
인쇄 미리보기 모드에서 Chrome의 요소 검사기를 사용하십니까? (0) | 2020.10.02 |
---|---|
문자열이 숫자인지 식별 (0) | 2020.09.30 |
유형에서 새 개체 인스턴스를 만드는 방법 (0) | 2020.09.30 |
쉼표로 구분 된 문자열을 배열로 변환하는 방법은 무엇입니까? (0) | 2020.09.30 |
Python 함수에서 예외가 발생하는지 어떻게 테스트합니까? (0) | 2020.09.30 |