一、版本控制
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。
Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。
对于任何一个文件,在 Git 内都只有三种状态:
已提交(committed):表示该文件已经被安全地保存在本地数据库中
已修改(modified):表示修改了某个文件,但还没有提交保存
已暂存(staged):表示把已修改的文件放在下次提交时要保存的清单中。
文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库
Git目录:每个项目都有一个 Git 目录(译注:如果git clone出来的话,就是其中.git的目录;如果gitclone --bare的话,新建的目录本身就是 Git 目录。),它是 Git 用来保存元数据和对象数据库的地方。该目录非常重要,每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。
工作目录:从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录。这些文件实际上都是从 Git 目录中的压缩对象数据库中提取出来的,接下来就可以在工作目录中对这些文件进行编辑。
暂存区域:只不过是个简单的文件,一般都放在 Git 目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。
基本的 Git 工作流程如下:
1. 在工作目录中修改某些文件。(已修改状态)
2. 对修改后的文件进行快照,然后保存到暂存区域。(已暂存状态)
3. 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。(已提交状态)
二、常见git命令
1.查看是否安装git:$git
2.初始化Git仓库:
$ mkdir learngit
$ cd learngit
$ pwd
/
Users/michael/learngit
$git init 将这个目录变成git可以管理的本地仓库
3.工作区与暂存区
工作区:电脑里看到的目录
版本库:工作区内的隐藏目录.git
暂存区:版本库里称为stage的区域
版本库里还有git自动创建的第一个分支master,以及指向master的一个指针HEAD。
4.添加文件到git仓库,分两步:
第一步:使用命令git add<file> ,可多次使用,添加多个文件(将文件修改保存在暂存区)
第二部:使用命令git commit-m "update cases",完成(将暂存区的内容提交到当前分支)
需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有
5.查看仓库当前状态,是否有文件修改过:git status
6.查看修改的内容:git diff e.g. git diffreadme.txt
查看工作区和版本库里面最新版本的区别
7.查看修改日志:git log (在每个修改log前的一串十六进制数为版本号commit_id)
8.git版本回退
HEAD指向的版本就是当前版本,HEAD^表示上个版本,HEAD^^表示上上个版本,HEAD~100表示往上100个版本
git切换到某个版本使用命令:git reset --hard commit_id 或 git reset --hard HEAD~x(回退)
若不记得版本号,可使用查看历史命令:gitreflog (位于每行开头的字符串为版本号)
9.撤销修改
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令gitcheckout -- file
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令gitreset HEAD file
,就回到了场景1,第二步按场景1操作
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,可使用版本回退git reset --hard commit_id,前提是没有推送到远程库
10.删除文件
当工作区与版本库文件不一致,即工作区中部分文件已删除时,使用git status命令可以查看哪些文件被删除了
如果要在工作区恢复文件,使用:git checkout -- file。即用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”
如果要从版本库删除文件,使用:git rmfile。再使用:git commit提交,文件可以从版本库删除
11.远程仓库---GitHub使用
本地git与GitHub之间传输通过SSH加密,需要设置SSH
第1步:创建SSH Key。
在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C youremail@example.com
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。
如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:
然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容。
在github上建立仓库,将本地仓库与之关联
gitremote add origin git@github.com:Ann-pai /testingstudy.git
添加后,远程库的名字就是origin,这是Git默认的叫法
把本地库的所有内容推送到远程库:git push -u origin master
第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令:git push origin master
在初始化的时候,如果点击了最下面那初始化一个readme.md文件,会导致的push失败,使用git pull --rebaseorigin master这句话会把这个文件更新下来,再次提交就行了。
12.分支管理
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
解决冲突:修改冲突文件后保存,重新git add 以及commit
查看分支合并情况:git log --graph --pretty=oneline --abbrev-commit
开发一个新feature,最好新建一个分支,如果要丢弃一个没有被合并过的分支,可以通过gitbranch -D <name>强行删除
13.分支合并详述(历史有分支)
合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,如图所示,而fast forward合并就看不出来曾经做过合并
e.g.git merge --no-ff -m "merge with no-ff" dev
--no-ff参数,表示禁用Fast forward,本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去
14.分支策略
实际开发中,分支管理的几个原则:
(1)master分支应该非常稳定,仅用来发布新版本
(2)开发都在dev分支,该分支不稳定,到发布日期时,将dev分支合并到master分支
(3)每个人都有自己的分支,开发完合并到dev分支
15.保存工作现场
储藏当前工作现场:git stash(即存在未提交内容)
此时,使用git status查看工作区,被储藏的内容不会显示,可创建分支,进行其他操作,在完成其他操作后,可恢复这部分内容,继续工作。
恢复方式:
(1)使用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除
(2)用git stash pop,恢复的同时把stash内容也删了
gitstash list 可查看储藏的工作现场
可使用命令:git stash apply stash@{0} 恢复指定的工作现场
16.多人协作
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
要查看远程库的信息,用git remote
用git remote -v显示更详细的信息,如果没有推送权限,就看不到push的地址
推送分支:git push origin master git push origin dev
抓取分支:git clone
在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致
多人协作,git push产生冲突,推送失败解决办法:
(1)先用git pull把最新的提交从仓库抓下来,然后,在本地合并,解决冲突,再推送。
(2)如果git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:gitbranch --set-upstream dev origin/dev
(3)再次git pull,这回gitpull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,add 、commit提交,再push。
总结:
多人协作的工作模式通常是这样:
(1)首先,可以试图用git push originbranch-name推送自己的修改;
(2)如果推送失败,则因为远程分支比你的本地更新,需要先用gitpull试图合并;
(3)如果合并有冲突,则解决冲突,并在本地提交;
(4)没有冲突或者解决掉冲突后,再用git pushorigin branch-name推送就能成功!
如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令:git branch --set-upstream branch-name origin/branch-name
17.标签管理
首先,切换到需要打标签的分支上,然后,敲命令:git tag <name>就可以打一个新标签;
可以用命令:git tag 查看所有标签,默认标签是打在最新提交的commit上的;
使用:git show <tagname>查看标签信息
也可以使用历史提交的commit id来打标签。 使用命令:git log --pretty=oneline--abbrev-commit 找到commit id,使用命令:git tag <name> <commit id>
还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
$git tag -a v0.1 -m "version 0.1 released" 3628164
删除标签(本地):git tag -d v0.1
推送某个标签到远程,使用命令:git push origin <tagname>
一次性推送全部尚未推送到远程的本地标签:git push origin --tags
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:git tag -d v0.9。然后,从远程删除:git push origin:refs/tags/v0.9
18.其他设置
配置别名:git config --global alias.co checkout
忽略特殊文件:将需要忽略的文件名写入.gitignore文件中,提交到git
如果要添加被忽略的文件,使用命令:git add -f App.class 强制添加