stay hungry stay foolish

git学习笔记

版本库

工作区有一个隐藏目录.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'不能通过。

合并冲突

当在masterdev分支上都对同一文件进行了修改,则合并的时候可能产生冲突,此时不能再用快速合并,需要先手动修改,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

  • 当本地有未pushcommit,此时如果远程仓库的版本比本地的版本要新,pull时会发生merge,并针对此merge生成相应的commitId
  • 如果远程仓库的版本比本地的版本要新,此时push会失败,提示需要先pull
  • commit了一次以后,此时如果你没有pull,则会提示你ahead of ‘远程分支’ by 1 commits,但是如果你本地版本不是最新的,你pull以后会发生merge,该merge会生成相应的commitId,此时本地的HEAD是改mergecommitId,每merge一次,提示的超前版本数量会增加一。