web-dev-qa-db-ja.com

Gitサブモジュールを追加するときにどうやってブランチ/タグを指定できますか?

git submodule add -bはどのように機能しますか?

特定のブランチを持つサブモジュールを追加した後、新しいクローン化されたリポジトリ(git submodule update --initの後)はブランチ自体ではなく特定のコミットになります(サブモジュールのgit statusには「現在どのブランチにもない」と表示されます)。

サブモジュールのブランチや特定のコミットに関する.gitmodules.git/configに関する情報が見つからないのですが、Gitはどうやってそれを把握しているのでしょうか。

また、ブランチの代わりにタグを指定することは可能ですか?

私はバージョン1.6.5.2を使っています。

630
Ivan

注: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は実際には新しいコードにマージされます。

654
djacobs7

ここに答えを追加したいのですが、それは本当に他の答えの集合体ですが、もっと完全かもしれないと思います。

これら二つのことがあるときあなたはあなたがGitサブモジュールを持っていることを知っています。

  1. あなたの.gitmodulesにはこんな感じのエントリがあります:

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
    
  2. 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ファイルにブランチについての情報を追加して、それを生成する前にサブモジュールオブジェクトを指定されたブランチの最新のコミットに更新するオプションをあなたに与えます。

495
Johnny Z

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サブモジュールも参照

175
vogella

Gitサブモジュールの使用例.

  1. 新しいリポジトリを作成する
  2. 次に、別のリポジトリをサブモジュールとして複製します。
  3. それから、そのサブモジュールにV3.1.2というタグを使用させます。
  4. そして私たちはコミットします。

そしてそれはこのように少し見えます:

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 

たぶんそれは助けになるでしょう(たとえ私がタグを使っていて、ブランチを使わなくても)

50
Johan

私の経験では、スーパープロジェクトや将来のチェックアウトでブランチを切り替えても、サブモジュールが適切に追加および追跡されているかどうかに関係なく、サブモジュールの分離HEADが発生します(つまり@ djacobs7と@Johnny Zの回答)。

そして手動で、またはスクリプトを通じて手動で正しいブランチをチェックアウトする代わりに gitサブモジュール を使用することができます。

これにより、サブモジュールのconfigファイルでbranchプロパティがチェックされ、設定されたブランチがチェックアウトされます。

git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'

35
Dan Cameron

Gitサブモジュールはちょっと奇妙です - 彼らはいつも "デタッチヘッド"モードにあります - 彼らはあなたが期待するかもしれないようなブランチの最新のコミットに更新しません。

あなたがそれについて考えるとき、これはある程度意味があります。サブモジュール bar を使ってリポジトリ foo を作成したとしましょう。私の変更をプッシュして、リポジトリからコミットa7402beをチェックアウトするように指示します foo

それからクローンを作る前に誰かがrepository bar への変更をコミットしたと想像してください。

Repository foo からcommit a7402beをチェックアウトすると、私がプッシュしたのと同じコードが表示されるはずです。そのため、サブモジュールが明示的に指示してから新しいコミットを行うまでサブモジュールは更新されません。

個人的には、サブモジュールはGitの最も分かりにくい部分だと思います。サブモジュールを説明できる場所は、私よりもたくさんあります。 Pro Git Scott Chacon作。

30
Neall

サブモジュールのブランチを切り替えるには(サブモジュールが既にリポジトリの一部としてあると仮定します)。

  • サブモジュールを含むリポジトリのルートへのcd
  • .gitmodulesを編集用に開きます
  • それぞれのサブモジュールについて、path = ...url = ...の下にbranch = your-branchという行を追加します。ファイル.gitmodulesを保存します。
  • その後、ディレクトリを変更せずに$ git submodule update --remoteを実行します

...これにより、変更された各サブモジュールについて、指定されたブランチの最新のコミットが取り込まれるはずです。

15
Engineer

.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-"
8
Pascal T.

他の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

そしてそれは上記の設定からコードを引き出します。

3
Love Sharma

サブモジュールのブランチを選択することの唯一の効果は、--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パラメータがない場合、--branchgit-clone(1)ドキュメントで説明されているように、暗黙的に振る舞います。したがって、 プライマリブランチのみを複製します

当然のことながら、git submodule updateコマンドによって実行されたクローン作成ステージの後、サブモジュール用に以前に設定した remote ブランチ用の最新のコミットを最終的にチェックしようとします。それはあなたの地元の浅いクローンの一部ではない、そしてそれゆえ失敗するでしょう

fatal:シングルリビジョンが必要

現在のOriginを見つけることができません/ NotThePrimaryBranch サブモジュールパス 'mySubmodule'にリビジョン

1
LuKePicci

gitサブモジュールadd -b Develop --name branch-name - https://branch.git

0
Passiondroid