一、前言:
关于git的学习最早是来源于廖雪峰帅哥的官网,通俗易懂,场景众多。不过最近在掘金上看了一个帅哥的文章,感觉十分惊艳,决定结合廖帅哥的文章,写一点点东西。
二、git优势:
为什么使用git?
没有什么特殊的目的,就是觉得用指令行敲命令的姿势很帅。
当然这只是我一个人的想法:
大多人的想法其实是:
1、适合分布式开发;
2、速度快, 成熟的架构,开发灵活;
3、任意两个开发者之间可以很容易的解决冲突;
4、离线工作,管理代码成本低,不需要依赖服务器;
5、良好的分支机制,可以让主干代码保持干净。
向大佬致敬:
Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。
Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。
三、git怎么用?
一张图就能看明白:
了解下面这4个专有名词。
Workspace:工作区
你项目在理电脑所在的位置。
Index / Stage:暂存区
.git目录下的index文件, 暂存区会记录git add添加文件的相关信息(文件名、大小、timestamp...),不保存文件实体, 通过id指向每个文件实体。可以使用git status查看暂存区的状态。暂存区标记了你当前工作区中,哪些内容是被git管理的。
当你完成某个需求或功能后需要提交到远程仓库,那么第一步就是通过git add先提交到暂存区,被git管理。
Repository:仓库区(或本地仓库)
git commit后同步index的目录树到本地仓库
Remote:远程仓库
这个就复杂了,有可能是服务器也有可能是托管地址。总之就是你远程项目托管的地方。
看明白之后,带你起飞:
git的一切从仓库开始:
仓库又称为版本库;英文名repository;有了它,你的文件就可以被git追踪。
创建一个空仓库:
mkdir learngit (创建一个learngit的空目录)
cd learngit (进入这个创建的目录)
git init (把这个空目录变成可以管理的空仓库)
填充这个空仓库1(把文件添加到暂存区):
git add file.txt(把文件添加到仓库)
有以下几种用法:
git add . 添加当前目录的所有文件到暂存区
git add [dir] 添加指定目录到暂存区,包括子目录
git add [file1] 添加指定文件到暂存区
填充这个空仓库2(将暂存区的内容提交到本地仓库,-m后面是本次提交的声明):
git commit -m "wrote a file"(-m后面是本次提交的声明)
有以下几种用法:
git commit -m [message]
提交暂存区到本地仓库,message代表说明信息
git commit [file1] -m [message]
提交暂存区的指定文件到本地仓库
git commit --amend -m [message]
使用一次新的commit,替代上一次提交
add和commit做了什么?
如图可以看出:
add将工作区修改的内容提交到暂存区,交由git管理。
commit将暂存区的内容提交到本地仓库,并使得当前分支的HEAD向后移动一个提交点。
HEAD是什么?
HEAD,它始终指向当前所处分支的最新的提交点。你所处的分支变化了,或者产生了新的提交点,HEAD就会跟着改变。
那么可能会问分支是什么?
branch(分支)即是一个平行空间:
你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
他有以下几种使用方式:
git branch
列出所有本地分支
git branch -r
列出所有远程分支
git branch -a
列出所有本地分支和远程分支
git branch [branch-name]
新建一个分支,但依然停留在当前分支
git checkout -b [branch-name]
新建一个分支,并切换到该分支
git branch --track [branch][remote-branch]
新建一个分支,与指定的远程分支建立追踪关系
git checkout [branch-name]
切换到指定分支,并更新工作区
git branch -d [branch-name]
删除分支
git push origin --delete [branch-name]
删除远程分支
创建分支就要合并分支(merge)
merge命令把不同的分支合并起来。如上图,在实际开放中,我们可能从master分支中切出一个分支,然后进行开发完成需求,中间经过R3,R4,R5的commit记录,最后开发完成需要合入master中,这便用到了merge。
git fetch [remote]
merge之前先拉一下远程仓库最新代码
git merge [branch]
合并指定分支到当前分支
一般在merge之后,会出现conflict,需要针对冲突情况,手动解除冲突。主要是因为两个用户修改了同一文件的同一块区域。如下图所示,需要手动解除。
版本回退(reset)
reset命令把当前分支指向另一个位置,并且相应的变动工作区和暂存区。
git reset —soft [commit]
只改变提交点,暂存区和工作目录的内容都不改变
git reset —mixed [commit]
改变提交点,同时改变暂存区的内容
git reset —hard [commit]
暂存区、工作区的内容都会被修改到与提交点完全一致的状态
git reset --hard HEAD
让工作区回到上次提交时的状态
上传本地仓库到远程仓库分支,实现同步:
git push [remote][branch] 上传本地指定分支到远程仓库
git push [remote] --force 强行推送当前分支到远程仓库,即使有冲突
git push [remote] --all 推送所有分支到远程仓库
实际工作中的场景:
分支管理策略
创建分支dev:
git checkout -b dev
并提交一个新的commit:
git add readme.txt
git commit -m "add merge"
切换回master:
git checkout master
合并dev分支,请注意--no-ff参数,表示禁用Fast forward:
git merge --no-ff -m "merge with no-ff" dev
git log看看分支历史:
bug分支:
git stash
把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
git status
查看工作区,就是干净的
git checkout master
回到主分支建立临时的bug分支
git checkout -b issue-101
git add
git commit -m
切换到master分支,并完成合并,最后删除issue-101分支:
git checkout master
git merge --no-ff -m "merged bug fix 101" issue-101
回到dev分支
git checkout dev
用git stash list命令看看:
git stash list
一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
另一种方式是用git stash pop,恢复的同时把stash内容也删了:
再用git stash list查看,就看不到任何stash内容了
多人协作:
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
要查看远程库的信息,用git remote:
用git remote -v显示更详细的信息:
上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
$ git push origin master/dev
抓取分支
$ git clone git@github.com:michaelliao/learngit.git
当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master分支。
git branch
- master
你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:
$ git checkout -b dev origin/dev
此时你进行代码提交结果push推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送: git pull
git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:
git pull
这回git pull
成功,但是合并有冲突,需要手动解决。解决后,提交,再push;
最后一步,献上学习的链接:
图文并茂,通俗易懂的掘金作者:
https://juejin.im/post/599e14875188251240632702?from=%E6%96%87%E7%AB%A0%E9%A1%B5%E5%86%85%E9%93%BE%E6%8E%A5
廖帅哥:
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000