版本库
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git 的版本库里存了很多东西,其中最重要的就是称为stage
(或者叫index
)的暂存区,还有 Git 为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
注意事项:
- 版本回退时可能会清空暂存区
stage
里的内容 - 用
git r
删除文件时,可以删除暂存区里的文件也可以删除版本库里的文件,不过删除版本库里的文件需要commit git checkout -- file
可以把工作区的修改回退到仓库或者暂存区(如果 add 到暂存区了)
远程库
可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到 GitHub 仓库。本地库和远程库关联时,如果远程库里的文件在本地库里没有或者远程库的版本比本地的版本要新,则必须先pull
才能push
。如果是克隆下来的,则不需要再关联远程库。
分支管理
创建和合并分支
当我们创建新的分支,例如dev
,Git 新建一个指针叫dev
,指向master
相同的提交,再把HEAD
指向dev
,就表示当前分支在dev
上。
Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化。
创建dev分支,然后切换到dev分支:
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
然后,用git branch命令查看当前分支:
$ git branch
* dev
master
git branch
命令会列出所有分支,当前分支前面会标一个*号。
dev
分支的工作完成,我们就可以切换回master
分支了:
$ git checkout master
Switched to branch 'master'
然后,把dev分支的工作成果合并到master分支上:
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
git merge命令用于合并指定分支到当前分支。
注意到上面的Fast-forward
信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master
指向dev
的当前提交,所以合并速度非常快。
合并完成后,就可以放心地删除dev分支了:
$ git branch -d dev
Deleted branch dev (was fec145a).
删除后,查看branch,就只剩下master分支了:
$ git branch
* master
因为创建、合并和删除分支非常快,所以 Git 鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在 master 分支上工作效果是一样的,但过程更安全。
合并dev分支时使用--no-ff
参数,表示禁用Fast forward
:
$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
不使用Fast forward
模式,merge后就像这样:
相对于快速合并模式,该模式会生成一个记录merge
操作的commit id
,可以在git log
里查看到。不过有一种情况比较特殊:如果在有冲突的情况下,这两种其实是没区别的,因为有冲突的情况下git merge --no-ff -m 'xxx'
不能通过。
合并冲突
当在master
和dev
分支上都对同一文件进行了修改,则合并的时候可能产生冲突,此时不能再用快速合并,需要先手动修改,add后再提交。
删除分支
普通删除
git branch -d dev
强行删除
git branch -D dev
stash
stash
可以将当前的工作区保存起来,当用git stash apply
或者git stash pop
返回现场时,会发生merge
,如果文件有冲突,需要手动解决。
多人协作
查看远程库信息
git remote -v
推送信息到远程库
git push origin master
git push origin dev
关联本地分支与远程分支
git checkout -b dev
git pull origin dev
在本地新建分支并推送到远程
git checkout -b test
git push origin test //这样远程仓库中也就创建了一个test分支
克隆
git clone git@github.com:michaelliao/learngit.git
抓取分支
git checkout -b dev origin/dev
标签
Git 的标签是版本库的快照,其实它就是指向某个commit的指针,跟分支很像,但是分支可以移动,标签不能移动。
创建标签
git tag v0.1
git tag -a v0.1 -m "version 0.1 released"
查看标签列表
git tag
查看标签详情
git show v0.1
删除标签
git tag -d v0.1
删除远程标签
git push origin :refs/tags/v0.1
推送标签到远程库
git push origin v0.1
git push origin --tags //推送全部
关于git的pull与push
- 当本地有未
push
的commit
,此时如果远程仓库的版本比本地的版本要新,pull
时会发生merge
,并针对此merge
生成相应的commitId
。 - 如果远程仓库的版本比本地的版本要新,此时
push
会失败,提示需要先pull
。 commit
了一次以后,此时如果你没有pull
,则会提示你ahead of
‘远程分支’ by 1commits
,但是如果你本地版本不是最新的,你pull
以后会发生merge
,该merge
会生成相应的commitId
,此时本地的HEAD
是改merge
的commitId
,每merge
一次,提示的超前版本数量会增加一。