Git-子模块头在运行更新后是否总是分离?
我在.gitmodules文件中对子模块进行了以下配置:Git-子模块头在运行更新后是否总是分离?,git,git-submodules,git-detached-head,Git,Git Submodules,Git Detached Head,我在.gitmodules文件中对子模块进行了以下配置: [submodule "sub"] shallow = true branch = master path = sub url = https://path/to/repo.git 现在我想知道,当有人克隆我的repo,然后运行以下命令时: git submodule init git submodule update 是得到子模块的浅主分支。但发生的情况是,它没有签出到主分支。它总是会到达分离的头部,
[submodule "sub"]
shallow = true
branch = master
path = sub
url = https://path/to/repo.git
现在我想知道,当有人克隆我的repo,然后运行以下命令时:
git submodule init
git submodule update
是得到子模块的浅主分支。但发生的情况是,它没有签出到主分支。它总是会到达分离的头部,所以我需要手动运行git checkout master
。因此,用户需要运行另外一个命令,而不仅仅是这两个命令
我调查了一下:
但任何关于已接受答案的建议似乎都没有帮助:我在.gitmodules
文件中添加了我想要的分支,我添加了remote upstream作为master(这只适用于我自己必须签出才能掌握的已克隆/更新的存储库)
那么,如果有人克隆我的存储库并想要设置子模块,这是否意味着要始终分离头部?我仍在研究这一点,但下面是我提出并正在使用的脚本:
#! /bin/bash
# Written by Carlo Wood 2016
echo "In \"$(pwd)\", entering $0 $*"
# This script should be run from the root of the parent project.
if ! test -e .git; then
echo "$0: $(pwd) is not a git repository."
exit 1
fi
# Parse command line parameters.
opt_init=
opt_recursive=
do_foreach=0
initial_call=1
while [[ $# -gt 0 ]]
do
case $1 in
--init)
opt_init=$1
;;
--recursive)
opt_recursive=$1
do_foreach=1
;;
--reentry)
initial_call=0
;;
--)
break;
;;
-*)
echo "Unknown option $1"
exit 1
;;
*)
break
;;
esac
shift
done
# Determine the full path to this script.
if [[ ${0:0:1} = / ]]; then
FULL_PATH="$0"
else
FULL_PATH="$(realpath $0)"
fi
if test "$initial_call" -eq 1; then
do_foreach=1
else
# Script is called from git submodule foreach ...'
name="$1"
path="$2"
sha1="$3"
toplevel="$4"
# Make sure we are in the right directory.
cd "$toplevel/$path" || exit 1
# Does the parent project want us to checkout a branch for this module?
SUBMODULE_BRANCH=$(git config -f "$toplevel/.gitmodules" submodule.$name.branch)
if test -n "$SUBMODULE_BRANCH"; then
echo "Calling 'git checkout $SUBMODULE_BRANCH' in $(pwd)"
git checkout $SUBMODULE_BRANCH || exit 1
echo "Calling 'git pull' in $(pwd)"
git pull || exit 1
if test $(git rev-parse HEAD) != "$sha1"; then
# Update the parent project to point to the head of this branch.
pushd "$toplevel" >/dev/null
SN1=$(git stash list | grep '^stash' | wc --lines)
git stash save --quiet Automatic stash of parent project by update_submodules.sh
SN2=$(git stash list | grep '^stash' | wc --lines)
git add $name
git commit -m "Update of submodule $name to current $SUBMODULE_BRANCH"
if test $SN1 -ne $SN2; then
git stash pop --quiet
fi
popd >/dev/null
fi
elif test $(git rev-parse HEAD) != "$sha1"; then
# No submodule.$name.branch for this submodule. Just checkout the detached HEAD.
git checkout $sha1
fi
fi
echo "do_foreach=$do_foreach; opt_init=$opt_init; opt_recursive=$opt_recursive; name=$name; path=$path; sha1=$sha1; toplevel=$toplevel; pwd=$(pwd)"
if test $do_foreach -eq 1; then
if test -n "$opt_init"; then
echo "Calling 'git submodule init'"
git submodule init
fi
# Make sure the submodules even exist.
echo "Calling 'git submodule update'"
git submodule update
# Call this script recursively for all submodules.
echo 'Calling '"'"'git submodule foreach '"$FULL_PATH --reentery $opt_init $opt_recursive"' $name $path $sha1 $toplevel'"'"
git submodule foreach "$FULL_PATH --reentry $opt_init $opt_recursive"' $name $path $sha1 $toplevel'
fi
调用此脚本将执行与“git子模块更新”相同的操作,并且
甚至支持init和recursive。但是,您可以通过设置“branch”值将子模块配置为签出和拉入分支;例如:git config-f.gitmodules submodule.NAME.branch master
将导致子模块名称签出并拉入分支master,而不是当前的SHA1。然后它还将更新父项目以指向该分支的负责人。是的,你说得对。用户mkungla从中得出的首要答案是胡说八道
在.gitmodule
中添加分支
选项与子模块的分离行为完全无关
从git子模块--help
,头分离是git子模块更新--remote
的默认行为
首先,无需指定要跟踪的分支<代码>源代码/主代码
是要跟踪的默认分支
--遥远的
使用子模块远程跟踪分支的状态,而不是使用超级项目记录的SHA-1更新子模块。使用的遥控器是分支机构的遥控器(branch..remote
),默认为origin
。使用的远程分支默认为master
为什么?
那么为什么在更新后头部会分离呢?因为子模块$name.update的默认行为是签出
--结帐
在子模块中分离的头上签出超级项目中记录的提交。这是默认行为,此选项的主要用途是在设置为签出
以外的值时覆盖子模块。$name.update
怎么
如果希望子模块自动与远程分支合并,请使用--merge
或--rebase
--合并
此选项仅对更新命令有效。将超级项目中记录的提交合并到子模块的当前分支中。如果给出此选项,子模块的头部将不会分离
--重基
将当前分支重设为超级项目中记录的提交。如果给出此选项,子模块的头部将不会分离
你需要做的就是
git子模块更新--远程--合并
#或
git子模块更新--远程--重新基础
还有一个选项,通过设置submodule.$name.update
到merge
或rebase
,将-merge
或rebase
作为git子模块更新的默认行为
下面是一个关于如何在.gitmodule
中配置子模块update的默认更新行为的示例
[submodule "bash/plugins/dircolors-solarized"]
path = bash/plugins/dircolors-solarized
url = https://github.com/seebi/dircolors-solarized.git
update = merge # <-- this is what you need to add
[子模块“bash/plugins/dircolors solarized”]
path=bash/plugins/dircolors solarized
url=https://github.com/seebi/dircolors-solarized.git
更新=合并#是,git子模块更新
始终为子模块创建分离的头部。当您想在子模块作为子模块时在子模块中进行开发(而不是在其他地方检查它们)时,这是非常烦人的。您必须记住,在执行工作之前,首先要做一个签出分支名称,并且在提交之后还要返回到父项目以添加更改。我现在也在寻找答案,以更方便的方式实现自动化。