转自: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 ...
随机推荐
-
[Ng]Angular应用点概览
1. 使用模块化写法. var app = angular.module('myApp', []); app.controller('TextController', function($scop ...
-
asp.net预定义的HttpModule
在asp.net中,已经预定义了很多HttpModule,甚至在服务器的网站配置文件中进行了注册,我们可以通过系统文件夹C:\Windows\Microsoft.NET\Framework\v4.0. ...
-
Asp.net Vnext ModelBinding
Model Binding 本文已经同步到<Asp.net Vnext 系列教程 >中] Model binding(绑定)简单来说就是通过遍历ValueProvider(值提供者)获取的 ...
-
关联 Android 源代码 到 Ecplise
1. 下载android 源码存于本地硬盘; 2. 打开Eclpise, 新建Android Project; 3. 在MainActivity文件中,按住Ctrl 点击Activity类 4. 弹出 ...
-
repo manifest xml 文件修改后提交命令
git push origin dev(本地分支):refs/for/tv/Internal_Jb910_develop_t
-
[置顶] 宏途_LCD调试流程.
今天在调试宏途的LCD屏时,开始是开机屏幕不亮,背光都不亮,可能板子已经损坏,一般通过测试电流电压简单验证,(注:硬件引脚没焊好也会引起读lcd id出现错误!!!)出现这个问题一般是因为引脚没焊好, ...
-
web领域的实时推送技术-WebSocket
WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex),即是所谓的及时推送技术. 在此之前,很多网站为了实现及时推送技术通常采用的是 ...
-
mssql server for docker on MacOs
1. install 1.下载镜像 docker pull microsoft/mssql-server-linux 使用该命令就可以把数据库的docker镜像下载下来. 2.创建并运行容器 dock ...
-
LOL新版符文 怎么查看队友的符文配置?
LOL怎么看其他玩家符文? 像我这种名字都懒的打的, 直接去WeGame复制昵称. 然后在LOL主界面点生涯, 之后搜索 光头强xian生
-
AutoRegister ASM AOP 字节码 案例 原理 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...