Git教程

> 参考 [黑马程序员Git全套教程](https://www.bilibili.com/video/BV1MU4y1Y7h5/?spm_id_from=333.999.0.0&vd_source=27c473f67063aa6a855a81b25ef650c9)
版本管理工具介绍
现在比较流行的版本管理工具是git ,但是实际上git 是近几年才发展起来的,可能有一些老的项目,还在用一些老的软件,比如svn
版本管理发展简史(维基百科)
SVN(SubVersion)
工作流程
SVN是集中式版本控制系统,版本库是集中放在中央服务器的.
工作流程如下:
1.从中央服务器远程仓库下载代码
2.修改后将代码提交到中央服务器远程仓库
2
3
4
优缺点:
优点: 简单,易操作
缺点:所有代码必须放在中央服务器
1.服务器一旦宕机无法提交代码,即容错性较差
2.离线无法提交代码,无法及时记录我们的提交行为
2
3
4
svn流程图
Git
工作流程
Git是分布式版本控制系统(Distributed Version Control System,简称 DVCS),分为两种类型的仓库:
本地仓库和远程仓库
工作流程如下
1.从远程仓库中克隆或拉取代码到本地仓库(clone/pull)
2.从本地进行代码修改
3.在提交前先将代码提交到暂存区
4.提交到本地仓库。本地仓库中保存修改的各个历史版本
5.修改完成后,需要和团队成员共享代码时,将代码push到远程仓库
2
3
4
5
6
7
8
总结:git和svn的区别
1. svn 是集中式版本控制工具,git 是分布式版本控制工具
2. svn 不支持离线提交,git 支持离线提交代码
2
Git 发展简史
林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds, 1969年~ )
很多人都知道,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社区免费使用这个版本控制系统。而授权的前提是:Linux 社区的人不能开发具有相同功能的竞争产品!
另一方面,BitKeeper不是开源的. 显然与Linux 的开源精神不相符,所以linux 社区的很多人抱怨,不愿意使用.
典型的就是 Andrew Tridgell (Samba 开发服务的创造者) 非常不满.偷偷违反了和 BitKeeper 的协议,反编译 BitKeeper 的源代码,开发了个爬虫,然后爬取信息被人发现了. BitKeeper 公司的领导非常不满意,然后开始发布消息说,(下个版本)不再为Linux 提供免费的服务.
Linus 本人就出面协调(几周或者几个月),但是不管用, 没办法. 估计谈判的过程感觉到了憋屈--"吃人嘴短,拿人手软"
Linus 本人 花了10天的时间Git 出来了,一个月之内,Linux系统的源码已经由Git管理了!
Git 出来以后毕竟是一个人做的,开始并不好用(刚开始只能用勉强可以用来形容), 还是很多人抱怨,发展了很多年都没有干过其他软件.
直到 2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,从此git 迎来了飞速发展,当下git 已经成为了最流行的版本控制工具
Git 工作流程
Git 初始化
命令行方式
cmd/iTerm 进入需要初始化的文件夹 执行 git init
客户端方式
我们先初始化一个本地仓
1) 新建测试文件夹
2) 进入文件夹,然后右键创建版本库
2
此时 我们看到
1) 文件夹上多了一个绿色图标
2) 文件夹内部生成了一个.git 隐藏文件夹(需要设置隐藏文件夹可见)
2
git 流程
流程图
概念即详解
本地仓库:是在开发人员自己电脑上的Git仓库,存放我们的代码(.git 隐藏文件夹就是我们的本地仓库)
远程仓库:是在远程服务器上的Git仓库,存放代码(可以是github.com或者gitee.com 上的仓库,或者自己该公司的服务器)
工作区: 我们自己写代码(文档)的地方
暂存区: 在 本地仓库中的一个特殊的文件(index) 叫做暂存区,临时存储我们即将要提交的文件
------------
Clone:克隆,就是将远程仓库复制到本地仓库
Push:推送,就是将本地仓库代码上传到远程仓库
Pull:拉取,就是将远程仓库代码下载到本地仓库,并将代码 克隆到本地工作区
2
3
4
5
6
7
8
8.tag 标签
8.1 标签的概念
如果你的项目达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以给它打上标签(tag)
比如说,我们想为我们的项目发布一个"1.0"版本。 我们给最新一次提交打上(HEAD)"v1.0"的标签。
标签可以理解为项目里程碑的一个标记,一旦打上了这个标记则,表示当前的代码将不允许提交
2
3
8.2 标签的创建(tag)
标签的创建和分支的创建操作几乎一样
8.3 标签的切换与删除
9. 远程仓库
我们的代码不能总是放在本地,因为总是放在本地,一旦电脑出现故障,数据将丢失,怎么共享呢,这里我们需要一个服务器, 我们可以把代码放到服务器上,然后让别人下载,这样我峨嵋你既可以备份代码,也可以进行团队协作开发
9.0 局域网仓库
实际上我们可以搭建一个单间的局域网服务器共享我们的代码
9.0.1本地相对路径,多个文件夹之间共享代码
9.0.2开启局域网共享代码
局域网这种共享是没有安全控制的,都可以访问,如果想要搭建一个可以控制权限的服务器需要借助第三方软件
gitblit,可以自行搜索搭建
9.1 常用远程仓库托管服务
除了自己搭建服务器,其实我们可以使用一些免费的远程仓库,远程仓库有很多,常见的免费互联网远程仓库托管服务如下:
www.github.com
www.gitee.com
www.gitlab.com
github 是一个基于git实现在线代码托管的仓库,向互联网开放,企业版要收钱。
gitee 即码云,是 oschina 免费给企业用的,不用自己搭建环境。
gitlab 类似 github,一般用于在企业内搭建git私服,要自己搭环境。
GitHub(gitee)、GitLab 不同点:
1、GitHub如果使用私有仓库是需要付费的,(2019年开始私有仓库也是免费的但是只能3个人协同开发,想要更多需要收费),GitLab可以在上面搭建私人的免费仓库。
2、GitLab让开发团队对他们的代码仓库拥有更多的控制,相对于GitHub,它有不少的特色:
(1)允许免费设置仓库权限
(2)允许用户选择分享一个project的部分代码
(3)允许用户设置project的获取权限,进一步提升安全性
(4)可以设置获取到团队整体的改进进度
(5)通过innersourcing让不在权限范围内的人访问不到该资源
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
鉴于国内用户可能网络不好,这里我们使用gitee(码云) 来讲解我们的课程,其他可自行找资料学习非常类似
9.2 码云账号注册
填写邮箱发送验证码,然后可以注册账号,主页如下
9.3 创建远程仓库
各个类型仓库之间的区别
9.4 把本地代码推送到远端
此时我们刷新仓库发现代码已经存在了
我们填写的用户信息,会被保存在本地,下次提交无需填写用户名和密码
9.5 从远程仓库克隆代码
我们同样可以从库下载代码,
新建一个文件夹 repo2 ,进入然后进行如下操作
此时我们发现我们的代码已经被下载下来了
9.6 代码的修改与提交,查看历史
1)此时我们修改代码就不能仅仅是提交到本地了,提交完毕应该推送到远端服务器
2)此时如果别人从远端仓库下载最新的代码其实是可以看到我们的代码修改记录的
git -->显示日志
2
3
9.7 ssh 连接概述
实际上git 不仅仅支持用户名密码方式的配置,可以有另外一种相对更加安全的配置即ssh 方式配置
ssh 方式的底层原理
ssh连接地城是RAS加密算法,又称非对称加密,是一种现在公认的最安全的加密方式
数学基础好的同学可以研究一下
https://www.cnblogs.com/cjm123/p/8243424.html
公钥私钥加密可以看作古代 的"虎符" , 我们本地电脑有一份,远程服务器有一份, 只要 "虎符" 核对通过 表示身份无误,可以执行提交等操作,无需输入用户名密码
2
3
4
5
9.8 ssh 密钥的生成
#生成公钥私钥
ssh-keygen -t rsa
一直回车即可
会默认用户目录 .ssh 目录生成一个默认的id_rsa文件 和id_rsa.pub
2
3
4
9.9 ssh 密钥配置
9.10 ssh 方式克隆/提交代码:
配置完成之后我们克隆我们之前的项目
修改后直接提交推送即可成功,,git 会自动去.ssh 目录找我们的私钥进行匹配
9.11. 远程仓库的其他操作
概念
当我们从 gitee 上查看别人的项目的时候我们可能会看到上图中的按钮
指数:
是gitee 网站根据当前项目的各项指标计算出来的一个值
2
Star:
点赞, 注意这里的并不像朋友圈那样容易获得点赞,圈内人还是很克制的
Watch:
如果你watch 了某个开源项目,那么这个项目后续所有的改动你将收到通知
Fork :
将别人的代码克隆到你自己的仓库
作用一: 如果担心某个优秀的项目别人突然有一天不开源了,你可以fork到自己的仓库
作用二: 修改别人的代码
以linux 为例,你其实不是linux 社区的开发人员,但是你 又想为linux 开发做贡献(维护代码)
你并没有权限,怎们办?
你可以先把linux 开源的代码 fork 到你自己的仓库,此时你就可以操作自己的仓库进行修改代码了
如何让别人合并你修改好的代码呢?
我们注意项目的上方有一个 " Pull Request" 这个按钮的意思是 "请求求别人合并你修改的代码"
当我们发起一个 Pull Request 时 , 项目的拥有者将收到 Pull Request请求,然后将根据你提交代码的质量决定是否合并
2
3
4
5
6
7
8
9
10
11
12
13
14
项目操作
1)我们可以删除修改我们自己仓库的基本信息
- 我们可以邀请其他人成为项目的开发人员或者管理人员
我们可以删除修改我们自己仓库的基本信息
9.12 利用 gitee 搭建个人主页
1)将静态资源上传至仓库
2) 选择服务 pages 即可部署
注意 1)必须有个index.html 文件
注意 2) 只能搭建静态网站,动态网站请租赁服务器搭建提供服务
注意 3) gitee 要求必须绑定手机号
2
3
4
5
6
点击开启后gitee 会自动生成一个域名
直接访问即可
此时我们已经在git 上部署了一个静态的网站
10.命令行-- git基本操作
10.1 介绍
上述我们的操作 使用的 是客户端TortoiseGit 操作的git ,实际上底层依旧是使用的命令行帮我们执行, 在早期 git 并没有窗口化工具,开发人员只能使用命令行模式
实际上,如果你掌握并熟练使用了命令行模式操作git 的话,你会发现某些操作命令行比窗口化操作要简单
所有你在工作中会发现高深的技术人员可能会喜欢命令行模式提交git
##10.2 环境配置
当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息
#设置用户信息
git config --global user.name “itcast”
git config --global user.email “itcast@itcast.cn”
#查看配置信息
git config --list
git config user.name
#通过上面的命令设置的信息会保存在~/.gitconfig文件中
2
3
4
5
6
7
8
##10.3 初始化本地仓库 init
## 初始化仓库带工作区
git init
## 初始化仓库不带工作区
git init --bare
2
3
4
##10.4 克隆 clone
## 从远程仓库克隆
git clone 远程Git仓库地址
例如: git clone https://gitee.com/itcast/gittest.git
2
3
##10.5 查看状态 status
## 查看状态
git status
#查看状态 使输出信息更加简洁
git status –s
2
3
4
##10.6 add
## 将未跟踪的文件加入暂存区
git add <文件名>
## 将暂存区的文件取消暂存 (取消 add )
git reset <文件名>
2
3
4
5
##10.7 commit
# git commit 将暂存区的文件修改提交到本地仓库
git commit -m "日志信息" <文件名>
2
3
##10.8 删除 rm
## 从本地工作区 删除文件
git rm <文件名>
## 如果本工作区库误删, 想要回退
git checkout head <文件名>
2
3
4
11. 命令行--git 远程仓库操作
11.1 查看远程
## 查看远程 列出指定的每一个远程服务器的简写
git remote
## 查看远程 , 列出 简称和地址
git remote -v
## 查看远程仓库详细地址
git remote show <仓库简称>
2
3
4
5
6
7
11.2 添加/移除远测仓库
## 添加远程仓库
git remote add <shortname> <url>
## 移除远程仓库和本地仓库的关系(只是从本地移除远程仓库的关联关系,并不会真正影响到远程仓库)
git remote rm <shortname>
2
3
4
11.3 从远程仓库获取代码
## 从远程仓库克隆
git clone <url>
## 从远程仓库拉取 (拉取到.git 目录,不会合并到工作区,工作区发生变化)
git fetch <shortname> <分支名称>
## 手动合并 把某个版本的某个分支合并到当前工作区
git merge <shortname>/<分支名称>
## 从远程仓库拉取 (拉取到.git 目录,合并到工作区,工作区不发生变化) = fetch+merge
git pull <shortname> <分支名称>
git pull <shortname> <分支名称> --allow-unrelated-histories ## 强制拉取合并
2
3
4
5
6
7
8
9
注意:如果当前本地仓库不是从远程仓库克隆,而是本地创建的仓库,并且仓库中存在文件,此时再从远程仓库拉取文件的时候会报错(fatal: refusing to merge unrelated histories ),解决此问题可以在git pull命令后加入参数--allow-unrelated-histories (如上 命令)
## 将本地仓库推送至远程仓库的某个分支
git push [remote-name] [branch-name]
2
12. 命令行-- 分支
## 默认 分支名称为 master
## 列出所有本地分支
git branch
## 列出所有远程分支
git branch -r
## 列出所有本地分支和远程分支
git branch -a
## 创建分支
git branch <分支名>
## 切换分支
git checkout <分支名>
## 删除分支(如果分支已经修改过,则不允许删除)
git branch -d <分支名>
## 强制删除分支
git branch -D <分支名>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 提交分支至远程仓库
git push <仓库简称> <分支名称>
## 合并分支 将其他分支合并至当前工作区
git merge <分支名称>
## 删除远程仓库分支
git push origin –d branchName
2
3
4
5
6
13 . 命令行 --tag
## 列出所有tag
git tag
## 查看tag详细信息
git show [tagName]
## 新建一个tag
git tag [tagName]
## 提交指定tag
$ git push [仓库简称] [tagName]
## 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]
## 删除本地tag
$ git tag -d [tag]
## 删除远程tag (注意 空格)
$ git push origin :refs/tags/[tag]
2
3
4
5
6
7
8
9
10
11
12
13
14
14. 案例
企业中我们是如何开发的
1) 入职第一天,管理人员分配/git账号密码
2) 开发人员下载代码即文档/ 根据文档将环境搭建成功
3) 团队一般会给你讲讲项目相关的支持
----
4) 你接到第一个需求(或者某个功能,一般要经过沟通,分析,设计...等过程)
5) 创建feature分支(一般一个需求对应一个feature,命名格式上标注该需求的id)
6) 开发需求,本地测试,提交代码到当前需求对应的feature分支,
一般来讲为了避免将测试代码提交,需要提交前,检查如下步骤
6.1) 是否多提交了某个文件,比如测试文件
6.2) 是否漏提交文件
6.3) 打开每一个应该提交的文件,判断是否多提交了一行代码,是否少提交了一行代码,是否删除了本应该存在的代码
检查完毕提交代码
7) 合并分支至test分支-- 测试人员会在test分支中测试
8) 测试人员测试bug ,开发者在feature分支上继续修改,提交
9) 测试人员测试通过 ,test分支会被测试人员合并到develop开发分支,再次测试
10)develop分支最终会被合并到master主分支
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
概述
Git介绍
- Git是分布式版本控制系统
- 集中式VS分布式,SVN VS Git
- SVN和Git主要的区别在于历史版本维护的位置
- Git本地仓库包含代码库还有历史库,在本地的环境开发就可以记录历史而SVN的历史库存在于中央仓库,每次对比与提交代码都必须连接到中央仓库才能进行。
- 这样的好处在于:
- 自己可以在脱机环境查看开发的版本历史。
- 多人开发时如果充当中央仓库的Git仓库挂了,可以随时创建一个新的中央仓库然后同步就立刻恢复了中央库。
Git命令
Git配置
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
2
git config
命令的--global
参数,表明这台机器上的所有Git仓库都会使用这个配置,也可以对某个仓库指定不同的用户名和邮箱地址。
创建版本库
初始化一个Git仓库
$ git init
添加文件到Git仓库
包括两步:
$ git add <file>
$ git commit -m "description"
2
git add
可以反复多次使用,添加多个文件,git commit
可以一次提交很多文件,-m
后面输入的是本次提交的说明,可以输入任意内容。
查看工作区状态
$ git status
查看修改内容
$ git diff
$ git diff --cached
$ git diff HEAD -- <file>
git diff
可以查看工作区(work dict)和暂存区(stage)的区别git diff --cached
可以查看暂存区(stage)和分支(master)的区别git diff HEAD -- <file>
可以查看工作区和版本库里面最新版本的区别
查看提交日志
$ git log
简化日志输出信息
$ git log --pretty=oneline
查看命令历史
$ git reflog
版本回退
$ git reset --hard HEAD^
以上命令是返回上一个版本,在Git中,用HEAD
表示当前版本,上一个版本就是HEAD^
,上上一个版本是HEAD^^
,往上100个版本写成HEAD~100
。
回退指定版本号
$ git reset --hard commit_id
commit_id是版本号,是一个用SHA1计算出的序列
工作区、暂存区和版本库
工作区:在电脑里能看到的目录;
版本库:在工作区有一个隐藏目录.git
,是Git的版本库。
Git的版本库中存了很多东西,其中最重要的就是称为stage(或者称为index)的暂存区,还有Git自动创建的master
,以及指向master
的指针HEAD
。
进一步解释一些命令:
git add
实际上是把文件添加到暂存区git commit
实际上是把暂存区的所有内容提交到当前分支
撤销修改
丢弃工作区的修改
$ git checkout -- <file>
该命令是指将文件在工作区的修改全部撤销,这里有两种情况:
- 一种是file自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
- 一种是file已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
丢弃暂存区的修改
分两步: 第一步,把暂存区的修改撤销掉(unstage),重新放回工作区:
$ git reset HEAD <file>
第二步,撤销工作区的修改
$ git checkout -- <file>
小结:
当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令
git checkout -- <file>
。当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令
git reset HEAD <file>
,就回到了第一步,第二步按第一步操作。已经提交了不合适的修改到版本库时,想要撤销本次提交,进行版本回退,前提是没有推送到远程库。
删除文件
$ git rm <file>
git rm <file>
相当于执行
$ rm <file>
$ git add <file>
2
进一步的解释
Q:比如执行了rm text.txt
误删了怎么恢复?
A:执行git checkout -- text.txt
把版本库的东西重新写回工作区就行了
Q:如果执行了git rm text.txt
我们会发现工作区的text.txt也删除了,怎么恢复?
A:先撤销暂存区修改,重新放回工作区,然后再从版本库写回到工作区
$ git reset head text.txt
$ git checkout -- text.txt
2
Q:如果真的想从版本库里面删除文件怎么做?
A:执行git commit -m "delete text.txt"
,提交后最新的版本库将不包含这个文件
远程仓库
创建SSH Key
$ ssh-keygen -t rsa -C "youremail@example.com"
关联远程仓库
$ git remote add origin https://github.com/username/repositoryname.git
推送到远程仓库
$ git push -u origin master
-u
表示第一次推送master分支的所有内容,此后,每次本地提交后,只要有必要,就可以使用命令git push origin master
推送最新修改。
从远程克隆
$ git clone https://github.com/usern/repositoryname.git
标签
tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
新建一个标签
$ git tag <tagname>
命令git tag <tagname>
用于新建一个标签,默认为HEAD,也可以指定一个commit id。
指定标签信息
$ git tag -a <tagname> -m <description> <branchname> or commit_id
git tag -a <tagname> -m "blablabla..."
可以指定标签信息。
PGP签名标签
$ git tag -s <tagname> -m <description> <branchname> or commit_id
git tag -s <tagname> -m "blablabla..."
可以用PGP签名标签。
查看所有标签
$ git tag
推送一个本地标签
$ git push origin <tagname>
推送全部未推送过的本地标签
$ git push origin --tags
删除一个本地标签
$ git tag -d <tagname>
删除一个远程标签
$ git push origin :refs/tags/<tagname>
版本管理
仓库管理
- 创建repository,mkdir/pws
- 初始化:git init
- 添加:git add
- 提交:git commit (
git commit
命令,-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录) - 要随时掌握工作区的状态,使用
git status
命令。如果git status
告诉你有文件被修改过,用git diff
可以查看修改内容 git log
命令显示从最近到最远的提交日志; +"--pretty=oneline"简化输出- git reset --hard 🆔
git reflog
用来记录你的每一次命令,用于版本回退
分支管理
创建分支
$ git branch <branchname>
1查看分支
$ git branch
1git branch
命令会列出所有分支,当前分支前面会标一个*号。切换分支
$ git checkout <branchname>
1创建+切换分支
$ git checkout -b <branchname>
1合并某分支到当前分支
$ git merge <branchname>
1删除分支
$ git branch -d <branchname>
1查看分支合并图
$ git log --graph
1当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。用
git log --graph
命令可以看到分支合并图。普通模式合并分支
$ git merge --no-ff -m "description" <branchname>
1因为本次合并要创建一个新的commit,所以加上
-m
参数,把commit描述写进去。合并分支时,加上--no-ff
参数就可以用普通模式合并,能看出来曾经做过合并,包含作者和时间戳等信息,而fast forward合并就看不出来曾经做过合并。保存工作现场
$ git stash
1查看工作现场
$ git stash list
1恢复工作现场
$ git stash pop
1丢弃一个没有合并过的分支
$ git branch -D <branchname>
1查看远程库信息
$ git remote -v
1在本地创建和远程分支对应的分支
$ git checkout -b branch-name origin/branch-name,
1本地和远程分支的名称最好一致;
建立本地分支和远程分支的关联
$ git branch --set-upstream branch-name origin/branch-name;
1从本地推送分支
$ git push origin branch-name
1如果推送失败,先用git pull抓取远程的新提交;
从远程抓取分支
$ git pull
1如果有冲突,要先处理冲突。
gitignore
技巧1:优化配置
Git 在全局、用户和本地级别上都是高度可配置的。
查找顺序
每个设置都可以被覆盖:
本地级别:
项目文件夹/.git/config
用户级别:
用户目录/.config/git
用户目录/.gitconfig
全局级别:
git目录/etc/gitconfig
2
3
4
5
6
7
修改配置
## 全局设置
git config --global <keypath> <value>
## 本地设置
git config <keypath> <value>
2
3
4
显示当前设置
## 显示当前设置及其来源
git config --list --show-origin
2
一些有用的配置
## 设定身份
git config --global user.name"<your name>"
git config --global user.email <your email>
2
3
技巧2:别名(alias)
创建别名来保存常用的git命令:
## 创建别名
git config --global alias.<alias-name> "<git command>"
## 使用别名
git <alias-name> <more optional arguments>
2
3
4
一些有用的别名
## 撤销上次提交
git config --global alias.undo "reset --soft HEAD^"
## 将暂存区更新修订到上次提交 (不改变提交信息)
git config --global alias.amend "commit --amend --no-edit"
## 压缩的状态输出
git config --global alias.st "status -sb"
## 用 GRAPH 为日志着色
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'"
## 删除所有已合并的分支
git config --global alias.rmb "!git branch --merged | grep -v '*' | xargs -n 1 git branch -d"
## 贡献排行
git config --global alias.rank "shortlog -n -s --no-merges"
2
3
4
5
6
7
8
9
10
11
12
技巧 3:查找 Commits 和更改
通过commits信息查找
## 通过 commit 信息查找 (所有分支)
git log --all --grep='<search term>'
## 通过 commit 信息查找 (包含 reflog)
git log-g --grep='<search term>'
2
3
4
通过更改查找
## 通过更新的内容查找
git log -S '<search term>'
2
通过日期查找
## 通过日期范围查找
git log --after='DEC 152019' --until='JAN 102020'
2
技巧4:添加hunk
git add
## 补丁命令
y = 暂存区块
n = 不暂存这个区块
q = 退出
a = 暂存当前文件的此区块以及所有剩余区块
d = 不暂存当前文件的此区块以及所有剩余区块
/ = 查找区块 (正则表达式)
s = 划分成更小的区块
e = 手动编辑区块
? = 打印帮助说明
g = 选择要前往的区块
j = 将区块设为未定,查看下一个未定区块
J = 将区块设为未定,查看下一个区块
k = 将区块设为未定,查看上一个未定区块
J = 将区块设为未定,查看下一个区块
2
3
4
5
6
7
8
9
10
11
12
13
14
15
技巧 5: 储藏(stash)更改而不提交
stash 将当前的更改临时搁置起来。在它的帮助下,可以返回当前状态的索引,并能在稍后应用已储藏的更改。
默认情况下,仅储藏当前跟踪文件中的更改,新文件将被忽略。
我们可以独立地创建和应用多个 stash。
创建
## 创建新的 STASH
git stash
## 创建新的 STASH (包含未追踪的更改)
git stash -u/--include-untracked
## 创建新的 STASH 并命名
git stash save"<stash name>"
## 交互式储藏
git stash -p
2
3
4
5
6
7
8
罗列
## 列出所有的 STASH (为其他命令提供 "n")
git stash list
2
浏览
## 浏览 STASH 内容
git stash show
## 浏览 STASH 差异
git stash show -p
2
3
4
应用
## 应用上一个 STASH (删除 stash)
git stash pop
## 应用上一个 STASH (保留 stash)
git stash apply
## 应用特定的 STASH (n = stash 列表序号)
git stash pop/apply stash@{n}
## 从 STASH 创建新的分支 (n = stash 列表序号)
git stash branch <newbranch name> stash@{n}
## 从 STASH 应用单个文件 (n = stash 列表序号)
git checkout stash@{n} -- <filepath>
2
3
4
5
6
7
8
9
10
清理
## 删除特定的 STASH (n = stash 列表序号)
git stash drop stash@{n}
## 删除所有的 STASH
git stash clear
2
3
4
技巧 6:空运行(Dry Run)
许多 git 操作可能具有破坏性,例如, git clean -f 将删除所有未跟踪的文件,而且无法恢复。
要避免出现这种灾难性的结果,许多命令都支持 dry-run ,可以在实际产生结果前对其进行检查。不过遗憾的是,使用的选项不完全一致:
git clean -n/--dry-run
git add -n/--dry-run
git rm -n/--dry-run
# GIT MERGE 模拟 DRY-RUN
git merge --no-commit --no-ff <branch>
git diff --cached
git merge --abort
2
3
4
5
6
7
技巧 7:安全强制推送
在处理旧的 commit、创建新的 head 等情况时时很容易弄乱分支。 git push --force 可以覆盖远程变更,但不应该这样做!
git push --force 是一种具有破坏性且危险的操作,因为它无条件生效,并且会破坏其他提交者已经推送的所有 commit。这对于其他人的代码仓库来说不一定是致命的,但是改变历史记录并影响其他人并不是一个好主意。
更好的选择是使用 git push --force-with-lease 。
git 不会无条件地覆盖上游的远程仓库,而是检查是否有本地不可用的远程更改。如果有,它会失败并显示一条“stale info”消息,并告诉我们需要先运行 git fetch 。
技巧 8:修改 commit 信息
Commit 是不可变的,且不能更改。不过可以用一条新的 commit 信息修订现有的 commit,这会覆盖原始 commit,因此请勿在已推送的 commit 中使用它。
git commit --amend -m "<new commit message>"
技巧 9:修改历史
修改代码仓库的历史不仅限于修改上次提交信息,使用 git rebase 可以修改多个提交:
## 提交的范围
git rebase -i/--interactive HEAD~<number of commits>
## 该 hash 之后的所有提交
git rebase -i/--interactive <commit hash>
2
3
4
在配置的编辑器中倒序列出所有的 commit,像这样:
#<command><commit hash><commit message>
pick5df8fbc revamped logic
pick ca5154e README typos fixed
pick a104aff added awesome new feature
2
3
4
通过更改编辑器中的实际内容,可以为 git 提供一个方案,来说明如何进行 rebase:
# p, pick = 使用提交而不更改
# r, reword = 修改提交信息
# e, edit = 编辑提交
# s, squash = 汇合提交
# f, fixup = 类似 "squash",但是会丢弃提交信息
# x, exec = 运行命令 (其余行)
# d, drop = 移除提交
2
3
4
5
6
7
保存编辑器后,git 将运行该方案以重写历史记录。
e, edit 会暂停 rebase,就可以编辑代码仓库的当前状态。完成编辑后,运行 git rebase --continue 。
如果过程中出现问题(例如合并冲突),我们需要重新开始,可以使用 git rebase --abort 。
技巧 10:存档跟踪文件
可以使用不同格式( zip 或 tar )来压缩特定引用的跟踪文件:
git archive --format<format> --output<filename> <ref>
git-archive (opens new window)
额外提醒:单破折号
有一个快捷方式可以表示刚用过的分支:一个单破折号 -
git checkout my-branch
## 当前分支:my-branch
<dosome git operations, e.g. adding/commiting>
git checkout develop
## 当前分支:develop
git merge -
## 将 my-branch 合并到 develop
2
3
4
5
6
7
单破折号等同于 @{-1} 。
[git-checkout](
Reference
[Git Pro](
`