Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git-子模块头在运行更新后是否总是分离?_Git_Git Submodules_Git Detached Head - Fatal编程技术网

Git-子模块头在运行更新后是否总是分离?

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 是得到子模块的浅主分支。但发生的情况是,它没有签出到主分支。它总是会到达分离的头部,

我在.gitmodules文件中对子模块进行了以下配置:

[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子模块更新
始终为子模块创建分离的头部。当您想在子模块作为子模块时在子模块中进行开发(而不是在其他地方检查它们)时,这是非常烦人的。您必须记住,在执行工作之前,首先要做一个签出分支名称,并且在提交之后还要返回到父项目以添加更改。我现在也在寻找答案,以更方便的方式实现自动化。