1. ホーム
  2. ギット

[解決済み] [Solved] Git Submodule HEADがmasterから切り離されるのはなぜですか?

2022-04-11 19:37:42

質問

Gitのサブモジュールを使っています。サーバーから変更を取り込んだ後、何度もサブモジュールのヘッドが master ブランチから切り離されてしまいます。

なぜこのようなことが起こるのでしょうか?

いつもやらなければならないことがある。

git branch
git checkout master

サブモジュールが常に master ブランチを指すようにするにはどうしたらいいですか?

解決方法は?

EDITです。

参照 シンバ 回答 有効な解決策

submodule.<name>.update を変更したい場合は ドキュメント - デフォルト checkout

submodule.<name>.branch 追跡するリモートブランチを指定します。 デフォルト master


OLD ANSWERです。

個人的には、時間が経つと機能しなくなる可能性のある外部リンクに誘導するここの回答は嫌いなので、私の回答をチェックしてみてください。 こちら (質問が重複している場合を除く) - 他の主題の行の間の主題をカバーしているが、全体的に等しい質問に対する指示: "私は答えていない、ドキュメントを読んでください。

では、質問に戻ります。なぜ、このようなことが起こるのでしょうか?

状況説明

サーバーから変更を取り込んだ後、私のサブモジュールのヘッドが何度も master ブランチから切り離されます。

を使用しない場合、よくあるケースです。 サブモジュール をあまり頻繁に使用しないか、または使用し始めたばかりである。 サブモジュール . 私は、次のように述べていることは正しいと思います。 私たちは このような場合 サブモジュール のHEADが切り離される。

  • 原因 サブモジュールが正しいブランチをトラッキングしていない (デフォルトでは master)。

    解決方法 サブモジュールが正しいブランチを追跡しているか確認してください。
$ cd <submodule-path>
# if the master branch already exists locally:
# (From git docs - branch)
# -u <upstream>
# --set-upstream-to=<upstream>
#    Set up <branchname>'s tracking information so <upstream>
#    is considered <branchname>'s upstream branch.
#    If no <branchname> is specified, then it defaults to the current branch.
$ git branch -u <origin>/<branch> <branch>
# else:
$ git checkout -b <branch> --track <origin>/<branch>

  • 原因 親レポがサブモジュールのブランチを追跡するように設定されていません。

    解決方法 以下の2つのコマンドで新しいサブモジュールを追加することで、サブモジュールがリモートブランチを追跡するようにします。
    • まず、git にリモートを追跡するよう指示します。 <branch> .
    • チェックアウトの代わりにリベースやマージを行うようにgitに指示した場合
    • リモートからサブモジュールを更新するようにgitに指示する。
    $ git submodule add -b <branch> <repository> [<submodule-path>]
    $ git config -f .gitmodules submodule.<submodule-path>.update rebase
    $ git submodule update --remote

  • 既存のサブモジュールをこのように追加していない場合は、簡単に修正することができます。
    • まず、あなたのサブモジュールが追跡したいブランチをチェックアウトしていることを確認します。
    $ cd <submodule-path>
    $ git checkout <branch>
    $ cd <parent-repo-path>
    # <submodule-path> is here path releative to parent repo root
    # without starting path separator
    $ git config -f .gitmodules submodule.<submodule-path>.branch <branch>
    $ git config -f .gitmodules submodule.<submodule-path>.update <rebase|merge>

一般的なケースでは、DETACHED HEADは上記の設定問題のいずれかに関連しているため、すでに修正されているはずです。

の場合、DETACHED HEADを修正する。 .update = checkout

$ cd <submodule-path> # and make modification to your submodule
$ git add .
$ git commit -m"Your modification" # Let's say you forgot to push it to remote.
$ cd <parent-repo-path>
$ git status # you will get
Your branch is up-to-date with '<origin>/<branch>'.
Changes not staged for commit:
    modified:   path/to/submodule (new commits)
# As normally you would commit new commit hash to your parent repo
$ git add -A
$ git commit -m"Updated submodule"
$ git push <origin> <branch>.
$ git status
Your branch is up-to-date with '<origin>/<branch>'.
nothing to commit, working directory clean
# If you now update your submodule
$ git submodule update --remote
Submodule path 'path/to/submodule': checked out 'commit-hash'
$ git status # will show again that (submodule has new commits)
$ cd <submodule-path>
$ git status
HEAD detached at <hash>
# as you see you are DETACHED and you are lucky if you found out now
# since at this point you just asked git to update your submodule
# from remote master which is 1 commit behind your local branch
# since you did not push you submodule chage commit to remote. 
# Here you can fix it simply by. (in submodules path)
$ git checkout <branch>
$ git push <origin>/<branch>
# which will fix the states for both submodule and parent since 
# you told already parent repo which is the submodules commit hash 
# to track so you don't see it anymore as untracked.

しかし、ローカルでサブモジュールを変更し、それをコミットしてリモートにプッシュした場合、'git checkout ' を実行すると Git はそのことを通知します。

$ git checkout <branch>
Warning: you are leaving 1 commit behind, not connected to any of your branches:
If you want to keep it by creating a new branch, this may be a good time to do so with:

推奨されている一時的なブランチを作成するオプションは良いもので、その後、これらのブランチをマージすればよいのです。しかし、私個人としては、単に git cherry-pick <hash> この場合

$ git cherry-pick <hash> # hash which git showed you related to DETACHED HEAD
# if you get 'error: could not apply...' run mergetool and fix conflicts
$ git mergetool
$ git status # since your modifications are staged just remove untracked junk files
$ rm -rf <untracked junk file(s)>
$ git commit # without arguments
# which should open for you commit message from DETACHED HEAD
# just save it or modify the message.
$ git push <origin> <branch>
$ cd <parent-repo-path>
$ git add -A # or just the unstaged submodule
$ git commit -m"Updated <submodule>"
$ git push <origin> <branch>

サブモジュールを DETACHED HEAD 状態にできるケースは他にもありますが、特定のケースをデバッグする方法を少し理解していただけたと思います。