1 Git概况
1.1 Git是什么
Git是什么?
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
什么是“版本控制”?
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。
Git与其他版本控制系统最主要的差异?
最主要差别在于Git对待数据的方法。直接记录快照,而非差异比较。每次提交更新或在Git中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git不再重新存储该文件,而是只保留一个链接指向之前存储的文件。Git对待数据像是一个快照流。
1.2 三个工作区域
"你的本地仓库由Git维护的三棵“树”组成。第一个是你的工作目录,它持有实际文件;第二个是暂存区(Index),它像个缓存区域,临时保存你的改动;最后是 HEAD,它指向你最后一次提交的结果。" ——《Git简明指南》
工作目录是对项目的某个版本独立提取出来的内容。 这些从Git仓库的压缩数据库中提取出来的文件,放在磁盘上供使用或修改。
暂存区是一个文件,保存了下次将提交的文件列表信息,一般在Git仓库目录中,也称为stage。
Git版本库是Git用来保存项目的元数据和对象数据库的地方。这是Git中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
对应的三种文件状态:已修改(modified)、已暂存(staged)和已提交(committed)。已修改表示修改了文件,但还没保存到数据库中。已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。已提交表示数据已经安全的保存在本地数据库中。
2 Git配置
2.1 配置用户信息
使用Git前需要配置提交时的签名,每次提交记录里都会包含这些信息。使用git config命令进行配置:
$ git config --global user.name "xxx"
$ git config --global user.email "[email protected]"
2.2 检查配置信息
当前用户的全局配置保存在~/.gitconfig文件中,修改全局配置时使用--global选项。
指定项目的配置保存在项目目录下的.git/config文件中,配置只针对当前项目生效。
检查配置可以使用 git config --list 命令来列出所有Git能找到的配置,也可以通过 git config
$ git config --list /*获取全部配置列表*/
$ git config user.name /*查看某一项配置*/
3 仓库
3.1 clone一个仓库
git clone <仓库地址> 命令可以从远程clone一个仓库,支持多种协议(如ssh://, http(s)://, git://...)
3.2 初始化一个仓库
如果要初始化一个新的仓库,首先进入项目目录,然后执行 git init
将本地仓库与远程仓库关联: git remote add origin <仓库地址>
将本地仓库同步到远端服务器:git push origin master
查看远程仓库信息:git remote -v
4 分支管理
4.1 分支概念
Git的分支可以支持在主线(master分支)之外进行代码提交,同时又不会影响代码库主线。分支的作用主要体现在多人协作开发中,团队的成员可以各自创建分支提交代码,而不会对其他人有影响,测试通过再把相关分支合并到主线。
4.2 创建分支三部曲
创建分支常用的三个命令:
git checkout -b /*本地新建并切换到新分支*/
git push origin : /*在远端建立分支*/
git branch --set-upstream-to=origin/ /*使本地分支跟踪远端分支*/
4.3 常用分支操作
查看当前所在分支:git branch
切换分支:git checkout
删除分支
① 删除本地分支
git branch -d /*注:删除分支时需切换到其他分支操作*/
tips:git branch -d只能删除那些已经被当前分支合并的分支,如果要强制删除某个分支的话使用git branch –D
② 删除远程分支
/*方法一*/ git push origin :
/*方法二*/ git push origin --delete
5 常用工作流
5.1 提交改动
- Git提交的基本流程
1、创建、修改或删除文件
2、使用git add命令添加新创建或修改的文件到本地的缓存区Index
3、使用git commit命令提交到本地代码库
4、使用git push命令将本地代码库同步到远端代码库(可选)
- 预览差异
提交改动前,可以使用git status命令查看当前git仓库的改动状态。
Untracked files —— 表示新增文件未提交至缓存区
Changes not staged for commit —— 表示修改文件未提交至缓存区
Changes to be committed —— 表示缓存区文件未提交至本地git仓库
- 提交改动到暂存区Index
git add ... /*提交指定文件到暂存区*/
git add * /*提交全部文件尚未提交的文件到暂存区*/
- 将暂存区中的文件提交到本地仓库
git commit -m "备注信息"
git commit -a -m "备注信息" /*注:除了全部暂存区中的改动,-a选项会将没有加到暂存区的“修改”也一起提交,但不会添加”新建“的文件*/
- 文件删除
如果需要删除暂存区或仓库的文件,同时本地工作区也不需要这个文件了,可以使用:
git rm
git commit -m 'delete file'
如果需要删除暂存区或仓库的文件,但本地又需要使用,只是不希望这个文件被版本控制,可以使用:
git rm --cached
git commit -m 'delete file'
5.2 撤销改动
- 修改尚未提交到暂存区,撤销本地工作区的改动
git checkout -- /*用版本库里的版本替换工作区的版本*/
- 修改已提交到暂存区,撤销暂存区和本地工作区的改动
git reset HEAD /*回退提交到暂存区的版本*/
git checkout -- /*恢复本地工作区的版本*/
- 丢弃在本地的所有改动与提交,到服务器上获取最新的版本历史,并将本地主分支指向它
git fetch origin
git reset --hard origin/master
5.3 分支回滚
- 本地版本回退
git reset --hard /*可用 git log --oneline 查看commit号*/
git reset --hard HEAD^ /*回退到上一个版本(HEAD表示当前版本,上一个版本是HEAD^,上两个版本是HEAD^^,上N个版本表示为HEAD~N)*/
- 远程版本回退
git push origin HEAD --force
-
在远程版本回退后再次回到回退之前的版本
git reflog命令可以查看所有分支的所有操作记录commit号(包括commit和reset的操作),找到reset之前的commit号即可复原
git reflog /*查看全部commit和reset操作历史*/
Tips:git reset命令后面的2种参数:"--hard"和"--soft"
这条命令默认情况下是"--soft"。执行上述命令时,这该条commit号之 后(时间作为参考点)的所有commit的修改都会退回到git缓冲区中。使用git status命令可以在缓冲区中看到这些修改。而如果加上”–hard”参数,则缓冲区中不会存储这些修改,git会直接丢弃这部分内容。
Tips:git revert和git reset的区别
git reset是直接删除指定的commit,git revert是用一次新的commit来回滚之前的commit。git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
git reset --hard只能针对本地操作,不能针对远程服务器进行同样操作。如果从本地删掉的内容没有提交到远端,则不会有副作用;如果已经提交到远端服务器,则下次本地merge远端分支时,这部分删掉的内容仍然会回来。而这个问题则可以很好的被git revert 命令解决。git revert
5.4 暂存改动
- 如果本地有代码没有提交,但是需要进行分支切换等工作,可以先把工作现场暂存起来
git stash
- 查看所有的暂存记录
git stash list
- 恢复暂存信息
方法一:
git stash apply /*恢复本地工作区的内容后,stash中内容还存在*/
git stash drop /*删除stash记录*/
注:命令后可加参数恢复指定的stash,如:git stash apply stash@{0}
方法二:
git stash pop /*恢复并删除stash记录*/
5.5 合并改动
- 更新本地仓库至最新
git pull /*该命令执行两个操作:从远程分支抓取修改的内容(git fetch),然后把它合并(git merge)到当前的分支*/
注:git fetch命令会更新远程仓库所包含分支的最新commit_id,将其记录到.git/FETCH_HEAD文件中
- 合并其他分支到当前分支
git merge /*将参数分支合并到当前所在分支*/
- 解决冲突
如果存在代码冲突则会返回以下提示:
Auto-merging filename
CONFLICT (content): Merge conflict in filename
Automatic merge failed; fix conflicts and then commit the result.
合并失败后先用git status查看状态,有冲突的文件会标识为"both modified",查看冲突文件详情。Git用<<<<<<<,=======,>>>>>>>标记出不同分支的冲突内容,手动调整代码,按需保留最终的内容,然后执行文件提交流程即可(git add → git commit → git push)
5.6 推送到远端仓库
- 推送代码到远端
git push /*若本地分支已跟踪远端分支,可直接执行git push*/
- 推送失败怎么办
如果推送结果不是fast forward,可能会报以下错误:
error: remote 'refs/heads/master' is not an ancestor of local 'refs/heads/master'.
Maybe you are not up-to-date and need to pull first?
这种情况通常是因为没有使用git pull获取远端仓库的最新更新,在本地修改的同时,远端仓库已经变化了(其他开发者提交了代码),此时应该先使用git pull合并最新的修改后再执行git push.
6 其他操作
6.1 GIT日志
- 查看日志
git log /*查看所有提交记录,默认按提交时间最近到最远排序*/
git log --oneline /*单行显示,只显示commit号和提交说明*/
git log --author= /*只看某个人的提交记录*/
git log --stat /*打印详细的提交记录,显示修改文件和增删行数信息*/
- 格式化日志
git log --pretty=oneline /*--pretty选项可以使用若干表现格式,如oneline, short, medium, full, fuller, email, raw*/
git log --graph --pretty=oneline /*--graph选项可以可视化提交图*/
6.2 代码比较
- 比较本地差异
git diff /*显示当前所有已做但没有加入到暂存区里的修改,未曾添加到索引的文件不显示*/
git diff --cached /*显示暂存区中没有提交到代码库的修改*/
- 比较不同分支
git diff /*比较两个分支HEAD节点的差异,+代表target_branch新增内容,-代表target_branch删除内容*/
tips:--stat 参数可以统计有哪些文件被改动,有多少行被改动
- 比较本地工作区与其他分支
git checkout
git diff /*以上两步实际比较的是target_branch分支本地工作区与source_branch分支HEAD的差异*/
tips:显示当前工作目录下的某一个文件与source_branch分支之间的差异:git diff
6.3 GIT标签
- 创建标签
git tag /*为某个提交记录创建一个标签,commit_id输入前几位即可*/
git tag /*如不加commid_id参数,默认标签会打在最新的commit上*/
git tag -a -m "blablabla..." /*指定标签信息*/
- 查看标签
git tag /*查看所有标签*/
git show /*查看标签详细信息*/
- 推送标签
git push origin /*推送某个标签到远程*/
git push origin --tags /*推送全部尚未推送到远程的本地标签*/
- 删除标签
删除本地标签:
git tag -d /*删除本地标签*/
删除远端标签:
git tag -d
git push origin :refs/tags/ /*删除后同步到远端*/
6.4 忽略特殊文件
如果有不需要提交到仓库的文件,可以填写到Git工作区的根目录下的.gitignore文件中,Git会自动忽略这些文件。
忽略文件的原则是:
忽略操作系统自动生成的文件,比如缩略图等
忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件
忽略带有敏感信息的配置文件,比如存放口令的配置文件
检查某文件是否被忽略:
git check-ignore -v
tips:文件被忽略后无法提交,如果想强制提交可以使用 git add -f
6.5 配置别名
为常用命令设置别名,配置后可直接用别名操作命令,如 git co master
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.st status
注:--global会记录到当前用户全局配置文件中,否则只针对当前的仓库的配置生效
6.6 获取帮助
使用Git时如果需要获取帮助,有三种方法可以找到Git命令的使用手册:
git help
git --help
man git-
7 References
- Pro Git Book
- W3C school git
- git log
- git reset