注:摘抄于廖雪峰老师网站:https://www.liaoxuefeng.com
一.git来源
Linus在开发Linux后,就管理各地志愿者发给他的源代码非常麻烦,他需要手工合成,不愿意选择CVS、SVN这些免费的版本控制系统管理(Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用,有一些好用的又是收费的,违背伟大思想开源),在10年之久,代码量发展到了很大,很难有手工管理,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统,开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。然后Linux就自己花了两周时间用C写了一个分布式版本控制系统,就是Git。
二.集中式和分布式对比
集中式版本控制系统,版本库是集中放在中央服务器的,自己干活时用的是自己的电脑,需要先从服务器上取得最新的版本,然后干活,在把自己的活提交给服务器。
集中式版本控制系统最大的毛病就是必须联网才能操作,如果是在局域网内还好,带宽够大,速度够快,但是如果是互联网,网速慢的话就非常花时间。
而分布式版本控制系统,分布式版本控制系统没有“中央处理器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上,而同时协作只需要把各自的修改推送给对方就行了。分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了,而集中式版本控制系统只要中央处理器出问题,就不能工作了。在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。Git的优势不单是不必联网这么简单,Git还有极其强大的分支管理。
三.Git安装
注:如果是Centos的Linux版本,则安装需要yum install git
四.Git的使用
1.创建版本库:
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
#和Linux一样,创建目录 mkdir testgit #进入目录 cd testgit #通过git init命令把这个目录变成Git可以管理的仓库 #目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了 #如果看不到 ls -ah git init
2.git add text.txt:
用命令git add告诉Git,把文件添加到仓库
3.git commit -m "succecess"(可以提交多个文件):
用命令git commit告诉Git,把文件提交到仓库,解释一下git commit
命令,-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
嫌麻烦不想输入-m "xxx"
行不行?确实有办法可以这么干,但是强烈不建议你这么干,因为输入说明对自己对别人阅读都很重要。实在不想输入说明的童鞋请自行Google,我不告诉你这个参数。
4.git reset --hard:
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD
指针
HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
。(还可以git reset --hard Head^,回退前一个版本,Head^^前两个,Head~100前100个)
穿梭前,用git log(可以加参数--pretty=oneline变成一行)
可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog
查看命令历史,以便确定要回到未来的哪个版本
5.工作区和暂存区:
git status:查看状态
6.git diff HEAD -- readme.txt:
查看工作区和版本库里面最新版本的区别.
Git是如何跟踪修改的,每次修改,如果不用git add
到暂存区,那就不会加入到commit
中。
7.git checkout -- file
可以丢弃工作区的修改:
git checkout -- file
命令中的--
很重要,没有--
,就变成了“切换到另一个分支”的命令.
git reset HEAD <file>
可以把暂存区的修改撤销掉(unstage),重新放回工作区,git reset
命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD
时,表示最新的版本
注:(已经提交了可以版本回退 git reset --hard Head^等)
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>
,就回到了场景1,第二步按场景1操作。
8.git rm:
命令git rm
用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容
9.git remote add origin
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git
;[如git remote add origin git@LYQCOOL:/test.git]
关联后,使用命令git push -u origin master
第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master
推送最新修改;
分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!
10.git clone:
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone
命令克隆。
Git支持多种协议,包括https
,但通过ssh
支持的原生git
协议速度最快
11.创建与合并分支:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
12.合并冲突:
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用git log --graph
命令可以看到分支合并图。
13.分支管理策略:
合并分支时,加上--no-ff
参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward
合并就看不出来曾经做过合并。
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本;
所以,团队合作的分支看起来就像这样:
14.Bug分支:
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash
一下,然后去修复bug,修复后,再git stash pop
,回到工作现场(还可以用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除)。
15.Feature分支:
开发一个新feature,最好新建一个分支;
如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>
强行删除
16.多人协作:
查看远程库信息,使用git remote -v
;
本地新建的分支如果不推送到远程,对其他人就是不可见的;
从本地推送分支,使用git push origin branch-name
,如果推送失败,先用git pull
抓取远程的新提交;
在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name
,本地和远程分支的名称最好一致;
建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name
;
从远程抓取分支,使用git pull
,如果有冲突,要先处理冲突。
17.Rebase:
rebase操作可以把本地未push的分叉提交历史整理成直线;
rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
18.创建标签:
命令git tag <tagname>
用于新建一个标签,默认为HEAD
,也可以指定一个commit id;
命令git tag -a <tagname> -m "blablabla..."
可以指定标签信息;
命令git tag
可以查看所有标签。
19.管理标签:
命令git push origin <tagname>
可以推送一个本地标签;
命令git push origin --tags
可以推送全部未推送过的本地标签;
命令git tag -d <tagname>
可以删除一个本地标签;
命令git push origin :refs/tags/<tagname>
可以删除一个远程标签
20.忽略特殊文件:
忽略某些文件时,需要编写.gitignore
;
.gitignore
文件本身要放到版本库里,并且可以对.gitignore
做版本管理!