本文主要用于记录阅读Git教程 - 廖雪峰的官方网站后的一些心得笔记,并且对git一些常用命令做一个整理总结。

本文要点分为:1、Git简介;2、Git常用命令;3、Git分支管理。

一、Git简介

什么是Git?

Git是目前世界上最先进的分布式版本控制系统(没有之一)。

Git的诞生

个人觉得还是很有必要了解一下Git的来龙去脉的,这样可以加深对Git这家伙的认识。

很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?

事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!

你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。

不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。

安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。

Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。

Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。

历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。

Git 与 SVN 的区别

我自己最早接触的就是SVN,从SVN到Git使用感触还是比较深刻的,此处先简单叙述一下我个人的理解。

首先,这是一个分布式(git)和集中式(svn)的区别。git好处在于多个人共同研发一个项目可以互不影响,或者多个需求进来可以分不同版本进行分布研发互不影响。而svn由于项目代码集中在一台机子上管理,往往受到彼此的牵制影响,很难做到多个版本并行研发。

其次,svn的那个套路是需要联网才能上传提交和下载更新,而git如果你不去推送到远程分支的话,仅本地git管理的话是可以不用联网的。

最后,git最强大的一点就是他的分支管理还有tag标签管理,如果是小团队(1~2人)、小项目(很少有需求变更,版本更新不多的情况)用用SVN还是阔以的,但是一旦项目庞大、版本复杂,这个时候强烈介意采用git来进行管理,不然svn会被虐很惨的。

△svn图示 -- 集中式

△git图示 -- 分布式

关于git远程分支(origin)的理解,摘要如下:

在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。

综上,我觉得git是一个可以实现“分布式”的升级版“SVN”,当多个人在一个git分支上进行共同研发的时候,那么他就是一个类似svn的操作;当多个人在不同git分支进行研发的时候,那么我们就能感受到了git的强大,svn的局限。

二、Git常用命令

说明:以下红色字体为固定命令,紫色字体为可变参数,一般指代路径名或文件名或分支名等。

git clone git@github.com:michaelliao/gitskills.git  从远程库克隆

如果有多个人协作开发,那么每个人各自从远程克隆一份就可以了。

你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

git remote add origin git@server-name:path/repo-name.git 关联远程库

注:一般都是从远程库克隆来拉取项目的,不建议本地去关联远程库。

要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git

关联后,使用命令git push -u origin master第一次推送master分支的所有内容;

此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;

分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!

git log 查看提交日志

git log --pretty=oneline 带参数地查看提交日志,显示会好看些

git log --graph 查看分支合并图

git log --graph --pretty=oneline --abbrev-commit 带参数地查看分支合并图,显示更好看

git reset --hard HEAD^ 回滚到上一个版本

git reset --hard HEAD^ 回滚到上上一个版本

git reset --hard commit_id  回滚到指定的提交id,例如 git reset --hard 1094a

注:此处版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。

git add readme.txt 添加改动过的文件至暂存区

git commit -m "change something"  将暂存区的变更提交至当前分支,同时带上message备注

git status 查看当前仓库状态,比如有没有还没提交的呀啥的

git checkout -- file 丢弃工作区的修改 比如

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commitgit add时的状态。

git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令。

git branch 查看本地分支

git branch -r 查看远程分支

git branch -a 查看所有分支

git branch <name> 创建分支

git checkout <name> 切换分支

git checkout -b <name> 创建+切换分支

git merge <name> 合并某分支到当前分支

git branch -d <name> 删除分支

注:以下为实战经典操作,所以整段copy了过来,大家可以完整地感受一下git命令常用流程。

首先,我们创建dev分支,然后切换到dev分支:

$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch dev
$ git checkout dev
Switched to branch 'dev'

然后,用git branch命令查看当前分支:

$ git branch
* devmaster

git branch命令会列出所有分支,当前分支前面会标一个*号。

然后,我们就可以在dev分支上正常提交,比如对readme.txt做个修改,加上一行:

Creating a new branch is quick.

然后提交:

$ git add readme.txt
$ git commit -m "branch test"
[dev b17d20e] branch test1 file changed, 1 insertion(+)

现在,dev分支的工作完成,我们就可以切换回master分支:

$ git checkout master
Switched to branch 'master'

切换回master分支后,再查看一个readme.txt文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:

现在,我们把dev分支的工作成果合并到master分支上:

$ git merge dev
Updating d46f35e..b17d20e
Fast-forwardreadme.txt | 1 +1 file changed, 1 insertion(+)

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。

合并完成后,就可以放心地删除dev分支了:

$ git branch -d dev
Deleted branch dev (was b17d20e).

删除后,查看branch,就只剩下master分支了:

$ git branch
* master

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

git remote -v 查看远程库信息

git push origin branch-name 从本地推送分支

git pull 抓取远程的新提交

git checkout -b branch-name origin/branch-name 在本地创建和远程分支对应的分支,本地和远程分支的名称最好一致

git branch --set-upstream branch-name origin/branch-name 建立本地分支和远程分支的关联

git tag 查看所有标签

git tag <tagname> 新建一个标签

默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办? 方法是找到历史提交的commit id,然后打上就可以了:

假设它对应的commit id是f52c633,敲入命令:

$ git tag v0.9 f52c633

git tag -a <tagname> -m "blablabla..." 可以指定标签信息

创建带有说明的标签,用-a指定标签名,-m指定说明文字:

git show <tagname> 可以看到说明文字

git tag -d <tagname> 删除一个本地标签

因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。 如果要推送某个标签到远程,使用命令git push origin <tagname>

git push origin <tagname> 推送一个本地标签

git push origin --tags 推送全部未推送过的本地标签

git push origin :refs/tags/<tagname> 删除一个远程标签

如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)

然后,从远程删除。删除命令也是push,但是格式如下:

$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git- [deleted]         v0.9

要看看是否真的从远程库删除了标签,可以登陆GitHub查看。

三、Git分支管理

不行了,写的我太TM累了,分支管理暂时用以前的文章将就地看一下吧:Git分支管理使用心得

不过还是那句话,具体情况具体分析,git为我们提供了分布式开发的可能性,如何去应用git分布式特性到我们的项目当中,需要我们灵活应变。

廖雪峰Git教程笔记与总结 -- Git简介、常用命令、分支管理相关推荐

  1. Git之(三)Git中常用命令——分支管理

    三.Git中常用命令--分支管理 为什么要使用分支管理? 分支就是科幻电影里面的平行宇宙,也就是当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN. 如果两个平行宇宙互不干 ...

  2. 廖雪峰Python教程-笔记

    廖雪峰Python教程 学习范围: Python基础 函数 高级特性 函数性编程 模块 面向对象编程 错误,调试和测试 IO编程 笔记: Python的整数没有大小限制 Python 3的字符串使用U ...

  3. 廖雪峰python教程笔记:装饰器

    这是看廖老师python教程的第一个的笔记,因为这是这份教程最难的章节之一,我来来回回看了三遍,终于有所突破,写在这里是为了巩固自己的理解,同时也是希望有错的地方能够得到指正.具体内容见廖雪峰老师的课 ...

  4. 廖雪峰Python教程笔记(一)

    原文链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 感谢廖老师精彩的Pyt ...

  5. 廖雪峰Python教程笔记

    文章目录 创建只有一个值的 tuple 不可变对象调用方法 使用python的下标循环 全排列 python中的三目运算符 生成器 可迭代对象和迭代器 迭代器与生成器的区别 函数名是一个变量 高阶函数 ...

  6. 廖雪峰js教程笔记 2

    arguments JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数.arguments类似Array但它不是一个Arr ...

  7. 廖雪峰js教程笔记9 json

    JSON是JavaScript Object Notation的缩写,它是一种数据交换格式. 在JSON出现之前,大家一直用XML来传递数据.因为XML是一种纯文本格式,所以它适合在网络上交换数据.X ...

  8. 廖雪峰python教程整理笔记_廖雪峰python教程笔记(一)

    变量与变量名 如 a = 123,此时,python解释器在做了两件事,在内存中创建了一个整数123对象,在内存中创建了一个名为a的变量.并把它指向123,一个赋值语句被执行后,内存中一个变量名与它所 ...

  9. 廖雪峰js教程笔记10 浏览器对象

    JavaScript可以获取浏览器提供的很多对象,并进行操作. window window对象不但充当全局作用域,而且表示浏览器窗口. window对象有innerWidth和innerHeight属 ...

最新文章

  1. HDU - 5874 Friends and Enemies 完全二分图
  2. OSI[七层]与TCP/IP[四层]模型简述简图
  3. oracle的正则表达式(regular expression)简单介绍
  4. centos 查找nginx_centos7 nginx安装/启动/进程状态/杀掉进程
  5. Zabbix邮件报警配置
  6. python123九宫格输入法_《啊哈C语言-2016最新修正版》.pdf
  7. IT人不要一直做技术(转载)
  8. [自己动手玩黑科技] 1、小黑科技——如何将普通的家电改造成可以与手机App联动的“智能硬件”...
  9. 《快速开发》通过Maven创建WebService项目Hello World!
  10. Java开发发送短信功能的实战教程(真实项目已在使用)
  11. android地球经纬度平面图,地球经纬度划分图高清 怎么划分经纬度
  12. Busboy 上传文件到指定目录,并重命名,node.js
  13. 《知识产权知识产权信用管理规定》解读问答
  14. 国家气象局提供的天气预报接口
  15. vbs过程参数--byref和byval
  16. Python 学习笔记 -- pickle模块,如何腌制泡菜(入门级)
  17. 助力篇|常见金融风控数据分析内容汇总,助你面试道路畅通无阻
  18. 学习能力 什么是真正的学习
  19. LeetCode 第 194 场周赛
  20. 基于新版本Gradle上传jitpack开源项目

热门文章

  1. jQuery实现点击链接显示和隐藏二维码
  2. 基于STM32人群定位,调速智能风扇设计
  3. java 枚举报错_java 枚举
  4. OneForAll子域名工具尝鲜
  5. 写专利还是比较辛苦的
  6. docker cuda的devel和runtime包
  7. 曾经一个程序员把BUG变成了彩蛋,这个程序员却把彩蛋变成了BUG
  8. 盘点那些以“马”作为车标的汽车品牌
  9. ITE EC代码解析1
  10. 【毕业设计】基于单片机无线充电的4轴飞行器 -物联网 嵌入式 stm32