- 通过
git int
把目录变成Git可以管理的仓库。 - 所有的版本管理系统,其实只能跟踪文本文件的改动,比如txt、网页、程序代码等。
- 强烈建议使用标准的utf-8编码,不要用windows自带的记事本编辑任何文本,要用utf-8 without BOM。
一.创建版本库
1.1.创建空目录
|
|
1.2.把目录变成Git可以管理的仓库
|
|
会看到该目录下生成.git的目录
1.3.把文件添加到仓库
|
|
可反复多次使用,添加多个文件
1.4.把文件提交到仓库
|
|
-m “xxx"本次提交的说明,commit可以一次提交很多文件。
二.时空穿梭
查看仓库当前状态
git status
查看具体修改内容
git diff 要查看的文件
diff就是difference的缩写。
2.1.版本回退
2.1.1.命令查看提交日志
|
|
退出按 Q 觉得输出信息太多,可以加参数
|
|
一大串xxxxxxxxxxx
是commin id(版本号)
。HEAD
是当前版本;HEAD^
是上一版本;HEAD^^
是上上版本;上100版本,用HEAD~100
。
查看文件版本
|
|
2.1.2.版本回退
用git reset
|
|
回退到上一版本。同时会修改工作区的文件。
2.1.3取消版本回退
如果命令窗口还没关闭,往回拉,找到commit_id版本号:
|
|
如果命令窗口已经关了,查看命令历史,找到版本号:
|
|
(ps:git base 按两下tab会有命令提示)
2.2.工作区、暂存区和master分支
一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:
|
|
|
|
可以查看工作区和版本库最新版的区别。
2.3.撤销修改
2.3.1.工作区
|
|
暂存区已提交,就回到暂存区状态;未提交暂存区,就回到版本库的状态。
其中--
很重要。
2.3.2.暂存区
把暂存区撤销,放回工作区
|
|
然后把工作区撤销
|
|
2.4.删除文件
删除本地文件
|
|
删除版本库文件,并且提交
|
|
如果是删错了,恢复到版本库
|
|
git checkout
实际上是用版本库替换工作区,无论是修改还是删除,都可以还原。
三.远程仓库
创建ssh key
ssh-keygen -t rsa -C “youremail@example.com”
测试ssh
|
|
3.1.添加远程库
关联本地仓库
git remote add origin git@github.com:example/example
如果报错
|
|
只要先删除,再添加:
|
|
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
把本地库的所有内容推送到远程库上:
git push -u origin master
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
从现在起,只要本地作了提交,就可以通过命令:
|
|
3.2.从远程库克隆
|
|
四.分支管理
4.1.创建与合并分支
通过指针的变化
首先,我们创建dev分支,然后切换到dev分支:
git checkout -b dev
git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
|
|
用git branch命令查看当前分支,当前分支前面会标一个*号:
$ git branch
*dev
master分支的提交
切换回主分支
git checkout master
把dev分支的工作成果合并到master分支上:
git merge dev
git merge命令是合并指定分支到当前分支。
删除dev分支
git branch -d dev
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。
可以用git push origin :dev 删除远程分支dev。
4.2.解决冲突
当两条分支对同一个文件的同一个文本块进行了不同的修改,并试图合并时,Git不能自动合并的,称之为冲突(conflict)。解决冲突需要人工处理。
dev分支和master分支有不同提交
这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。
- git status也可以告诉我们冲突的文件,«««<,=======,»»»>标记出不同分支的内容。
对于简单的合并,手工编辑,然后去掉这些标记,最后像往常的提交一样先add再commit即可。
- 用git log –graph命令可以看到分支合并图
- 注意分支和分支并不是完完全全的平行.在切换分支前, 一定要在做出改动的分支将改动提交, 否则可能会将改动带到切换到的分支, 产生误会. 只要提前提交了, 改动就不会带过去。
- 其实多个分支是共用暂存区的,也就是说如果在分支1上仅add而不commit,实际暂存区中已经记录该次修改。哪怕后续切换到分支2上再进行commit也是有效的操作,只不过已经不是自己想要的处理。
- 合并如果没有冲突出现也就是自动合并成功, 则在当前分支中不需要add/commit提交合并后的内容, 因为实际上当前分支在合并成功后就指向了最近的commit(由做出改动的分支提交)。
4.3.分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
|
|
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
查看分支历史
|
|
在实际开发中,应该按照几个基本原则进行分支管理:
master
分支应该是非常稳定的,仅用来发布新版本,平时不在上面干活;
dev
分支是不稳定的,发布版本时,把dev
分支合并到master
上,发布1.0版本。
每个人都有自己的分支,时不时地往dev
上合并。
4.4.Bug分支
当前工作到一般还不能提交,但是又要修复bug添加bugfix分支,可以用stash
存储工作状态。
|
|
现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。
修完bug,回到原来分支,用git status list
查看存储状态。用git stash apply
恢复,git stash drop
清空。或者用git stash pop
一步完成。
|
|
4.5.Feature分支
添加实验性功能时,不希望乱七八遭的代码把主分支打乱,最好添加feature分支,在上面开发,完成后合并、删除。
4.6.多人协作
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
要查看远程库的信息,用git remote:
|
|
或者,用git remote -v显示更详细的信息:
|
|
并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
master分支是主分支,因此要时刻与远程同步;
dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:
|
|
现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程。
小伙伴已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送,失败。
小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送。
|
|
git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,先设置dev和origin/dev的链接,再pull:
|
|
多人协作的工作模式通常是这样:
首先,可以试图用git push origin branch-name推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!
如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch –set-upstream branch-name origin/branch-name。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
五.标签管理
tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
5.1.创建标签
切换到需要打标签的分支上:
|
|
给master分支打上了v1.0的标签。
查看所有标签:
|
|
以前的commit忘记打标签了,需要找到commit id:
|
|
找到id比如是xxx
打上标签
|
|
注意,标签不是按时间顺序列出,而是按字母排序的。可以用git show
|
|
还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字
|
|
用命令git show
|
|
还可以通过-s用私钥签名一个标签:
|
|
签名采用PGP签名,因此,必须首先安装gpg(GnuPG),如果没有找到gpg,或者没有gpg密钥对,就会报错。
5.2.操作标签
如果标签打错了要删除:
|
|
因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使用命令git push origin
|
|
或者,一次性推送全部尚未推送到远程的本地标签:
|
|
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
|
|
然后,从远程删除。
|
|
要看看是否真的从远程库删除了标签,可以登陆GitHub查看。