零、Windows上安装Git
-
下载
下载地址:https://git-for-windows.github.io/
国内镜像:https://pan.baidu.com/s/1kU5OCOB#list/path=%2Fpub%2Fgit -
安装
全都下一步 -
指定user和email
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
一、版本控制
创建版本库
- 创建目录
$ mkdir learngit
$ cd learngit
$ pwd
/Users/michael/learngit
- 初始化仓库
将目录变成GIT可管理的版本仓库
生成.git目录:
这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了
$ git init
- 把文件添加到版本库
$ echo -e "Git is a version control system.
Git is free software." > readme.txt
$ git add readme.txt # 添加文件,可添加多个,之后一起提交
- 提交
$ git commit -m "wrote a readme file"
-m 添加备注
- 查看仓库状态
$ git status
- 查看文件修改内容
$ git diff readme.txt
版本回退
- 查看添加查看提交历史记录
$ git log
$ git log --pretty=oneline # 单行显示
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL # 第一段为commit id
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file
- 回退到上一个版本
$ git reset --hard HEAD^ # 上一个版本是HEAD^,上上一个版本是HEAD^^
- 回退指定版本
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:
$ git reset --hard 3628164 # 版本号没必要写全,前几位就可以了,Git会自动去找。
- 回退后恢复到下一个版本
$ git reflog # 查看历史操作命令对应的commit id
$ git reset --hard 3628164
工作区和缓存区
- 工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区 - 版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
撤销修改
-
丢弃工作区的修改
当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时
$ git checkout -- readme.txt
-
git add添加到暂存区后
$ git reset HEAD readme.txt # 回退到上一个commit的版本
$ git checkout -- readme.txt # 清空工作区的修改
删除文件
- 删除文件
$ git rm test.txt
$ git commit -m "remove test.txt"
- 误删文件恢复
误删恢复是指已经git add file添加的文件,在系统层面删除了文件,此方式恢复
git checkout -- test.txt
二、远程仓库
添加远程仓库需要在github上找到setttings点击后选择左侧导航的SSH and GPG keys添加 ssh key 公钥
添加远程库
1.关联远程仓库
origin是远程的库名,
xxx为用户名
git remote add origin https://github.com/xxx/learngit.git
- 第一次推送master分支所有内容
git push -u origin master
- d第一次之后推送
git push origin master
从远程库克隆
git clone git@github.com:michaelliao/gitskills.git # 使用ssh协议克隆,速度快推荐
or
git clone https://github.com/michaelliao/gitskills.git # 使用https协议克隆,某些只开放https端口的情况下使用
三、分支管理
创建与合并分支
- 创建分支
$ git checkout -b dev # 新建并切换分支,相当于底下两条命令
$ git branch dev
$ git checkout dev
$ git branch # 列出所有分支,*号为当前分支
$ git checkout master # 切换分支
- 合并分支
git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。
$ git merge dev # 合并dev分支
输出结果:
Updating d17efd8..fec145a
Fast-forward # Fast-forward“快进模式”,直接把master指向dev的当前提交,所以合并速度非常快。
readme.txt | 1 +
1 file changed, 1 insertion(+)
- 删除分支
$ git branch -d dev
解决冲突
两个分支提交后内容不一致,
此种情况Git无法快速合并,
如果此时合并分支会报错冲突
$ git status # 告诉我们冲突的文件
$ git log --graph --pretty=oneline --abbrev-commit # 添加,提交之后,可查看分支合并的情况
# git log --graph命令可以看到分支合并图
分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
- 实验
$ git checkout -b dev
$ git add readme.txt
$ echo "new midify" >> readme.txt
$ git commit -m "add merge"
$ git checkout master
$ git merge --no-ff -m "merge with no-ff" dev # 强制禁用Fast forward模式
# 因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
git log --graph --pretty=oneline --abbrev-commit # git log看看分支历史
- 分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
bug分支
当手头有工作没有做完,有需要有bug需要修改时
$ git stash # 当前工作现场“储藏(stash)”起来,等以后恢复现场后继续工作
切换至bug分支,bug分支新建分支修复
修复好提交bug新建的分支,切换bug分支合并
删除bug新建的分支
...
修复完毕
$ git checkout dev # 切换回原分支
$ git status # 没有原有的工作区内容
$ git stash list # 查看stash列表
$ git stash pop # 恢复的同时把stash内容也删了
or
git stash apply # 恢复工作
git stash drop # 删除stash
$ git stash apply stash@{0} # 指定stash恢复
多人协作
$ git remote # 列出远程库信息
$ git remote -v # 列出远程库详细信息
$ git push origin dev # 指定推送分支
$ git pull # 拉取当前分支最近的提交,用作发现提交冲突
$ git branch --set-upstream dev origin/dev # 用作git pull失败,没有指定本地分支与远程分支的连接使用
四、标签管理
- 创建标签
$ git branch
$ git checkout master # 切换至分支
$ git tag v1.0 # 打一个新标签
$ git tag # 列出标签列表
忘记打标签,补救措施
$ git log --pretty=oneline --abbrev-commit # 列出commit id,找到对应的commit id
$ git tag v0.9 6224937
#
$ git show v0.9 # 查看标签信息
$ git tag -a v0.1 -m "version 0.1 released" 3628164 # 创建带有说明的标签
-a指定标签名
-m指定说明文字
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a # 通过-s用私钥签名一个标签
# 签名采用PGP签名,因此,必须首先安装gpg(GnuPG),如果没有找到gpg,或者没有gpg密钥对,就会报错
# 用PGP签名的标签是不可伪造的,因为可以验证PGP签名。验证签名的方法比较复杂,这里就不介绍了。
- 操作标签
$ git tag -d v0.1 # 标签打错了,也可以删除
# 创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
$ git push origin v1.0 # 推送某个标签到远程
$ git push origin --tags # 一次性推送全部尚未推送到远程的本地标签
删除已推送到远程的标签
$ git tag -d v0.9 # 先删除本地
$ git push origin :refs/tags/v0.9 # push远程删除