git 如何找出哪个'master'或'main'分支存在于仓库中?

idfiyjo8  于 12个月前  发布在  Git
关注(0)|答案(6)|浏览(128)

我正在使用一个Bash脚本来维护Git仓库。有些仓库使用'master'作为主分支,而其他仓库使用'main'。我可以使用什么Git命令来返回这些仓库中存在的第一个分支?
P.S.我想检查repo的本地分支,因为总是会有一个本地'master''main'分支。

8ulbf1ek

8ulbf1ek1#

要找出两个 local 分支中的哪一个存在,可以使用git branch-l/--list选项:

git branch -l master main  # outputs 'master' or 'main', provided only one exists

字符串
Git还会用星号标记当前的分支,因此您可以添加--format来防止:

git branch -l main master --format '%(refname:short)'

g2ieeal7

g2ieeal72#

要了解其他Git仓库的HEAD是什么,请使用git ls-remote

$ git ls-remote --symref origin HEAD
ref: refs/heads/master  HEAD
670b81a890388c60b7032a4f5b879f2ece8c4558    HEAD

字符串
这是假设你的Git和远程的Git都不是太旧以至于它们不支持--symref(它必须在两端都支持)。请注意,这个命令可以直接使用URL在任何存储库之外运行,而不是像origin这样的远程名称。
要找出其他Git仓库中存在哪些分支名称,可以克隆它并检查生成的远程跟踪名称,或者使用git ls-remote。注意,您可以只指定refs/heads以将输出限制为仅显示分支名称,或者完全忽略它以获得所有内容(所有分支和标记名称以及它们选择公开的任何其他名称)。

nsc4cvqm

nsc4cvqm3#

我可以使用什么Git命令来返回存在的第一个分支?
git branch -r返回远程列表。
grep origin/ma将匹配mainmaster
如果需要更挑剔,请使用grep -E 'origin/(main|master)'
返回给数组的列表应该可以工作,但是要小心带有空格的名字,因为数组元素是由空格分隔的,整个东西可能会爆炸。

b=( $(git branch -r | grep origin/ma ) ) # all matches
git checkout "${b[0]##*/}"               # first hit

字符串
如果你想更小心一点,

for n in main master; do 
  b="$(git branch -r -l "origin/$n")"
  if [[ -n "$b" ]]; then
    git checkout "${b[0]##*/}"
    break # keep the first success
  fi 
done

vfh0ocws

vfh0ocws4#

好吧,“default分支”在本地没有任何意义;只有当你的repo是其他人的远程仓库,或者是其他人托管的远程仓库时,它才有意义。(另外,关于“当我从这个本地分支拉取时,我默认拉取什么分支,但是如果你知道这一点,你就不会问这个问题了。)

git fetch
git branch -r --list 'origin/HEAD' | grep '>'

字符串

2hh7jdfx

2hh7jdfx5#

我想要一个可以使用多个remote(origin fork或canonical upstream)和使用main或master的仓库的脚本。基于Paul Hodges的回答,我最终得到了:

#Update local/fork default to match remote. Can also delete current local branch using -D (to clean up a finished feature branch)
gum(){
  REMOTES=( $(git branch -r | grep -Eo "  (origin|upstream)/(master|main)") )
  RNAME=${REMOTES[-1]%%/*}    # Prefix of last one in the list (prefer fetching from upstream over origin)
  RBRANCH=${REMOTES[-1]##*/}  # Suffix of last matching remote
  LBRANCH="$(git rev-parse --abbrev-ref HEAD)"  # Name of current checked out branch

  if [[ "$LBRANCH" != "$RBRANCH" && "$1" != "-D" ]]; then
    echo "error current branch is '$LBRANCH' not $RBRANCH and -D not specified to delete current branch"
  elif [[ ! -z $(git status -s) ]]; then
    echo "error pending changes on local branch"
  else
    # Switch to local default, delete current if requested
    if [[ "$LBRANCH" != "$RBRANCH" && "$1" == "-D" ]]; then
      git checkout $RBRANCH
      git branch -D $LBRANCH
    fi
    # fetch all and prune, then update local default
    git fetch --all -p && git merge $RNAME/$RBRANCH && if [[ "$RNAME" != "origin" ]]; then
      git push ${REMOTES[0]%%/*} $RBRANCH # also update default branch on fork
    fi
  fi
}

字符串

agxfikkp

agxfikkp6#

我想检查一个repo的本地分支,因为总会有一个本地mastermain分支
把它作为预期用例环境的可靠描述,因为在一般情况下,它通常是不正确的,
我可以使用什么Git命令来返回存在的第一个分支?
一种简洁的方法是

if git cat-file -e refs/heads/master 2>&-; then echo master
elif git cat-file -e refs/heads/main 2>&-; then echo main
fi

字符串
但对于任何更复杂的东西,你可能希望每个参考,

{ git for-each-ref --format='%(refname)' refs/{heads,remotes/*}/master;
  git for-each-ref --format='%(refname)' refs/{heads,remotes/*}/main;
} | sed -E 's,(.*)/,\1 ,' | sort -usk1,1


这给出了本地分支和所有被跟踪的远程的答案,而没有任何foofaraw。
例如,在我的git repo中,它报告了refs/remotes/origin master,Git项目将两个分支名称保持同步。但正如其他人指出的那样,一些项目将master作为切换时的位置记录,正如你可能已经注意到的,我没有mastermain分支。我的make分支跟踪origin/next,这是我运行部署的分支,还有一些其他的分支用于小项目。
要做的只是地方分公司做的

{ git for-each-ref --format='%(refname:short)' refs/heads/master;
  git for-each-ref --format='%(refname:short)' refs/heads/main;
} | head -1


参见for-each-ref示例,它就是为此而构建的。

相关问题