版本控制系统的作用
- 记录改动
- 协作编辑
Git的诞生
Linus坚决反对CVS和SVN等集中式版本控制系统(因为速度慢且需要联网)
–>BitMover公司授权Linux社区商业软件BitKeeper免费使用权
–>Linus社区牛人试图破解BitKeeper的协议被BitMover公司发现
–>BitMover公司收回Linux社区BitKeeper免费使用权
–>Linus花两周时间用C语言写出了分布式版本控制系统Git
集中式VS分布式
分布式在本地就可保存历史痕迹,不用担心污染服务器,集中式提交就到服务器了,如果提交出错就比较麻烦。
集中式版本控制系统的版本库放在中央服务器,分布式版本控制系统的版本库每个人的电脑上都有。
集中式版本控制系统必须联网才能使用,分布式版本控制系统不必联网就能使用。
分布式版本控制系统的安全性更高,分支管理特别优秀。
集中式如果单点故障,大家甚至无法提交更无法开分支。
有趣的小知识
以前软件GNU Interactive Tools也叫GIT,所以老版本Linux安装git需要使用命令sudo apt-get install git-core。
当然,之后随着Git的名气越来越大,后来GNU Interactive Tools改名成了gnuit,git-core正式改名为git。
Unix的哲学之一
“没有消息就是好消息”
Git命令行的使用
- 在git add之前可以用git diff查看指定文件具体修改内容。
- 在进行版本回退之前可以使用git log查看历史commit记录,Git的commit_id是用计算得出的哈希值表示。
- HEAD表示当前版本,HEAD^表示上一版本,HEAD^^表示上上一个版本,HEAD~100表示往上100个版本。
- 一般使用git reset –hard commit_id进行版本穿梭,此时commit_id尤其重要。
- 使用git reflog查看历史命令可以确保回退到过去版本后依然能查询到未来版本的commit_id。
- 工作区是Working Directory,版本库是Repository,暂存区是stage(或index)。
- git add把要提交的修改放到暂存区,git commit则可以一次性将暂存区的所有修改提交到分支。
- Git比其它版本控制系统优秀的其中一个原因是Git跟踪并管理的是修改,而非文件。
- git diff HEAD – <文件名>可以查看指定文件在工作区和版本库中的区别。
- 使用git checkout – <文件名>将指定文件在工作区的修改撤回,使用git reset HEAD <文件名>将指定文件提交到暂存区的修改撤回,使用git reset –hard commit_id等版本回退操作将提交到版本库的修改撤回。
- 使用rm <文件名>删除文件后,工作区和版本库就不一致了,git status就会提示我们哪些文件被删除了,如果确认在版本库中也要删除该文件则再使用git rm <文件名>。
- Git的两级提交机制是一大杀器?
- 使用git remote add origin <远程仓库URL>将本地版本库与远程仓库关联。
- git push -u origin master第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
- 因为各个分支用指针来管理,git的分支切换几乎可在瞬间完成。
- git merge <branch_name>用于合并指定分支到当前分支。
- 合并分支时有时提示Fast-forward表示此次合并是”快进模式”,也就是把分支指针移动一下。
- 因为创建、合并和删除分支非常快,所以Git鼓励使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。
- 合并对同一文件进行了不同修改的两个分支会出现冲突,此时用git status可以查看有哪些冲突的文件,之后打开对应文件会显示两个分支中该文件具体的不同。
- 解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
- git log –graph –pretty=oneline –abbrev-commit可以查看分支合并图。
- 不要使用Fast forward模式合并,这样的合并删除分支后会丢失分支信息且从合并图看不出曾经做过合并。
- 平时应该使用非”快速模式”合并分支,git merge –no-ff -m <”注释信息”> <branch_name>,注意使用这种方式在merge时生成一个新的commit,所以这样合并后就可以从历史信息中看出合并信息。
- 日常使用分支管理开发时要保证master分支是稳定只用来发布新版本,平时都不在上面干活而是在分支dev上干活之后合并。
- 创建Bug分支并修复Bug然后合并前,针对当前未完成提交的dev分支工作环境,使用git stash进行存储;创建Bug分支并修复Bug然后合并后,使用git stash list查看保存的工作环境,使用git stash pop(恢复后删除stash记录)或git stash apply <指定stash>(恢复后不删除stash记录)恢复工作环境。
- 开发一个新的feature,最好新建一个分支;如果要丢弃一个没有合并过的分支,使用git branch -D <branch_name>强行删除。
- 多人协作时一般需要向远程推送master和dev分支,Bug分支一般不需要远程推送。
- 从远程克隆仓库下来后默认只看到master分支,使用git branch -b dev origin/dev创建远程dev分支到本地进行开发。
- git pull失败原因一般是没有指定本地分支dev分支与远程origin/dev分支的链接,此时使用git branch –set-upstream-to=origin/dev dev设置它们之间链接后再git pull即可。
- push前如果git pull成功但是与当前库合并出现冲突时还是先手动处理冲突,之后再push。
- rebase操作可以把本地未push的分叉提交历史整理成直线,使查看历史提交的变化更容易?
- Git的标签实际也是指向某个commit的指针,跟分支很像但是分支可以移动,标签不行。
- tag是让人容易记住有意义的名字,他与某个commit绑在一起,但更humanity。
- 使用git tag <tag_name>默认是打在最新提交的commit上,当然也能打到指定commit上,需要在后面添加相应的commit_id。
- git show <tag_name>查看标签详情,另外由于标签总是和某个commit绑在一起,如果这个commit在两个分支都有,那两个分支都能看到该commit对应的标签。
- 命令git tag -a <tag_name> -m “blablabla…”可以指定标签信息。
- 命令git push origin <tag_name>可以推送一个本地标签;命令git push origin –tags可以推送全部未推送过的本地标签;命令git tag -d <tag_name>可以删除一个本地标签;命令git push origin :refs/tags/<tag_name>可以删除一个远程标签。
- 一个本地库关联多个远程库用git remote add多添加几个远程库URL即可。
- 可以使用git check-ignore检查.gitignore文件是否有哪条规则导致出错。