1. Git是什么?
Git是目前世界上最先进的分布式版本控制系统(没有之一)
2. 安装Git
2.1 linux安装Git
debian或者Ubuntu Linux:sudo apt-get install git
如果是其他linux版本,可以直接通过源码安装。先从Git官网下载源码,解压,依次输入:./config
, make
, sudo make install
2.2 Windows上安装Git
可以从官网上直接下载安装程序,默认安装即可,安装完成会有Git Bash,类似一个linux命令行的窗口
3. 设置
安装完成进行如下设置$ git config --global user.name "your name"
$ git config --global user.email "email@example.com"
4. 创建版本库
找到一个合适的地方,创建一个空的文件夹mkdir learngit
cd learngit
pwd
通过git init 命令把这个目录编程Git可以管理的仓库git init
会生成一个.git的目录
5.把文件添加到版本库
先创建一个文本文件如readme.txt,里面内容如下it is a git test
将文件添加到仓库git add readme.txt
然后执行git commit 将文件提交到仓库git commit -m "add readme.txt"
通过命令git status可以查看仓库的当前状态
6. 查看修改的内容
修改文件readme.txt里的内容,执行git add
和git commit
然后通过git diff
可以查看修改的内容
7. 版本回滚
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commint_id
穿梭前,可以用git log查看提交的历史,以便确定要回退到哪个版本
要重返未来,用git reflog查看历史命令,一边确定回到未来的哪个版本
8.工作区和暂存区
8.1 工作区
就是在自己电脑里能看到的目录
8.2 版本库
工作区有一个隐藏目录.git,这一个不算工作区,而是Git的版本库
将文件网版本库里提交的时候,分两步执行
第一步:git add将文件添加进去,实际上就是把文件修改添加到暂存区
第二步:git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
9. 管理修改
Git跟踪并管理的是修改,而不是文件
所以每次修改之后都要在提交前执行git add,如果git add之后,再修改文件git commit,第二次修改的内容将丢失
10. 撤销修改
未执行git add之前可以使用git status查看,并执行git checkout -- file 可以丢弃工作区的修改
如$ git checkout -- readme.txt
如果执行了git add之后,再未提交之前,使用git reset HEAD
如 git reset HEAD readme.txt
11 删除文件
在Git中,删除也是一个修改操作,我们添加一个新文件test.txt到Git并且提交
执行rm test.txt
这个时候,执行git status
查看,会告诉我们哪些文件被删除了
现在可以有两个选择,一是确定从版本库中删除该文件git rm test.txt
并且执行git commit
, 文件就从版本库中删除了
如果想恢复,可以执行git checkout -- text.txt
从版本库中恢复
12. 远程仓库
GitHub提供Git仓库托管服务,先注册的一个GitHub账号
12.1 创建SSH Key
在用户主目录下执行ssh-keygen -t rsa -C "email@example.com"
会生成一个.ssh目录,里面有id_rsa和id_rsa.pub两个文件
12.2登陆GitHub,打开“Account settings”, "SSH Keys"
点击“Add SSH Key”,填上任意Title,在key文本框里粘贴id_rsa.pub文件的内容,点击“Add Key”
12.3 创建一个远程的仓库
登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库例如spider
然后再本地执行命令git remote add origin git@github.com:chenliang1995/spider.git
添加成功后,需要执行git push origin master
把本地master分支的最新修改推送至GitHub
如果报错为Permanently added the RSA host key for IP address '13.229.188.59' to the list of known hosts
需要将13.229.188.59 github.com
添加到/etc/hosts中(linux)或者/c/windows/system32/drivers/etc/hosts(windows)
如若报错为refusing to merge unrelated histories
可以使用命令git pull origin master -allow-unrelated-histories
强制将文件拉取到本地仓库,再推送到远程仓库上
12.4 从远程克隆
假若本地没有仓库,可以从远程克隆git clone git@github.com:chenliang1995/spider.git
同时,GitHub支持https,类似https://github.com/chenliang1995/spider.git
这样的地址
13 分支管理
13.1 创建与合并分支
- 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点
- 每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。
- 当我们创建一个新的分支,例如dev是,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。
- 不过从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变。
- 假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并。
合并分支后,甚至可以删除dev分支,删除dev分支就是把dev指针给删掉,删除后,我们就剩下一个master分支了
具体操作实战:
- 首先,我们创建一个dev分支,然后切换到dev分支
git checkout -b dev
这条命令相当于git branch dev
和git checkout dev
-b参数表示创建并切换 git branch
查看当前分支
列出所有分支,当前分支前面会标有一个*号- 修改分支上的文件并提交
比如我们对readme.txt进行修改,加上一行Creating a new branch is quick
然后提交git add readme.txt
git commit -m "branch test"
- 查看master分支
现在,dev分支上的工作完成,我们就可以切换回master分支git checkout master
可以发现文件readme.txt添加的内容不见了,因为刚才提交的是在dev分支上,而master分支此可的提交点并没有发生改变
5 合并
现在我们把dev分支的工作成果合并到master分支上git merge dev
这个命令用于合并指定分支到当前分支上,合并后,再查看readme.txt的内容,可以看到,和dev分支的提交是完全一样的 - 删除分支
合并完成后,就可以放心的删除分支dev了git branch -d dev
删除后执行git branch
查看分支,发现只剩下一个master分支
由于创建、合并和删除分支非常快,所以Git鼓励使用分支完成某个任务,合并后再删除分支,这和直接在master分支上工作效果是一样的,但更加安全
13.2 解决冲突
有时候,合并分支会出现异常比如:
- 我们准备一个新的分支
git chechout -b featurel
修改readme.txt最后一行,改为Creating a new branch featurel
在分支feature1分支上提交git add readme.txt
- 切换到master分支
git checkout master
在master分支上把readme.txt文件的最后一行改为Creating a new branch is quick & simple
提交git add readme.txt
git commit -m "& simple"
3 合并git merge featurel
这种情况下,Git无法执行‘快速合并’,只能试图把各自的修改合并器来,但这种合并就可能有冲突,
此时需要我们进行手动解决git status
可以告诉我们冲突的文件 - 修改master分支下readme.txt
Creating a new branch featurel
再提交git add readme.txt
git commit -m "conflict fixed"
完成,git log --graph --pretty=oneline --abbrev-commit
可以查看合并情况 - 删除分支featurel分支
git branch -d featurel
工作完成
所以当Git无法自动合并分支是,就必须首先解决冲突,解决冲突后,再提交,合并完成,
用git log --graph
命令可以看到合并图
13.3 分支管理策略
git merge dev
Git会用Fast foward模式,但这种模式下,删除分支后,会丢失分支信息
如果要强制禁用Fast foward模式,Git就会再merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息git merge --no-ff -m "merge with no-ff" dev
因为合并要创建一个新的commit,所以加上-m参数,把commit描述写进去
13.4 bug分支
- 当我们接到一个bug时,工作只进行到了一半,还没办法提交,预计完成还需一天时间,但是,必须再两个小时内修复该bug,怎么办?
- Git提供了一个stash功能,可以把当前工作现场“储存”起来,等以后恢复现场后继续工作
git stash
- 现在,用
git status
查看工作区,就是干净的(除非没有被Git管理的文件),因此可以放心的创建分支来修复bug - 首先确定在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支
git checkout master
git checkout -b issue-101
- 现在修复bug,需要把redme.txt种的修改,然后提交
git add readme.txt
git commit -m "fix bug 101"
- 修复完成后,切换到master分支,并完成合并,最后删除issue-101分支
git checkout master
git merge --no-ff -m "merged bug fix 101" issue-101
- 可以了,bug修复完成,接着回到dev分支上干活
git checkout dev
git status
- 工作区时干净的,刚才的工作现场存到哪去了?用
git stash list
命令看看git stash list
- 工作现场还在,Git把stash内容存在某个地方了,但是需要修复一下,有两个办法
一是用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除
另一种方法是用git stash pop
,恢复的同时把statsh内容也删除
再用git stash list
查看,就看不到任何stash内容了 - 你可以多次stash,恢复的时候,先用
git stash list
查看,然后恢复指定的stash,用命令git stash apply stash@{0}
13.5 Feature分支
软件开发种,总有无穷无尽的新的功能要不断添加进来,没添加一个新的功能,我们会新建一个分支,在上面开发,文成后,合并,最后,删除该feature分支。
当新建的分支提交之后准备合并时,如果不需要这个新功能,我们在执行git branch -d feature
时,Git会提醒,如果删除,将丢失修改,
此时我们 需要执行git branch -D feature
来进行强制删除
13.6 多人协作
- 当我们从远程克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名字时origin
要查看远程库的信息,用git remotegit remote
或者用git remote -v
显示更详细的信息git remote -v
上面显示了可以抓取和推送的origin的地址,如果没有推送权限,就看不到push的地址 - 推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上git push origin master
如果要推送其它分支,比如dev,就改成git push origin dev
- 但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要?
mster分支是主分支,因此要时刻与远程同步
dev分支是开发分支,团队所有队员都需要在上面工作,所以也需要与远程同步
bug分支只要与在本地修复bug,就没必要推到远程了
feature分支是否推到远程,取决于你和你的小伙伴合作在上面开发
13.7 抓取分支
多人协作时,大家都会往master和dev分支上推送各自的修改
现在,模拟一个你的小伙伴在另一台电脑或者同一台电脑的另一个目录下克隆git clone git@github.com:chenliang1995/spider.git
当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master分支
现在,你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支git checkout -b dev origin/dev
现在,他就可以在dev上继续修改,然后,时不时把dev分支push到远程git add env.txt
git commit -m "add env"
当他已经向origin/dev分支推送了他的提交时,而碰巧你也对同样的文件做了修改,并视图推送git add env.txt
git commit -m "add new env"
git push origin dev
推送失败,因为你的小伙伴的最新提交和你视图推送的提交有冲突,此时我们可以用git pull
把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送git pull
失败了,根据提示,设置dev和origin/dev的链接git branch --set-upstream-to=origin/dev dev
再pullgit pull
返回git pull成功,但是合并有冲突,需要手动解决,解决后,再push
14 标签管理
14.1 创建标签
git中打标签非常简单,首先切换到需要打标签的分支上git checkout master
然后敲命令git tag <name>
就可以打一个新的标签git tag v1.0
可以用命令git tag
来查看标签
默认标签是打在最新提交的commit上的,有时候,如果忘了打标签,可以通过提交的commit id打git log --pretty=oneline --abbrev-commit
git tag id
还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字git tag -a v0.1 -m "version 0.1 released" id
注意,标签总是和某个commit挂钩,如果这个commit既出现在master分支,又出现在dev分支,那么这两个分支上都可以看到这个标签
14.2 操作标签
如果标签打错了,也可以删除git tag -d v0.1
如果要推送某个标签到远程git push origin <tagname>
或者,一次性推送全部尚未推送到远程的本地标签git push origin --tags
如果标签已经推送到远程,要删除远程标签就得先从本地删除git tag -d v0.9
然后从远程删除git push origin :refs/tags/v0.9
查看是否真的从远程库中删除了标签,可以登陆GitHub查看