目次
git submodule
git submodule update --init --recursive
since 2023-03-02
(以下は ChatGPT の回答)
"git submodule update –init –recursive"は、Gitでリポジトリ内のすべてのサブモジュールを、親リポジトリの参照に従って最新のコミットに更新するために使用されるコマンドです。
各オプションの説明は以下の通りです。
"git submodule update"は、親リポジトリに参照されているコミットに、リポジトリ内のサブモジュールを更新します。
"–init"は、まだ初期化されていないリポジトリに追加された新しいサブモジュールを初期化します。
"–recursive"は、サブモジュール内のサブモジュールを再帰的に初期化および更新します。
したがって、「git submodule update –init –recursive」を実行すると、Gitはすべてのサブモジュールが初期化され、親リポジトリの参照に従って最新のコミットに更新されることを保証します。これは、複数のサブモジュールが含まれる大規模または複雑なプロジェクトを扱う場合に特に便利です。
The command "git submodule update –init –recursive" is used in Git to update all submodules in a repository to their latest commit according to the main repository's references.
Here's what each option does:
"git submodule update" updates the submodules in the repository to the commit referenced in the parent repository.
"–init" initializes any new submodules added to the repository but not yet initialized.
"–recursive" initializes and updates any submodules in the submodules recursively.
So, when you run "git submodule update –init –recursive", Git will ensure that all submodules are initialized and updated to their latest commit, as referenced by the parent repository. This is particularly useful when working with large or complex projects that may contain multiple submodules that need to be updated and synced with the main repository.
以下は過去の記事
http://git-scm.com/book/en/Git-Tools-Submodules
http://qiita.com/items/0d525e568a6088f6f6bb
git subtree というのもある:
http://tech.a-listers.jp/2013/05/17/alternatives-to-git-submodule-git-subtree/
http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
使ってみる
since 2013-06-05
新しいレポジトリを作って、サブディレクトリはすでにある別のレポジトリの中身を使う:
$ mkdir gitsubtest $ cd gitsubtest/ $ git init Initialized empty Git repository in /Users/nishimotz/work/gitsubtest/.git/ $ echo "hello" > readme.md $ git add readme.md $ git commit -m "initial" [master (root-commit) b628967] initial 1 file changed, 1 insertion(+) create mode 100644 readme.md
ここでは somewhare.org の x2013www プロジェクトをサブディレクトリ www として取り込む:
$ git submodule add git@somewhare.org:nishimotz/x2013www.git www Cloning into 'www'... remote: Counting objects: 223, done. remote: Compressing objects: 100% (181/181), done. remote: Total 223 (delta 37), reused 223 (delta 37) Receiving objects: 100% (223/223), 3.00 MiB | 932 KiB/s, done. Resolving deltas: 100% (37/37), done.
$ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: .gitmodules # new file: www # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # .DS_Store
$ git commit -m "add x2013www as a submodule www" [master 8ab54e1] add x2013www as a submodule www 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 www
$ git show commit 8ab54e13c2f21702c32ed1ef86f3af98bbbfe293 Author: Takuya Nishimoto <nishimotz@gmail.com> Date: Wed Jun 5 11:39:24 2013 +0900 add x2013www as a submodule www diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f0c8264 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "www"] + path = www + url = git@somewhare.org:nishimotz/x2013www.git diff --git a/www b/www new file mode 160000 index 0000000..6cb241c --- /dev/null +++ b/www @@ -0,0 +1 @@ +Subproject commit 6cb241c12bc911e53d1e17ace4eff508f12423e9
サブモジュールから .gitignore をコピーして親モジュールに追加する:
$ cp www/.gitignore . $ git add .gitignore $ git commit -am "gitignore" [master 0116bcc] gitignore 1 file changed, 2 insertions(+) create mode 100644 .gitignore
reflog するとサブモジュールディレクトリの外と中で別々の履歴が見える:
$ git reflog 0116bcc HEAD@{0}: commit: gitignore 8ab54e1 HEAD@{1}: commit: add x2013www as a submodule www b628967 HEAD@{2}: commit (initial): initial $ cd www/ $ git reflog 6cb241c HEAD@{0}: clone: from git@somewhare.org:nishimotz/x2013www.git
サブディレクトリの中に add する
http://stackoverflow.com/questions/9035895/how-do-i-add-a-submodule-to-a-sub-directory
コマンドそのものは .git がある場所でしか実行できない:
$ cd assets/ $ git submodule add git@somewhere.org:nishimotz/x2013www.git www You need to run this command from the toplevel of the working tree.
しかし add 先を深くすることができる:
$ cd .. $ git submodule add git@somewhere.org:nishimotz/x2013www.git assets/www Cloning into 'assets/www'... remote: Counting objects: 223, done. remote: Compressing objects: 100% (181/181), done. remote: Total 223 (delta 37), reused 223 (delta 37) Receiving objects: 100% (223/223), 3.00 MiB | 933 KiB/s, done. Resolving deltas: 100% (37/37), done.
clone する
親レポジトリが gitsubtest としてサーバに push されているとする。
これを git clone すると、サブモジュールは空のディレクトリになるが、下記の手順で中身を取り出せる:
$ git clone git@somewhare.org:nishimotz/gitsubtest.git $ cd gitsubtest $ git submodule init $ git submodule update
この状態でサブモジュールの中で git branch すると (no branch) と出てくる。 git checkout master などしておいたほうが、あとでコミットするときに安全かも知れない。
init して update するのと、下記は等価なのか、何か違うのか。。
$ git submodule update --init
サブモジュールの中にさらにサブモジュールがある場合の操作:
$ git submodule update --init --recursive
conflict 対策
親レポジトリで git pull origin master すると、サブモジュールのメタ情報 subdir が CONFLICT になることがある。
http://stackoverflow.com/questions/826715/how-do-i-manage-conflicts-with-git-submodules
サブモジュールのメタ情報をファイルに見立てて reset すればいいという話:
$ git reset HEAD subdir $ git commit -am "message"
サブモジュールの削除
親リポジトリの管理下に戻したいので削除する、というときは。
http://d.hatena.ne.jp/oppara/20101116/p1
- .gitmodulesファイルから該当する行を削除
- .git/configファイルから該当する行を削除
$ git rm --cached path/to/hoge
この状態でこうなる:
# deleted: path/to/hoge # 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: .gitmodules # # Untracked files: # path/to/hoge/
コミット:
$ git add .gitmodules $ git commit -m "message"
それから path/to/hoge を add し直す:
$ cd path/to/hoge $ rm -rf .git $ rm .gitignore $ git add . $ cd ../../.. $ git commit -m "message"
リモートで更新されたサブモジュールが更新されない
サブモジュールを git pull origin master してから親モジュールで git submodule update
msysgit だと git submodule foreach がうまく動かない。
サブモジュールの中で fetch & merge する
since 2013-12-24
サブモジュールの origin
公開レポジトリ https://bitbucket.org/nvdajp/nvdajpmiscdep
を更新したので、親レポジトリからの参照を更新したい:
親レポジトリからは miscDepsJp という名前で git submodule add されている。
> cd miscDepsJp > git fetch origin master > git merge FETCH_HEAD
git status / git branch する:
> git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # nothing to commit, working directory clean >git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/master
なぜか ahead になっているが。。
submodule が使われたレポジトリを clone すると、サブモジュールは名前のないブランチになるが、自分で add したサブモジュールは master ブランチになる、のだろうか。。
親レポジトリに戻って、参照をコミットする:
> cd .. > git status # On branch jpbranch # 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: miscDepsJp (new commits) #
サブモジュールの中が完全に clean であること。 さもなくば、git diff したときに、ハッシュ値の後ろに -dirty が付いてしまう。