[TOC]
前言
刚刚开始使用Git的版本控制时,我根本不确定我付出那么多时间是不是会得到回报,Branch、Stage、Stash、Commit、pull、push、origin这些Git名词对我来说都非常陌生。
今天的我已不能想象开发生活没有Git会变成什么样。
Git不仅提供了非常非常非常需要的版本控制功能,还让我变成一个优秀的程序员。
如何学习Git
最快速的学习就是命令
# 展示显示帮助的命令
git --help
# 显示 拉取操作的命令用法
git help pull
终端输入后,都是直接开启帮助文档,当然都是英文,请自备词典
学习书籍
看不懂英文,没事小黄书一本
感谢开源社区 GitHub progit2
Git 视频教程
Git版本控制视频教程 共有5个视频,因为软件教学视频的更新非常快,而且有实效性,一般不会存留太久,请尊重作者版权,拒绝侵权行为
Git换行符规约
必须使用 Unix 风格的行编码
缺省涵盖 BSD/Solaris/Linux/OSX 的用户,也就是 LF 换行风格,Windows 用户要格外小心,不然出现莫名其妙的冲突。
如果你使用 Git ,你请一定加入下面这个全局配置,来保护你的项目不被 Windows 的行编码侵入导致项目故障:
# Mac 请设置为
git config --global core.autocrlf input
# Windows 请设置为
git config --global core.autocrlf true
从简单的工作流开始
Git的最核心,也是最根本的用法就是工作流,不需要任何高级功能,要的就是简单粗暴,坚守原则的git工作流,在任何大型项目中都适用,svn被淘汰的根本原因就是不能适应工作流。
而工作流是基于Git的分区来工作的,Git在使用的过程中会沉淀很多 commit 和少量的tag,对外展现一个 README,实际开发中,小型或者个人项目使用基础工作流,大型项目使用模板工作流。
Git的分区概念
区域名称 | 位置 | 用途 |
---|---|---|
工作区(working copy) | 就是你当前PC看到的目录 | 日常文本操作或者查看 |
版本库(version) | 工作区里的隐藏目录 .git | 维持本地git各种管理,分支管理,暂存管理,备份管理等等,不用刻意在意它 |
暂存区(Stage) | 版本库里的东西 | git add命令添加到的就是stage分区,commit就是将暂存区的目标内容提交到当前本地分支 |
远程区(origin) | 服务端的代码 | 有时候也叫 服务库,作为开发组的同步基准,不要和部署代码的远程服务器混淆了,部署到服务器的其实也是一个服务器上的本地工作分支 |
基本工作流
用git干活就是工作流方式,简单直接粗暴
Git的工作日常就是,重度关心自己的本地一个分支,不断提交做笔记,一定确认后push(推送)
check -> pull -> add -> commit -> pull ---------------> push -> check
| |
| |
> merge -> commit -->
这是一个从检查确认开始到检查确认的循环
Git使用原则
不到万不得已,不要跨分支提交,除非你不晕多维空间,反正我是晕的
打开工程,拉取一次, 切换本地仓库分支,拉取一次
不要做任何备份(stash),你会在本地仓库建立几何倍数的本地仓库,直到自己无法维护为止
不建议留任何未提交文件就去拉取,Fetch虽好,不要贪拉
不要把系统临时文件,开发工具配置文件,项目配置文件,执行结果文件,编译过程文件,压缩优化文件,日志文件等等,反正是大部分开发者人一眼看不懂内容的文件,或者肯定会和队友冲突的文件,扔到git远程区上去,这样会制造百分百麻烦
拉取不成功,解决冲突,提交不成功,解决冲突,解决不了冲突,请联系队友
冲突解决后,别闲着,要提交,要提交,要提交!
分支合并前,或者提交合并前,注意谁指向谁,工作流执行时几乎都是单向合并
推送前,一定确认还有没有文件没有提交,然后才是,看清楚推送的是谁到谁
使用混合命令偷懒是对的,前提是遵守基础工作流,不然你得修复自己制造的错误
服务器上的部署分支,严禁做任何提交和修改,这是在制造麻烦,服务器上的部署仓库只需要拉取发布分支的提交或者拉取发布的Tag就行
除了部署服务器的pull的默认策略为rebase外,请默认pull的策略为merge
永远别怕犯错误,因为git是每个参与者都是备份,git天生带有非常强悍的修复能力,git是作死都不会死的,除非你不遵守上面的所有原则,这么多原则都不准守的难度确实很大
提交commit和标签tag
git是一个重度commit的使用方式,故会产生极多的commit,时间一长就不好找,tag就是用于管理查询的
tag用于标识发布,或者重度bug,或者仓库迁移,tag和commit可以跨分支查询
ignore的重要性
ignore基础用法是防止没必要的提交的,当然活用的话会非常适合做团队开发,使用合理的ignore来配置团队开发依赖,维护ignore模板是一个开发者的基本工作。
Markdown的实用性
git仓库几乎都是用Markdown来写 README的,怎么写Markdown得单独开章节了。
当然README也有点规矩,README的写法见 另开贴的 README.md 规范
工作流与工作流模板推荐
工作流的详细介绍请参阅 深入理解学习Git工作流 感谢博主对于开源的支持。
作流模板推荐
设计者的Git工作流
Markus Prinz的Git工作流
Yehuda Katz的普通Git工作流
Agile团队的Git工作流
开始用git去作死吧
不要因为觉得Git什么都是命令行,感觉很复杂,学习压力很大,还TMD的全是英文看不懂,你完全可以从今天开始使用Git,去git建立一个git仓库,然后愉快的作死去!
不要再害怕犯错误
Git最出色的一点是:使用Git几乎是100%要出错误
以下几点git的特性让你不再害怕
Git基本上不删除数据。即使是那些看起来是删除数据的操作,实际上是为了让你更快的撤销删除,而在向系统添加数据
Git基本可以撤销所有操作。鼓励你更多的实验和探索你的想法,因为这就是使用版本控制系统系统的最主要的好处之一
你团队的每一个成员都在他/她的计算机中有各自的副本。本质上这更像是整个版本控制项目中的冗余备份(包括包括整个历史纪录),你捅了大娄子而且还没办法还原这种情况是极其少见的
理解分支
Git基本分支和合并方法
分支树是一个Git分支和合并的简短介绍
Git分支是一个绘图过程,图形越好识别,说明工作流越适合这个团队
一个成熟的Git分支模型是大家无意中,用工作流创建的
暂存区解惑
Stage(暂存区) 不是用来做备份,不是用来做备份,不是用来做备份,很重要,需要说三次,用上Git后,你的队友,服务端都是你的完全备份,而万恶的 Stash 才是备份。
--stat参数可以看到每次提交的文件变更统计
# 显示被修改文件的修改统计信息
git log --stat
origin working stash 是你每次用git的时候,必然看到的3个区 远程区 工作区 暂存区 (其实是有备份区,但是强调了不要有备份区出来)
查看提交暂存区和版本库中文件的差异
git diff --cached #or git diff --staged
当对工作区中被修改的文件执行git add时,暂存区中的目录将被更新,同时工作区被修改的文件内容会被写入到对象库中的一个新的对象中,新对象的ID被记录在暂存区的文件索引中。
git commit时,暂存区的目录树会写到版本库(对象库)中,master分支会做相应更新,即master最新指向的目录树就是提交时原暂存区的目录树
git reset HEAD时,暂存区的目录树会被重写,会被master分支指向的目录树替换,但是工作区不受影响
git rm --cashed <file>或git checkout -- <file>时,会用暂存区全部的文件或指定的文件替换工作区的文件!!
git checkout HEAD或git checkout HEAD <file>会用HEAD指向的master分支中的全部或相应文件替换暂存区和工作区中的文件。当进行提交时,实际上是将暂存区的内容提交到版本库中
请使用Git图形界面
对于程序员来说
不会用终端命令的程序员是没有兽性的,这种码农生存困难,衣食堪忧
不过还有一句话
没有界面或者一键安装的软件或者系统,都是在耍流氓
所以,请在日常开发中,多使用图形界面,并混合git命令来不断提高自己
管理工具-Git 桌面版
多种仓库类型支持的 SourceTree
安利一下 SourceTree 支持 git 和 svn hg等
SourceTree还有一个好处就是可以中文,提供各种非常人性的快捷方式,还有最重要的,能看到你的每次Git操作的命令内容。
目前最流行的Github 推出的 Github desktop
Github desktop 编程界的圣地亚哥,Github官方客户端,功能不多,但是没有蛀牙~
开发工具-Git IDE插件
Eclipse家族
Eclipse 及其衍生的IDE,比如zend,还有各种马甲的,请使用有严重bug的 EGit
(但是在Eclipse生态圈,Egit已经是Bug最少的了),Egit最常见的bug就是暂存区突然出现莫名其妙的文件,文件名各种随机,文件内容一般奇怪,无法忽略,无法定位,出现一次得整个团队折腾一次。
当然现在Eclipse已经被替代了,Eclipse生态已经进入死亡期,新的Eclipse已经放弃了老生态,改名叫Eclipse che
建议改用当今时代的IDE,或者 sublime text
或者 Atom
这样的智能编辑器
非得用Eclipse的话,安装Egit也很简单,EGit 的版本繁多,Bug也多,除了原生 Eclipse 通过 Eclipse Market 安装良好,其他的衍生品IDE,请自行查找对应版本的安装源。
JetBrains 家族
集成开放环境推荐使用 Jetbrains 家的东西,插件很多,快捷键合理一致,响应快速(前提会java优化),默认带有非常完善的Git插件
Jetbrains的 Git工具没有严重bug,还有很多Git工具插件类似 .ignore
含义非常实用的git ignore管理和内置了各种使用ignore模板,而且人性化很多(用了1年的EGit日常记它小黑本)
Jetbrains 的IDE有
名称 | 语言 | 用途 | 是否付费 |
---|---|---|---|
IntelliJ | Java | java开发,JetBrains的基础 | 否 |
Android Studio | Java | Anroid开发,基于IntelliJ,谷歌扶持 | 否 |
WebStorm | Web Javascript CSS | Web H5等等的开发套件 | 是 |
PyCharm | Python Web Javascript | Python开发套件,基于WebStorm | 是 |
RubyMine | Ruby Web Javascript | Ruby开发套件,基于WebStorm | 是 |
PhpStorm | php web | php开发套件,基于WebStorm | 是 |
AppCode | Swift OC | iOS/OS X 开发套件,个人感觉比XCode那个连插件管理都做不好的好太多 | 是 |
CLion | C C++ | C语言的开发套件,目前最智能的C语言IDE(其实是因为其他的不争气) | 是 |
OxDBE | database&SQL | 数据库管理工具 ORACLE MySQL MongoDB SQLite DB2 SYBASE | 是 |
JetBrains几乎覆盖了所有的开发环境,JetBrains的快捷键统一,界面统一,只有一次的学习成本,如何入门JetBrains,以及深入使用,请等新帖链接,因为JetBrains实在太强大而且功能太多了。
富文本编辑器
推荐 Sublime Text 3 的git插件,具体使用另开篇幅
Atom 是由GitHub出品的,肯定带有git的编辑器,使用参见Atom 编辑器 入门 快捷键 插件安利
从 SVN 投奔过来的注意事项
git 和 svn区别
git是分布式版本管理,也就是本地即完整的仓库,包括所有的提交,分支,标签等,而且提交,分支等操作都是在本地进行,与远程仓库只是相互同步的关系
svn是集中式版本管理,本地只是远程仓库的某个镜像,比如处于某个分支,某个版本,但不保存其他版本信息,提交或者建分支等操作都是要连接远程仓库的。
svn 中本地和远程的关系相当于我们浏览器打开网站和该网站的服务器的之间的关系,我们本地只是状态,而我们要提交修改或切换页面都是通过与服务交互进行的。
而 git中本地和远程的关系相当于两台服务器之间的关系,两者都能独立完成操作,两者之间需要的只是同步。
使用版本管理工具的最大坏习惯
使用SVN的10个有9.9个喜欢不完全提交,因为懒或者紧急情况什么的,理由有很多,反正就是有提交残留
提交残留又称代码垃圾,提交残留导致团队工作过程中,大家都出现没完全提交,故大家都会扔代码垃圾。
代码垃圾和垃圾代码是两个东西,一个是代码管理的,一个是开发水平的,不可混谈
SVN是同步式设计,设计上要求一定同步,所以,我见过的开发团队只要是SVN管理的代码,只要开发了一段时间后,代码都是一团糟,因为这些团队都在违背SVN的设计--完全同步,所以团队项目是SVN管理的免不了成为代码垃圾场,SVN损坏啊,不知道搞了啥东西,各种额外备份啊,各种应对方法都来了,效果就是拆东墙补西墙。
Git其实也怕不提交代码,制造代码垃圾
当然Git与SVN不同,很多SVN到Git的玩家,学会了缓存区,本地多分支什么的,以此继续扔代码垃圾的职业人生。
开始的使用Git的时候,他们玩得很hi没出篓子,但很快发现垃圾代码在影响自己的每一天提交,甚至导致本地工作区和暂存区损坏,他们会觉得Git老是和他们作对,然后就向Git发脾气,抱怨没有XXX好用。
任何时候,不要和严谨的程序生气,因为一开始你就输了。
冷静下来后,他们开始做完全提交,一步一的改正不好的习惯,最后他们都放弃了制造代码垃圾。
因为以前SVN是单一服务器,扔垃圾不会臭自己,要臭臭全家,既然大家都臭就都糊涂装没事情,但是在Git管理下,扔垃圾代码都是臭自己,让那些制造垃圾的收拾自己的烂摊子去。
造成上述的代码垃圾原因是一个,影响却是完全不同,建议使用git管理团队代码,毕竟不靠谱的队友什么时候都不会缺少的,git会隔离这些猪队友,并让他们恶心自己。
Git tips
常用命令
把一个本地文件夹提交到远程仓库
首先需要一个远程仓库地址,需要有访问权限的那种
git init
# first of all you need .gitignore
git add .gitignore
git add --all
git commit -m "init commit"
# you need git address [git or https]
git remote add origin [git address] && git push -u origin master
查询自己搞了什么幺蛾子
# 查询当前git本地仓库存在咩问题
git status
# 查看自己搞了什么飞机
git diff [文件路径/文件名]
查询修改
# 显示被修改文件的修改统计信息
git log --stat
# 逐行显示历史
git log --pretty=oneline
# 显示最近[number]条的修改
git log --stat -[number]
# 显示具体的修改
git log -p -2
# 显示我自己的修改
git log --stat --author=[Your name]
# 查看单个文件[file path]最近[times]次修改的记录
git log --stat -[times] -- [file path]
精准的提交
git commit -m "[commit message]"
提交写错了没事可以这样做
# 逐行显示历史
git log --pretty=oneline
# 针对目标提交
git rebase -i [commit name]
# 或者找出分支名的最近[times]次提交
git rebase -i HEAD~[times]
# 等待一会儿后,会进入 vi 界面然后会出现[times]行的提交 和操作提示
pick: [commit name]
pick: [commit name]
pick: [commit name]
...
# 使用vi编辑操作修改你需要改的那个[commit name],从pick改成edit,然后保存退出查看日志
git log
# 提交正确的message
git commit --amend -m "[message]"
# 最后重置提交一下
git rebase --continue
这个方法也可以用于修改commit的文件,不过不建议这样做,建立新的提交就行,错了不丢人,丢人的是知错不改,还藏着
查看我的提交历史
# 查看完全历史
git log
# 逐行显示历史
git log --pretty=oneline
快速回退工作区版本
# 工作区回退到上一个版本
git reset --hard HEAD^
# 工作区回退到上上个版本
git reset --hard HEAD^^
# 工作区回退到上第 times 个的版本
git reset --hard HEAD^[times]
# 工作区回退到某个名字[commit] 的版本
git reset --hard [commit]
查看自己历史干了啥输入了什么命令
git reflog
撤销工作区修改
# 撤销目标文件[filename]的修改
git checkout -- [filename]
删除工作区文件
# 删除工作区的[filename]文件
git rm [filename]
找回错误删除的文件
# 删除错误的文件[filename]
git checkout [filename]
git tag 使用
tag 用于版本发布,分支用于开发管理,千万别使用分支来区分功能,会非常难使用
# 创建轻量标签
git tag 1.0.0
# 创建附注标签
git tag -a 1.0.0 -m "1.0.0 msg"
# 显示标签
git show
# 切换到标签
git checkout [tagName]
# 删除标签
git tag -d [tagName]
# 给指定的commit打标签
git tag -a [tagName] [commit]
# 标签发布
git push origin [tagName]
# 本地所有标签一次性提交
git push origin –tags