git如何更改分支名称(branch会打印本地所有分支名)(1)

使用 git branch 查看分支,会打印仓库下的所有分支名,通过 '*' 星号来标识当前分支。

如果想打印且打印当前本地分支名,可以用 git symbolic-ref --short HEAD 命令。

$ git branch * curent_branch_xxx enable_func $ git symbolic-ref --short HEAD curent_branch_xxx

也可以使用 git rev-parse --abbrev-ref HEAD 命令来打印且只打印当前分支名。

$ git rev-parse --abbrev-ref HEAD curent_branch_xxx

这两个命令可用在shell脚本中获取当前分支名,做一些自动化处理。

git symbolic-ref --short HEAD

使用 man git-symbolic-ref 查看该命令的帮助信息,说明如下:

git symbolic-ref: Read, modify and delete symbolic refs

git symbolic-ref [-m <reason>] <name> <ref>

git symbolic-ref [-q] [--short] <name>

Given one argument, reads which branch head the given symbolic ref refers to and outputs its path, relative to the .git/ directory. Typically you would give HEAD as the <name> argument to see which branch your working tree is on.

--short

When showing the value of as a symbolic ref, try to shorten the value, e.g. from refs/heads/master to master.

即,git symbolic-ref 命令可以查看 symbolic ref 的信息。而 HEAD 就是一个 symbolic ref 的名称,可用于查看当前工作分支。

使用 man git 可以查看到 git refs、HEAD 的一些说明:

Named pointers called refs mark interesting points in history. A ref may contain the SHA-1 name of an object or the name of another ref. refs with names beginning ref/head/ contain the SHA-1 name of the most recent commit (or "head") of a branch under development. SHA-1 names of tags of interest are stored under ref/tags/. A special ref named HEAD contains the name of the currently checked-out branch.

查看 github 网站上的开发者文档 (https://developer.github.com/v3/git/refs/),有如下说明:

A Git reference (git ref) is just a file that contains a Git commit SHA-1 hash. When referring to a Git commit, you can use the Git reference, which is an easy-to-remember name, rather than the hash. The Git reference can be rewritten to point to a new commit. A branch is just a Git reference that stores the new Git commit hash.

即,git ref 保存了git commit hash值,git ref 本身有一个名称,被用作分支名。一个分支其实就是一个 git ref。不同分支的差异是分支head指向的 git commit hash 不同。

HEAD 是一个指向当前工作分支的 git ref,切换工作分支,会改变 HEAD 的指向。这个文件在git仓库中的路径是 ".git/HEAD",可以用cat命令查看它的内容,下面的 HEAD 指向 master分支:

$ cat .git/HEAD ref: refs/heads/master

各个 git ref 存在 ".git/refs/" 目录下,本地分支head存在 ".git/refs/heads/" 目录下:

$ ls .git/refs/heads great master

可以看到,git branch 的分支名跟 ".git/refs/heads/" 目录下的文件名相同:

$ git branch great * master

结合这几个说明,对 git symbolic-ref --short HEAD 命令分解说明如下:

  • git symbolic-ref 命令可以解析获取 git ref 的信息
  • --short 表示获取 symbolic ref 的名称
  • HEAD 是指向当前工作分支的 git ref,解析HEAD文件信息,就能获取当前分支名
git rev-parse --abbrev-ref HEAD

git rev-parse --abbrev-ref HEAD 命令也能获取当前分支名。查看 man git-rev-parse 的说明如下:

git rev-parse: Pick out and massage parameters

git rev-parse [ --option ] <args>...

--abbrev-ref[=(strict|loose)]

A non-ambiguous short name of the objects name.

在man手册里面没有具体说明这个命令的表现是什么。在git的在线参考链接上找到一些描述: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection

If you want to see which specific SHA-1 a branch points to, or if you want to see what any of these examples boils down to in terms of SHA-1s, you can use a Git plumbing tool called rev-parse; basically, rev-parse exists for lower-level operations and isn’t designed to be used in day-to-day operations.

大致理解,git rev-parse 是一种git管道(plumbing)工具,可用于处理SHA-1 hash值。

我们在上面看到,git rev-parse --abbrev-ref HEAD 打印当前分支名,--abbrev-ref 表示输出所给对象不会混淆的短名,类似于 git symbolic-ref 的 --short 选项的输出结果。

不加 --abbrev-ref 时,会打印出HEAD对应的hash值:

$ git rev-parse HEAD 8ebf0117f9545187d3368adc1ce629608214984a

这两个命令都可以打印当前分支名,如果当前处于未命名分支下面时,它们的行为会有一些差异。下面用 git branch 命令查看,可以看到当前处在分离的HEAD状态下,当前分支没有命名:

$ git branch * (detached from 65c6917) great master

在这种情况下,HEAD不是符号引用,git symbolic-ref 会以错误退出:

$ git symbolic-ref --short HEAD fatal: ref HEAD is not a symbolic ref

而 git rev-parse –abbrev-ref 将HEAD解析为自身:

$ git rev-parse --abbrev-ref HEAD HEAD

,