git checkout 命令详解【转】
转自:http://www.cnblogs.com/hutaoer/archive/2013/05/07/git_checkout.html
在日常的git操作中,git checkout——检出,是我们的常用命令。最为常用的两种情形是创建分支和切换分支。
在下面的命令中,使用了一些简写,在这里说明一下:
git st # git status
git ci # git commit
git br # git branch
git co # git checkout
git mg # git merge
git line # git log --oneline
当然,你也可以直接在git中敲命令,将这些简写添加到git配置中
git config --global -e
然后,可以插入下面的配置:
[alias]
st = status
co = checkout
br = branch
mg = merge
ci = commit
md = commit --amend
dt = difftool
mt = mergetool
last = log -1 HEAD
cf = config
line = log --oneline
latest = for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) [%(committername)]' ls = log --pretty=format:\"%C(yellow)%h %C(blue)%ad %C(red)%d %C(reset)%s %C(green)[%cn]\" --decorate --date=short
hist = log --pretty=format:\"%C(yellow)%h %C(red)%d %C(reset)%s %C(green)[%an] %C(blue)%ad\" --topo-order --graph --date=short
type = cat-file -t
dump = cat-file -p
这样,你也就可以使用这些简写的命令咯。下面步入正题啊。
(一)基础——千里之行,始于切糕(checkout)
先熟悉下常用操作,创建分支和切换分支,也可以称为检出分支。
首先我们新建一个仓库gitTest,然后新建文件a,为什么要用a命名呢,这里是故意为之,后面为大家揭晓分支。呵呵。或许下面的介绍会有些枯燥乏味,因为您已经对这些命令烂熟于胸,而且运用得相当熟练,那么您可以直接跳过这一步。
在master分支上,做一次提交c1,然后现在新建一个分支a,并切换到a分支。
这个操作主要会用到两个命令:
创建新分支:git branch branchName
切换到新分支:git checkout branchName
然后,上面两个命令也可以合成为一个命令:
git checkout -b branchName
(二)真相——HEAD是checkout的灵魂
其实,我们在切换分支,和新建分支的时候,有没有想过,这些操作操作背后的工作原理是怎样的呢?最大的功臣就是.git目录下的HEAD引用,她宛如一个芭蕾舞者,从一个分支飘逸的跳到另一个分支,虽无声无息,却精准无比。
在我们身处master分支的时候,您一定很好奇,当前的HEAD的内容是什么?不妨来看看吧。
我们看到c1的提交hash值和HEAD对应分支master的当前hash值是一样的。也就是说,HEAD指向的是当前分支名master,而master又对应了当前的最新的一次提交ID.
好,那么我们再做一次提交,看看master对应的hash值有无变化。
从上图,我们可以不难看出,HEAD对应的ref没有变化,还是master,但是master对应的commit ID却变成了c2对应的commit ID,即更新为最后一次提交的ID咯。
现在,提交一次的原理,我们已然了解,那么切换分支的时候呢??
现在我们身处master分支,然后我们切换到a分支,看看会发生什么样的情况吧。
从上图分析,在master分支上的时候,HEAD指向的是master,对应的是c2的commit ID。而切换到a分支的时候,HEAD也相应的指向了a,同时a对应的是a分支上的最新commit ID。因此,我们可以得出结论,在切换分支的时候,HEAD也会相应的指向对应的分支引用。
但是,使用checkout命令的时候,并不是每次都会改变HEAD指针的指向哦。在什么情况下HEAD一直坚定不移的拥护者他的女神呢?可谓衣带渐宽终不悔,长使英雄泪满襟啊!让我们接着往下看。
(三)进阶——HEAD懂不懂,看你怎么用
checkout命令用法如下:
1. git checkout [-q] [<commit>] [--] <paths> ...
2. git checkout [<branch>]
3. git checkout [-m] [ [-b | -- orphan ] <new_branch>] [start_point]
用法2比用法1的区别在于,用法1包含了路径。为了避免路径和引用(或提交ID)同名而发生冲突,可以在<paths>前用两个连续的连字符作为分隔。用法1的<commit>是可选项,如果省略,则相当于从暂存区进行检出。
来看个例子:
情景1,省略掉<commit>
现在我们处于master分支下,然后我们修改了文件a,输入“c3”文本到a中,这时候,暂存区中的内容是没有"c3"的,通过git diff可以比较。现在我们从当前分支暂存区中检出文件a。那么我们可以直接使用git checkout a。
这时候,提示检出失败,git以为我们想检出仓库a。还记得为什么在第一步中,我们曾新建的文件a吗?这里终于派上用场了,由于仓库中还存在分支a,同时当前分支中又存在文件a,于是git傻傻分不清楚了。这时候怎么办?有两个办法,第一,我们在命名分支的时候要注意语义性,分支名要具有一定的意义,不能使用简单的a,b,c来命名,这样很容易导致分支名和文件名重复;第二,参照用法1,使用两个连字符来分隔。在目前的情形中,我们使用第二种方法吧。
这时候,发现工作区的内容被暂存区的内容覆盖,"c3"文本也没有了,当然HEAD指针也没有什么变化,一切又恢复了平静。
再看一个例子:
情景2,不省略<commit>
在不省略<commit>的时候,<commit>既可以是某一个具体的commit hash值,也可以是某个分支名称,tag名称。不论分支也好,tag也好,它们本质上对应的都是一个commit hash值。
在检出a分支下的a文件的时候,最好把两个连字符加上,不然git也会无法区分。整个过程中,HEAD头指针没有发生改动。
总结:第1种用法(包含<paths>的用法)不会改变HEAD头指针,主要使用于指定版本的文件覆盖工作区中对应的文件。如果省略<commit>,则会用暂存区的文件覆盖工作区中的文件,否则用指定提交中的文件覆盖暂存区和工作区中的对应文件。
接下来,我们看看用法2,在第一部分中,我们知道切换分支,会改变HEAD的指向,那么如果我们是检出某个commit会怎样呢?同检出分支一样,会用该commit下的内容覆盖当前分支工作区和暂存区的内容,请看例子。
目前我们处于master分支上,且已经有了两次提交,分别是c1和c2,然后我们修改a,给a文件添加内容"c3",并add到暂存区,随即使用checkout到c1的commit 上。注意,刚开始checkout的时候,git不会允许你直接切换,因为你修改了暂存区的内容, 它会提醒你提交后再切换,这时候,你可以使用-f 强行切换。再查看状态的时候,git提示我们已经不在任何分支上,HEAD指针也是指向具体的c1的commit值,进入了“分离头指针”状态。这个状态下,要回到master上面,只需要git checkout master即可,也可以在这个状态上新建分支。
如果,checkou后面不跟任何参数,则就是对工作区进行检查,请看例子。
我们身处master分支上,并且没有任何改动,这时候git checkout没有任何输出。然后,我们给a文件添加内容“c3”,然后再git checkout一下,git就会提示a文件有修改,是不是很简单?
总结:对于第2种用法,不是检出某个具体文件的的时候,即不指定<paths>的时候,单纯的检出某个commit或分支,是会改变HEAD头指针的。而且只有当HEAD切换到某个分支的时候才可以对提交进行跟踪,否则就会进入“分离头指针”的状态。如果省略用法2后面的<branch>,则默认对工作区进行状态检查。
(四)熟悉的checkout,陌生的用法,妈妈再也不用担心我的checkout啦!
1. git branch <branch> <start point>
以某个commit创建新分支。 在通常情况下,我们都会在当前分支的基础上,创建新分支。比如git branch new_branch
也许你不知道,我们还可以基于当前分支的某一次commit来创建分支。请看!
3. git checkout -B <branch>
这个命令,可以强制创建新的分支,为什么加-B呢?如果当前仓库中,已经存在一个跟你新建分支同名的分支,那么使用普通的git checkout -b <branch>这个命令,是会报错的,且同名分支无法创建。如果使用-B参数,那么就可以强制创建新的分支,并会覆盖掉原来的分支。请看具体操作。
当前分支为master,且仓库中已经存在分支a,我们先用git checkout -b a来创建a分支,必然会失败的,并提示我们仓库中已经有了一个a分支咯,仿佛在说“hi,哥们,你已经有了一个老婆了,一夫一妻制你的不懂?你以为这里是印度啊?”。随后,我们使用git checkout -B a,耶~~,it works!
4. git checkout --orphan <branch>
是的,假如你的某个分支上,积累了无数次的提交,你也懒得去打理,打印出的log也让你无力吐槽,那么这个命令将是你的神器,它会基于当前所在分支新建一个赤裸裸的分支,没有任何的提交历史,但是当前分支的内容一一俱全。新建的分支,严格意义上说,还不是一个分支,因为HEAD指向的引用中没有commit值,只有在进行一次提交后,它才算得上真正的分支。还等什么呢?赶紧试试!
好了,现在我们终于找到组织了!
5. git checkout --merge <branch>
这个命令适用于在切换分支的时候,将当前分支修改的内容一起打包带走,同步到切换的分支下。
有两个需要注意的问题。
第一,如果当前分支和切换分支间的内容不同的话,容易造成冲突。
第二,切换到新分支后,当前分支修改过的内容就丢失了。
所以这个命令,慎用!
6. git checkout -p <branch>
这个命令可以用来打补丁。这个命令主要用来比较两个分支间的差异内容,并提供交互式的界面来选择进一步的操作。这个命令不仅可以比较两个分支间的差异,还可以比较单个文件的差异哦!
结束语:至此,关于git checkout命令暂告一段落,对于checkout命令,你也有所熟悉了吧。当然,git checkout还有一些其它用法,本文并没有讲到,你可以在git bash或终端中使用git checkout --help去进一步了解!
git checkout 命令详解【转】的更多相关文章
- git checkout 命令详解
转自:http://www.cnblogs.com/hutaoer/archive/2013/05/07/git_checkout.html?utm_source=tuicool&utm_me ...
- git checkout 命令详解(转)
在日常的git操作中,git checkout——检出,是我们的常用命令.最为常用的两种情形是创建分支和切换分支. 在下面的命令中,使用了一些简写,在这里说明一下: git st # git stat ...
- Git 常用命令详解
Git 是一个很强大的分布式版本管理工具,它不但适用于管理大型开源软件的源代码(如:linux kernel),管理私人的文档和源代码也有很多优势(如:wsi-lgame-pro) Git 的更多介绍 ...
- Git 常用命令详解(二)
Git 是一个很强大的分布式版本管理工具,它不但适用于管理大型开源软件的源代码(如:linux kernel),管理私人的文档和源代码也有很多优势(如:wsi-lgame-pro) Git 的更多介绍 ...
- 【转】 Git 常用命令详解(二)----不错
原文网址:http://blog.csdn.net/ithomer/article/details/7529022 Git 是一个很强大的分布式版本管理工具,它不但适用于管理大型开源软件的源代码(如: ...
- git stash命令详解
git stash命令用于将更改储藏在脏工作目录中. 使用语法 git stash list [<options>] git stash show [<stash>] git ...
- git基础命令详解
一些必须要知道的概念 git的三个工作区域:工作目录.暂存区.git仓库. 工作目录:其实就是本地文件磁盘上的文件或目录: 暂存区:是一个文件,保存了下次提交的文件列表信息,一般在git仓库目录中: ...
- Git常用命令详解
1.创建版本库 git clone <url> #克隆远程版本库 git init #初始化本地版本库 通过 ls -ah 可以看到隐藏的.git目录 2.修改和提交 添加文件readme ...
- git add 命令详解
或"表示git会例出索引库中的文件列表中的第个文件."-"表示git会例出索引库中的文件列表中的第个文件到第个文件.回车将执行.如果我们不输入任何东西,直接回车,将结束r ...
随机推荐
- OpenSSL 自签名证书
通过下面9步,可以轻松生成自签名证书. 1.安装.部署OpenSSL 略 2.创建文件夹(下面通常root文件夹).用来放即将创建的各种证书等.如:I:\Key10.167.219.64 3.在roo ...
- BZOJ5020 THUWC2017在美妙的数学王国中畅游(LCT)
明摆着的LCT,问题在于如何维护答案.首先注意到给出的泰勒展开式,并且所给函数求导非常方便,肯定要用上这玩意.容易想到展开好多次达到精度要求后忽略余项.因为x∈[0,1]而精度又与|x-x0|有关,当 ...
- mysql查看表中列信息
查看所有数据库中所有表的数据库名和表名 SELECT `TABLES`.`TABLE_SCHEMA`, `TABLES`.`TABLE_NAME` FROM `information_schema`. ...
- R1 学习记录
libevent框架学习特点: 1.可移植行,跨平台的 2.速度快,libevent会用各平台最快的非阻塞IO函数 3.扩展性 4.方便性构成: 1.evutil: 抽象出各平台network的函数 ...
- BZOJ 1007 水平可见直线 | 计算几何
BZOJ 1007 水平可见直线 题面 平面直角坐标系上有一些直线,请求出在纵坐标无限大处能看到哪些直线. 题解 将所有直线按照斜率排序(平行的直线只保留最高的直线),维护一个栈,当当前直线与栈顶直线 ...
- uoj318 [NOI2017]蔬菜 【贪心 + 堆 + 并查集】
题目链接 uoj 题解 以前看别人博客,在考场上用费用流做,一直以为这题是毒瘤网络流题 没想到竟然是贪心模拟题... 如果只有一个蔬菜呢?这就是一个经典的普及难度的贪心,正着推面临优先选择的困难,而逆 ...
- 解题:SCOI 2008 配对
题面 如果没有两个数不能相同这个限制就两个数组排序后贪心即可.现在加上这个限制,注意到每个数组中的数是两两不同的,所以每次一定能在前面或后面一个数中找一个换过来,这样每次考虑相邻三个数转移就可以了,注 ...
- 关于JavaScript诞生之初的趣事
我在读很多优秀的JavaScript源码时候常常被它诡异的语法搞的精疲力尽,所以时不时的加固JavaScript基础知识是十分有必要的,这些知识每次温故或者你换个角度去思考都能收获颇多,那么如此深不可 ...
- nginx让用户通过用户名密码认证访问web页面
在使用nginx转发的时候,要进行一次用户身份的确认. 1)通过htpasswd命令生成用户名及对应密码数据库文件. [root@bgs-5p173-wangwenting ~]# htpasswd ...
- kubernetes 之ingress
www.cnblogs.com/hellojackyleon/p/8420911.html apiVersion: extensions/v1beta1 kind: Deployment metada ...