git submodule add -b
はどのように機能しますか?
特定のブランチを持つサブモジュールを追加した後、新しいクローン化されたリポジトリ(git submodule update --init
の後)はブランチ自体ではなく特定のコミットになります(サブモジュールのgit status
には「現在どのブランチにもない」と表示されます)。
サブモジュールのブランチや特定のコミットに関する.gitmodules
や.git/config
に関する情報が見つからないのですが、Gitはどうやってそれを把握しているのでしょうか。
また、ブランチの代わりにタグを指定することは可能ですか?
私はバージョン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
そのサブモジュールディレクトリが指すコミットする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
ファイルに1行追加するだけです。したがって、同じ例に従うと、このようになります。
[submodule "SubmoduleTestRepo"]
path = SubmoduleTestRepo
url = https://github.com/jzaccone/SubmoduleTestRepo.git
branch = master
編集:上記でサポートされているのはブランチ名のみで、SHAやTAGはサポートされていません。
サブモジュールオブジェクトはまだ特定のコミットを指しています。 -b
オプションがあなたを買う唯一のものはVogellaの答えに従ってあなたの更新に--remote
フラグを追加する能力です:
git submodule update --remote
サブモジュールの内容をサブモジュールが指すコミットに移入する代わりに、そのコミットをマスターブランチの最新のコミットに置き換えます。そうすると、サブモジュールにそのコミットが移入されます。これは、djacobs 7 answerによって2段階で実行できます。サブモジュールオブジェクトが指しているコミットを更新したので、変更したサブモジュールオブジェクトをGitリポジトリにコミットする必要があります。
git submodule add -b
は、すべてをブランチで最新に保つための魔法のような方法ではありません。それは単に.gitmodules
ファイルにブランチについての情報を追加して、それを生成する前にサブモジュールオブジェクトを指定されたブランチの最新のコミットに更新するオプションをあなたに与えます。
Git 1.8.2ではブランチを追跡する可能性が追加されました。
# 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
Gitサブモジュールの使用例.
そしてそれはこのように少し見えます:
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
たぶんそれは助けになるでしょう(たとえ私がタグを使っていて、ブランチを使わなくても)
私の経験では、スーパープロジェクトや将来のチェックアウトでブランチを切り替えても、サブモジュールが適切に追加および追跡されているかどうかに関係なく、サブモジュールの分離HEADが発生します(つまり@ djacobs7と@Johnny Zの回答)。
そして手動で、またはスクリプトを通じて手動で正しいブランチをチェックアウトする代わりに gitサブモジュール を使用することができます。
これにより、サブモジュールのconfigファイルでbranchプロパティがチェックされ、設定されたブランチがチェックアウトされます。
git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'
Gitサブモジュールはちょっと奇妙です - 彼らはいつも "デタッチヘッド"モードにあります - 彼らはあなたが期待するかもしれないようなブランチの最新のコミットに更新しません。
あなたがそれについて考えるとき、これはある程度意味があります。サブモジュール bar を使ってリポジトリ foo を作成したとしましょう。私の変更をプッシュして、リポジトリからコミットa7402beをチェックアウトするように指示します foo 。
それからクローンを作る前に誰かがrepository bar への変更をコミットしたと想像してください。
Repository foo からcommit a7402beをチェックアウトすると、私がプッシュしたのと同じコードが表示されるはずです。そのため、サブモジュールが明示的に指示してから新しいコミットを行うまでサブモジュールは更新されません。
個人的には、サブモジュールはGitの最も分かりにくい部分だと思います。サブモジュールを説明できる場所は、私よりもたくさんあります。 Pro Git Scott Chacon作。
サブモジュールのブランチを切り替えるには(サブモジュールが既にリポジトリの一部としてあると仮定します)。
cd
.gitmodules
を編集用に開きますpath = ...
とurl = ...
の下にbranch = your-branch
という行を追加します。ファイル.gitmodules
を保存します。$ git submodule update --remote
を実行します...これにより、変更された各サブモジュールについて、指定されたブランチの最新のコミットが取り込まれるはずです。
.gitconfigファイルにこれがあります。それはまだドラフトですが、今のところ有用であることがわかりました。それは私が常にサブモジュールをそれらのブランチに再接続するのを助けます。
[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 = [email protected]/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-"
他のGitリポジトリから特定のモジュールを取得するために Quack を使用します。提供されたレポジトリのコードベース全体を使わずにコードを引っ張る必要があります - その巨大なレポジトリからの非常に特定のモジュール/ファイルが必要であり、updateを実行するたびに更新されるべきです。
だから我々はこのようにしてそれを達成しました:
設定を作成します
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']
上記の設定では、最初のモジュール設定で指定されているように、提供されたGitHubリポジトリから1つのディレクトリを作成し、もう1つは与えられたリポジトリからファイルを取得して作成します。
他の開発者はただ実行する必要があります
$ quack
そしてそれは上記の設定からコードを引き出します。
サブモジュールのブランチを選択することの唯一の効果は、--remote
コマンドラインでgit submodule update
オプションを渡すときはいつでも、Gitは detached HEAD モードでチェックアウトするということです(デフォルトの場合は--checkout
)振る舞いが選択されていること)その選択された remote branchの最新のコミット。
サブモジュールのシャロークローンを扱う場合は、Gitサブモジュールに対してこのリモートブランチトラッキング機能を使用するときに特に注意が必要です。サブモジュール設定でこの目的のために選択したブランチ IS NOT git submodule update --remote
の間に複製されるブランチ。 --depth
パラメータと も渡すと、どのブランチをクローンしたいのかについてGitに指示しない - そして実際にはできません git submodule update
コマンドラインで!! - 明示的なgit clone --single-branch
パラメータがない場合、--branch
のgit-clone(1)
ドキュメントで説明されているように、暗黙的に振る舞います。したがって、 プライマリブランチのみを複製します 。
当然のことながら、git submodule update
コマンドによって実行されたクローン作成ステージの後、サブモジュール用に以前に設定した remote ブランチ用の最新のコミットを最終的にチェックしようとします。それはあなたの地元の浅いクローンの一部ではない、そしてそれゆえ失敗するでしょう
fatal:シングルリビジョンが必要
現在のOriginを見つけることができません/ NotThePrimaryBranch サブモジュールパス 'mySubmodule'にリビジョン
gitサブモジュールadd -b Develop --name branch-name - https://branch.git