网站的tdk指的是什么意思,中国住房和城乡建设部网站建造师,织梦做的网站首页打不开,外包网主要介绍个人开发提交记录的主要流程#xff0c;包括以下内容#xff1a;
索引- 提交的暂存区。查看工作的状态和内部变更。如何读取用于描述变更的已扩展统一diff格式。支持查询和交互的提交#xff0c;修改提交。创建、显示和选择#xff08;切换#xff09;分支。切换…主要介绍个人开发提交记录的主要流程包括以下内容
索引- 提交的暂存区。查看工作的状态和内部变更。如何读取用于描述变更的已扩展统一diff格式。支持查询和交互的提交修改提交。创建、显示和选择切换分支。切换分支失败的原因以及应对策略。使用git reset对分支复位。与HEAD脱离的匿名分支例如签出的标签等。
1、新建提交
在使用Git开始一个新项目之前用户需要先添加自己的姓名和电子邮件信息。上述信息主要用于标记开发人员的工作记录无论作者还是提交者都是如此。该设置可以是适用于所有版本库的全局配置使用git config --global命令或者直接编辑/.gitconfig文件也可以是仅局限于用户本地版本库使用git cofig命令或者编辑.git/config文件。每个版本库的配置将会覆盖单个开发人员的配置。某些用户也许会希望在公司的版本库下工作时使用工作电子邮件在某些公共版本库中使用非工作电子邮件。
相应的配置文件信息与下列内容类似
[user]name Joe R. Hackeremail joecompany.com1.1、新建提交的DAG视图
为一个项目做贡献通常意味着为上述项目添加新的修订然后将它们作为提交节点添加到修订视图上。
接下来假定我们现在处于master分支如下图所示然后我们想为项目添加一个新的修订版本。git commit命令将会创建一个新的提交对象——一个新的修订节点。该提交会创建一个特定的签出修订版本本示例是c7cd3。该修订会被追踪引用的起点指针HEAD引用即当前图表中HEAD指向的节点c7cd3。 当前的分支是masterHEAD指针指向的修订版本是c7cd3该修订也是目前签出的修订。
Git系统会移动master指针到新的节点创建节点之后的情形如下图所示。在图中我们可以看到新的提交节点用加粗的红框标记了出来master分支旧的节点用半透明的形式表示。需要注意的是HEAD指针并没有改变它一直是指向master分支的新的提交a3b79是用加粗的红框标记的master分支上指针由提交c7cd3指向了提交a3b79代表分支发生了变更如下图中的虚线所示
1.2、索引——提交的暂存区
Git版本库对应的工作区中的每个文件对于Git系统来说包括两种即已知的跟踪文件和未知的。其中未知文件对于Git系统来说又分为未跟踪和已忽略两类。
Git系统跟踪的文件一般有两种状态已提交未变化和已修改。已提交状态意味着工作目录下的文件内容和最近一次提交的修订内容一致很安全地存放在版本库中。
如果文件和最新提交的修订版本存在差异则被认为是已修改的文件。
不过在Git系统内部还存在另外一种状态。接下来让我看看当使用git add命令添加一个文件后会发生什么。版本控制系统都需要在某处存放上述状态信息。Git系统采用被称为索引index的机制实现此功能它是存储将要提交信息的暂存区。git add 命令会暂存文件当前版本的当前内容然后将之添加到索引中。
如果用户只是喜欢将某个文件标记为已添加那么可以使用git add -N file命令这样一来上述文件在暂存区的内容就是空白的。
索引是项目的第三个存储拷贝之前的拷贝一个是包含用户自己项目文件拷贝的工作目录另外一个是用户本地版本库存放项目历史记录专门为用户同步其他开发人员的变更。
下图中的箭头表示了Git命令拷贝内容的主要步骤例如git add命令会将工作区的文件内容拷贝到暂存区。 创建一个新的提交需要执行如下步骤
1在工作目录下面使用编辑器对文件进行编辑。2使用git add命令对上述文件进行暂存为它们添加快照文件当前的状态。3使用git commit命令创建一个新的修订这会把存放在暂存区的文件信息作为修订版本永久地存放到本地版本库中。
在项目启动之初工作区的被跟踪文件、暂存区的文件和最近一次提交的修订版本在内容上都是一致的。
不过用户通常会采用提交记录命令的快捷方式即git commit –a是git commit --all的快捷方式该命令会把被跟踪并且发生变更的文件添加到暂存区中在当前的Git系统中和git add -u命令的效果一样然后创建一个新的提交如上图所示。需要注意的是新增的文件仍然需要使用git add命令告知Git系统对其进行跟踪然后才能将之添加到新的提交对象中。
1.3、查看已提交的变更
在提交变更和创建新的修订新的提交之前用户也许希望看看自己的工作成果。
除非用户在命令行中声明了提交注释信息例如git commit -m简短的描述信息否则Git会在提交信息模版中显示将要提交的记录并且该模版可以根据用户需要进行编辑配置。
用户还可以通过不修改文件或者使用一个空的提交信息终止提交操作注释信息中以#号开头的内容会被忽略。
1、工作目录状态
用户使用工具检查文件状态的目的在于查看哪个文件发生了变更、哪些地方新增了文件等这就是git status命令的主要用途。
上述命令默认输出结果的信息非常详尽。如果项目没有发生变更例如直接克隆版本库之后用户会看到类似以下内容的信息
$ git status
On branch master
nothing to commit, working directory clean如果上述分支本示例中当前用户处于master分支是一个本地分支打算添加一些变更之后发布到公共版本库中并且事先配置好了对应的上游分支origin/master那么用户还会看到对应的远程跟踪分支的相关信息
Your branch is up-to-date with origin/master.接下来的示例中我们将会忽略上述信息。
例如用户打算给项目新增两个文件一个是包含版权信息的文件名字叫COPYING另外一个是空白文件名字叫NEWS。为了跟踪刚才引入的COPYING文件需要执行git add COPYING命令。用户一不留神使用git rm README命令将README文件从工作区删除了然后编辑了Makefile文件用git mv命令把文件rand.c的名字改成random.c并没有修改其中的内容。 一般来说完整信息输出格式的好处是易读并且描述信息详尽
$ git status
On branch master
Changes to be committed:(use git reset HEAD file... to unstage)new file: COPYINGrenamed: src/rand.c - src/random.cChanges not staged for commit:(use git add file... to update what will be committed)(use git checkout -- file... to discard changes in working
directory)modified: Makefiledeleted: READMEUntracked files:(use git add file... to include in what will be committed)NEWS如你所见Git不仅记录和描述了哪些文件发生了变更而且还在提交中解释了文件的变更状态以及哪些将要提交的变更被删除了。上述结果大致可以分为3个部分
拟提交的变更这是已经放入暂存区准备使用git commit命令提交的变更没有-a选项。它是暂存区的文件快照和最近一次提交HEAD是有显著差异的。未暂存的变更这些列表是工作区中和暂存区的快照存在差异的文件列表。这些变更将不会使用git commit命令提交不过可以通过git commit -a命令将上述内容作为被跟踪文件的变更提交。未跟踪的文件这类文件对于Git系统来说是未知的而且也是可以被忽略的这类文件可以使用添加操作命令git add.在顶层目录中进行批量添加。用户还可以使用–untracked-filesno简写为-uno选项忽略该操作。
如果用户不希望充分利用暂存区提供的灵活性那么可以简单地使用git add命令只添加新文件然后使用git add -a命令获取所有被跟踪文件的变更继而创建提交。这种情况下用户创建的提交包含将要提交的变更以及不在暂存区的变更。
还有一种简洁的输出格式使用–short选项声明。–porcelain选项适合脚本执行因为在保证一致稳定性的同时使用–short选项还支持用户对输出结果的编辑。对于某些相同的变更输出结果和下列内容类似
$ git status –short
A COPYINGM MakefileD README
R src/rand.c - src/random.c
?? NEWS采用格式之后每个路径的状态会用双字母状态码表示。第一个字母表示索引的状态暂存区和最近一次提交的差异第二个字母表示工作区的状态工作区和暂存区的差异。
并不是所有的状态码组合都是存在的状态码A、R和C只可能出现在第一个列即表示索引的状态。一个特别的情况是??符号它主要用来表示未知未跟踪文件的!!符号表示已忽略文件当使用git status --short --ignored命令时。
2、最新修订的差异比较
如果用户不仅希望知道哪些文件发生了变更使用git status命令而且还想知道具体发生了哪些变更那么可以使用git diff命令。
Git系统中包含3个区域工作目录、暂存区和版本库通常是最近一次修订版本。因此我们不止有一组差异而是有3组如下图所示。
用户可以要求Git回答如下问题 用户编辑了哪些内容但是还未暂存的换句话说就是暂存区和工作区之间的差异是什么哪些内容是已暂存准备提交的也就是说最近一次提交HEAD和暂存区的差异是什么
用户希望了解自己编辑了哪些文件但是还未将其暂存那么可以使用不带任何参数的git diff命令。该命令会比较用户的工作目录和暂存区直接的差异。上述变更是可以被添加的但是如果使用git commit命令提交变更却不会被显示这些变更并未放入暂存区因此执行git status命令之后查询结果不会包含上述变更。
用户如果希望查看已经暂存的变更并且打算提交这些变更那么可以使用git diff --staged或者git diff –cached命令该命令会比较最近的一次提交和暂存区之间的差异。上述变更可以使用git commit命令不带-a选项进行添加同时也是执行git status命令后输出结果中将要提交的变更记录。还可以使用git diff --staged提交记录 命令比较暂存区和任意提交历史记录之间的差异HEAD最近的一次提交是默认的比较对象。
可以使用git diff HEAD命令比较用户当前的工作目录和最近一次提交的修订之间的差异可以使用git diff提交记录与任意历史修订记录比较差异。上述变更可以使用git commit -a命令快速地添加到版本库中。如果用户没有使用git commit –a命令而且也不需要充分利用暂存区那么通常使用git diff命令查看将要提交的变更记录就可以满足需要了。
如果只使用命令git add唯一需要处理的问题是新增文件除非用户使用git add --intent-to-add命令新增文件到版本库也可以使用git add -N否则使用git diff命令之后新增的文件将不会显示在查询结果中。
4、Git的统一diff格式
一般来说Git系统在大部分情况下都会采用统一的diff输出格式显示变更记录。
理解这种输出格式对于用户来说是非常重要的不仅在查看将要提交的变更记录时会用到而且在审核和检查变更记录时也会用到例如在代码审核审查中或者执行git bisect命令之后查找可疑提交记录。
用户可以使用–stat或者–dirstat选项只统计变更记录数量或者使用–name-only查看名字发生变更的文件数目或者使用–name-status选项查看文件名类型发生变更的记录或者使用–raw选项查看项目的目录结构发生的变化或者使用–summary选项查看扩展首部信息的摘要。用户还可以使用–word-diff选项进行字符之间的差异比较这比行间差异比较精确度更高这样一来即使文件内部的标题和段落标题相似但是只改变段落的格式也可以检测出其中的差异。Diff生成工具还可以通过设置特定的gitattributes信息实现特定文件或者某类文件的差异比较。用户甚至可以指定diff助手即描述变更的命令或者还可以为二进制文件指定文本转换过滤器。
如果用户喜欢使用图形化工具通常支持逐行比较查看上述变更记录那么可以使用git的difftool代替使用git diff命令。这可能需要预先做适当的配置。
接下来介绍一个使用diff命令查看git项目历史记录的高级示例。首先使用diff命令查看git.git版本库中的提交1088261f。当然用户也可以使用浏览器查看该提交例如通过GitHub。下列内容是该提交的第三条补丁记录
diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.cb/http-fetch.c-1,8 1,9 #include cache.h#include walker.h-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
int main(int argc, const char **argv){const char *prefix;struct walker *walker;int commits_on_stdin 0;int commits;-18,6 19,8 int cmd_http_fetch(int argc, const char **argv,int get_verbosely 0;int get_recover 0; prefix setup_git_directory();
git_config(git_default_config, NULL);while (arg argc argv[arg][0] -) {1.4、可查询的提交
有时在看过一些未提交的变更记录之后你也许会发现工作目录下面有两个或者更多无甚关联的变更分别属于不同的业务逻辑它是引起工作拷贝混淆的诱因。用户需要将这些不相关的变更分别放到对应的提交中即隔离变更集。这种做法也和软件开发的最佳实践不谋而合。一种做法是先创建提交然后再修复它将之一分为二。
不过有时候其中某些变更急需马上上线例如一个在线网站的bug修复同时其余变更还有待进一步完善。因此这时用户需要把上述变更分割成两个独立的提交。
1、文件提交查询
最简单的情形就是这些不相关的变更分布于若干文件中。例如说如果bug只存在于文件view/entry.tmpl中并且该文件不存在其他变更那么可以专门为该文件创建一个修复bug的提交相关命令如下
$ git commit view/entry.tmpl该命令会忽略已经暂存到索引中的变更即暂存区的内容取而代之的是提交当前给定文件或目录工作目录中的变更中的内容。
2、变更的交互式查询
不过有时变更无法以这种方式分类文件中的变更都集中到了一起。用户可以尝试git commit命令和–interactive选项一起使用对上述变更进行梳理
$ git commit --interactivestaged unstaged path1: unchanged 3/-2 Makefile2: unchanged 64/-1 src/rand.c*** Commands***1: status 2: update 3: revert 4: add untracked5: patch 6: diff 7: quit 8: help
What now这里Git系统为用户显示了工作区的状态和变更摘要信息以及暂存区/索引暂存的-状态子命令的输出结果。描述变更的方式是添加和删除文件的数量和git diff --numstat输出结果类似
What now h
status - show paths with changes
update - add working tree state to the staged set of changes
revert - revert staged set of changes back to the HEAD version
patch - pick hunks and update selectively
diff - view diff between HEAD and index
add untracked - add contents of untracked files to the staged set of
changes
*** Commands ***1: status 2: update 3: revert 4: add untracked5: patch 6: diff 7: quit 8: help为了对这些变更进行梳理分类用户需要用到patch子命令例如使用5或者s。之后Git系统会弹出一个Update对话框让用户选择如何处理这些文件然后用户需要根据上面的状态信息输入希望更新的文件对应的数字标记然后按下回车键即可。用户还可以输入*选择所有文件。确认输入完毕目标文件的信息之后可以按下回车键输入一个空行告诉系统选择结束了用户还可以使用–patch选项直接忽略批量文件的选择。Git系统将会为用户逐个显示特定文件的变更区域然后让用户选择分类下面的选项是专门操作单个变更区域的
y - stage this hunk暂存该区域
n - do not stage this hunk不暂存该区域
q - quit; do not stage this hunk or any of the remaining ones退出不暂存任何区域s - split the current hunk into smaller hunks分隔该区域为更小的区域
e - manually edit the current hunk手工编辑当前区域
? - print help 打印帮助区域的输出结果和对话提示和下列内容类似 -16,7 15,6 int main(int argc, char *argv[])int max atoi(argv[1]);srand(time(NULL));int result random_int(max);printf(%d\n, result);Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? y一般来说上述选项可以应付大部分在提交内部进行区域选择的操作。不过在一些极端情况下用户可以将上述区域分割成更小的区域甚至手工编辑其中的差异。
3、提交创建入门
使用git commit --interactive进行交互式提交记录查询有一个缺点那就是它无法对将要提交的变更进行测试。当然用户也可以在创建一个提交之后随时对其进行检查编译或者运行测试发现bug之后及时修复它。不过这只是一种替代性的解决方案。用户可以使用git add --interactive命令将准备提交的变更放在暂存区中或者采用类似的解决方案使用Git的图形化提交工具例如 git gui。交互式的提交只是交互式添加变更然后提交的一种快捷方式。之后用户还可以使用git diff --cached命令查看这些提交以及使用git add 、git checkout 和git reset 命令对这些提交做相应的修改。
理论上来说不管这些变更正确与否用户都可以对它们进行测试至少可以确认它们是否可以通过程序编译。为此首先要使用git stash save --keep-index命令保存当前的状态然后将工作目录的状态存放到暂存区中索引。执行该命令之后用户就可以执行测试程序了至少确认一下程序是否能够通过编译。如果测试通过那么用户就可以执行git commit命令创建一个新的修订版本如果测试不通过用户就可以使用git stash pop --index命令从暂存区读取工作目录的状态将之恢复到之前的状态也有可能会需要用到git reset --hard命令对工作区进行重置。后者可能是非常有必要的因为Git在保存用户的工作记录时过于保守而且并不知道用户只是将某些记录隐藏暂存了。首先索引中未提交的变更不能阻止Git用其他变更将其覆盖。其次工作区的变更和暂存区的变更大体相同因此当然会发生冲突。
1.5、 修改提交
Git系统非常明显的一个优点是用户可以随心所欲地恢复其中的任何东西。无论用户如何认真地编辑准备提交的变更记录或多或少都会出现一些问题例如忘记添加某个变更或者提交的信息有错别字等。这就是git commit命令的–amend选项大显身手的时候了它能够帮助用户方便地修改最近的提交记录如下图所示。注意用户还可以使用该选项修改合并提交例如修复一个合并错误。 修订的DAG图C1到C2的变更代表对最近一次提交修改之前的状态C5代表当前签出的提交。这里我们使用数字代替SHA-1码表示相关的提交记录。
如果用户希望对提交的历史记录做进一步的修改假定该提交未发布至少没有人在该提交的基础上提交新的修订那么可能会用到交互式变基操作或者是某些特殊的工具例如StGit一个基于Git的提交历史批量管理工具。
如果用户只是想修正提交备注信息中的错误那么只需要再添加一条备注信息即可不需要将它暂存注意我们使用git commit命令时并没有使用-a / --all选项
$ git commit --amend如果用户希望为最近一次的提交添加一些变更记录见下图那么可以先使用git add命令将这些变更暂存然后像前面的示例一样再次提交该修订记录或者使用git commit -a --amend命令提交这些变更 经过编辑的最近一次修订记录上上图的DAG图这里新的C5修订是基于添加了更多变更记录之后的C5它替换了旧版本的提交对象。
这里有一个非常重要的忠告你永远不要修改一个已经发布了的修订这是因为修改操作会创建一个新的提交对象替换原有的对象如上图所示。如果开发工作只有一个人的话那么这么做不会出什么问题。不过如果是多人协作开发当你把原有的修订记录发布到远程版本库中后团队其他人员可能已经基于该修订版本做了一些开发工作了。使用经过修订的版本替换原有的版本之后可能会导致下游出现问题。
如果你尝试将一个已经发布过的提交修订然后将之推送发布到某个分支上Git将会阻止用户重写已发布的历史提交记录然后询问用户是否真的希望替换旧的版本进行强制推送除非用户配置了默认强制推送选项。修订的历史版本在被编辑之前在分支的引用日志和HEAD引用日志中仍然是有效的例如刚经过修订后不久它仍然可以通过{1}的形式访问。一般来说除非手动清除Git将会保存旧版本修订一个月。
2、使用分支
分支是一系列开发工作的符号名称。在Git中每个分支都可以看作修订DAG中指向某些提交的具名指针因此它也被称为分支首部。
分支在Git中的表现形式目前Git在硬盘中采用了两种截然不同的方式来表示分支松散格式和压缩格式。例如master分支该分支是Git采用的默认分支名用户在创建新的版本库时默认的分支名就是它。采用松散格式时它是.git/refs/heads/master中的一行文本其中指代分支的内容是十六进制的SHA-1码。在压缩格式中它是.git/packed-refs中的一行文本使用最顶部修订的SHA-1码和分支全名一起表示该分支。
一系列的开发工作就是指从分支首部为起点所有可达的修订集合。而且它并不一定是线性的修订还可以是分支分流或者联合。
2.1、新建分支
用户可以使用git branch命令创建一个新分支例如在当前分支上新建一个名为testing的分支参见下图右上部分可以执行如下命令
$ git branch testing新建一个testing分支然后切换到该分支或者新建一个分支并且马上切换到该分支上使用命令。
执行上述命令之后会发生什么呢 该命令会为用户创建一个可供访问的新指针一个新引用。如果用户希望在创建新分支的同时将它指向某些修订提交那么可以使用相应的参数。
不过需要注意的是git branch命令并不会改变HEAD指针的位置指向当前分支的符号引用并且不会改变工作目录中的内容。
如果用户希望创建一个新分支并切换到该分支上可以马上在新建分支上工作那么可以使用如下快捷方式
$ git checkout -b testing如果我们在当前的版本库中创建分支checkout -b命令的差异仅在于它还会将HEAD指针移动到新建的分支上如上图所示。
2.2、孤儿分支
有时用户也许希望在版本库中新建一个和主分支没什么关联的孤儿分支。例如为每个预览版程序单独存放对应的用户手册使得用户不需要安装转换工具或者解析器例如AsciiDoc解析器就可以方便地阅读用户手册例如HTML格式的帮助页面。又或者用户希望在版本库中的每个项目存放一些Web页面这和GitHub网站项目中Web页面的用途类似。有些用户希望开源自己的项目代码但是首先要把代码清理一番例如修改版权和授权许可文件。
一种办法是为包含上述内容的孤儿分支建立一个独立的版本库然后从远程跟踪分支上获取它们然后用户可以基于该孤儿分支创建一个本地分支。
用户还可以执行如下命令达到上述目的
$ git checkout --orphan gh-pages
Switched to a new branch gh-pages上述命令会重新生成某些状态在执行完git init:操作之后将HEAD指针指向gh-pages分支如果该分支不存在的话会先创建该分支然后执行上述操作。而且该分支的创建是基于第一个提交对象的。
如果用户希望使用类似GitHub页面这种简洁的目录结构启动项目那么还需要将起点分支的内容移除HEAD指向默认分支即当前分支和当前工作目录的状态。例如使用如下命令
$ git rm -rf .对于开源目代码中需要排除的私人信息用户需要在工作目录中认真编辑进行相应的替换。
2.3、分支的查询和切换
为了切换到一个已有的本地分支上用户需要执行git checkout命令。例如在创建testing分支之后可以使用如下命令切换到该分支上
$ git checkout testing1、分支切换释疑
在切换分支时Git也会将签出的内容放入工作目录中。那么如果有未提交的变更又会发生什么呢先不考虑Git将会切换到哪个分支上
切换分支时让当前分支保持整洁的状态是一个好习惯。如果有必要的话在切换前清空暂存区或者创建一个提交。在极个别情况下将未提交的变更一并执行分支切换操作是很有用的。
如果当前分支对应的文件变更和将要切换的目标分支没有关联那么当前分支未提交的变更也会一并移动到新分支中。这对于用户开始着手研究新的东西时非常有用。随着时间的推移用户正好可以将这一系列的工作放到独立的特性分支中。如果未提交的变更和给定分支有冲突那么Git将会拒绝切换到目标分支从而防止用户的工作成果遭到破坏
$ git checkout other-branch
error: Your local changes to the following files would be overwritten by
checkout:file-with-local-changes
Please, commit your changes or stash them before you can switch branches.在这种情况下有以下几个解决方案可供选择
用户可以隐藏自己的变更当切换到原来的分支时再恢复它们通常这是比较推荐的做法。或者可以简单地为这些正在进行中的工作创建一个临时提交然后在切换到原来分支时可以对该提交进行修改或回退。用户还可以尝试通过合并操作将自己现有的变更记录移动到新分支中可以使用git branch --merge命令该操作会执行三路合并其中包括当前分支、工作区中未保存的变更和目标分支还可以在签出之前隐藏用户的变更记录然后在切换分支之后将隐藏的变更记录恢复到暂存区中。用户还可以使用git checkout --force命令丢弃原有的变更。
2、匿名分支
如果用户尝试签出一个非本地分支会如何呢例如任意的修订像HEAD^或者一个标签像v0.9或者一个远程跟踪分支像origin/master。在这种情况下Git会假定用户需要在当前工作目录状态的基础上创建一个提交。
旧版本的Git程序会拒绝执行没有目标分支的切换操作。不过现在的Git程序会通过与HEAD指针分离创建一个匿名分支即直接指向一个提交对象而不是使用一个引用符号指向一个分支如下图所示。为了在当前位置显式创建一个匿名分支用户可以在执行checkout命令时使用–detach选项。被分离的HEAD引用会在分支列表中被当作Git的一个历史修订版本存在又或者是作为较新的版本修订从HEAD脱离或者HEAD在某处脱离。 无分支的签出结果Git中签出HEAD操作之后的状态HEAD被分离了或者称之为匿名分支。
如果用户因为失误而将HEAD和分支脱离了那么还可以将之恢复到脱离之前的状态这里的-代表上一分支
$ git checkout -因为当用户在创建一个匿名分支时Git会给用户一些警示信息因此用户还可以使用git checkout -b new-name命令为该分支命名。
3、Git的智能签出
还有一种非常特殊的情况属于签出时的内容不是分支的。如果你使用分支的简称本示例是next签出了一个远程跟踪分支例如origin/next但是如果当前状态下有一个同名的本地分支的话Git会认为用户希望在远程跟踪分支的基础上添加一些新的内容可以完成用户的预期目标。“做我所想”DWIM机制将会创建一个新的本地分支以便跟踪远程跟踪分支。
相关命令如下
$ git checkout next它等效于如下命令
$ git checkout -b next --track origin/next只有在不会产生歧义的情况下Git才会执行上述操作本地分支必须不存在否则该命令会简单地切换到目标分支而且必须只有一个远程跟踪分支与之对应。这种情况可是使用git show-ref next使用分支简称命令检查远程跟踪分支是否只有唯一符合条件的记录最近的一条记录可以使用refs/remotes/前缀和引用名进行识别。
2.4、分支列表
如果用户在执行git branch命令时不带任何选项参数的话那么它会显示所有的分支并使用*标记当前分支。
该命令是专门为最终用户设计的它的输出结果在未来的Git程序中可能会发生变化。在shell脚本中可以通过编写代码实现如下功能
可以使用git symbolic- ref HEAD命令获取当前分支的名称。可以使用git rev-parse HEAD命令找到当前提交的SHA-1码。可以使用git show-ref或者git for- each-ref命令显示所有分支。
上述命令都是管道化的因此可以将它们应用到脚本中。
用户可以使用-v (–verbose)或者-vv选项查询更多信息还可以对分支进行条件查询例如可以在给定的shell程序中使用git branch --list模式命令进行模式匹配查询如果有必要的话可以使用引号将模式包裹起来防止它被shell解析。
用户可以使用git remote show命令查询远程版本库的信息当然其中也包括远程分支的查询。
2.5、分支的回退和复位
如果用户想丢弃最近一次提交的修订记录或者回退重置当前的分支到上一分支他该怎么做为此用户需要使用reset命令。它可以改变当前分支指针的指向。不过需要注意的是和checkout命令不同reset命令在默认情况下不会改变工作目录的内容用户需要使用相应的命令参数才行例如git reset --keep命令尝试保留未提交的变更或者git reset --hard强行删除未提交的变更。
下图展示了在指定分支和无分支参数的情况下checkout命令和reset命令之间的差异。总之reset命令会改变当前分支指针的指向移动引用而chekout命令既可以进行分支切换又可以在没有无分支的情况下在给定的修订中和HEAD分离。
在指定分支例如maint和无分支例如HEAD^参数的情况下checkout命令和reset 命令之间的差异对照。
2.6、分支的删除
在Git中一个分支其实就是一个指针它在修订的DAG图上就是一个指向节点的外部引用因此删除一个分支实际上就是删除一个指针。
实际上当删除一个分支时同时也永久性地至少对于当前版本的Git是如此移除了和该分支对应的引用日志即它的本地历史日志。
用户可以使用git branch -d命令删除分支。当然在删除该分支前有一个必须要考虑的问题那就是其中是否还有其他引用指向该分支相关的项目历史记录。否则该修订将会变得无法访问Git系统会在HEAD引用日志过期之后将之删除一般来说默认配置的过期时间是30天后。
Git允许用户删除已经完全合并过的分支因为它的所有提交都还是可以通过HEAD访问的如下图所示或者可以通过它的上游分支访问如果它存在的话。 当我们目前所在的主分支这里是master包含一个名为base-doc的分支时可以先将它的变更与主分支合并然后使用命令git branch -d base-doc 对该分支进行定向删除。
如果要删除一个没有经过合并的分支那么风险就在于该分支在DAG图上是不可达的。用户需要一个更强大的命令即git branch -DGit在拒绝用户删除一个分支时会建议用户使用该命令参见下图 用户甚至可以检查某个分支是否已经和其他分支合并过相关的检查命令是git branch --contains branch。用户不能删除当前的分支。 使用git branch -D osx-port命令删除一个未经过合并的分支osx-port。
2.7、分支的重命名
有时在选择分支名称时常需要对分支进行重命名。这是经常发生的例如在开发过程中特征分支的涵盖范围发生了改变等。
用户可以使用git branch -m命令给分支重命名如果分支名存在而且用户希望重写该分支还可以使用-M选项该操作会对分支重命名并且移动相应的引用日志将重命名操作添加到引用日志中然后修改与之相关的所有配置例如描述信息、上游信息等。