Git详细教程与使用
1.常见代码托管服务
-
github :面向开源及私有软件项目的托管平台,只支持Git作为唯一的版本库格式进行托管
-
码云 :国内代码托管平台,服务器在国内,因此相比github,速度更快
-
GitLab :用于仓库管理系统的开源项目,用Git作为代码管理工具,并在此基础上搭建起来的web服务器
2.Git与SVN区别
**SVN:**集中版本控制系统,版本库集中放在中央服务器;开发人员从中央服务器下载最新版本,开发后将自己的代码提交到中央服务器;
缺点:服务器单点故障(服务器出现问题,开发环境都无法正常使用);容错性差;
**Git:**分布式版本控制系统,(Distributed Version Control System,DVCS),分为本地仓库和远程仓库;
本地仓库:开发人员电脑上的Git仓库;
远程仓库:远程服务器上的Git仓库;
Clone 克隆,将远程仓库复制到本地;
Push 推送,将本地仓库代码上传到远程仓库;
Pull 拉取,将远程仓库代码下载到本地仓库。
区别:
1、Git 是分布式的,SVN 不是:Git 和其它非分布式的版本控制系统(SVN,CVS 等)最核心的区别。
2、Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。
3、Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
4、Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
5、Git 的内容完整性优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JhdxD8rS-1603884530273)(C:%5CUsers%5Casus%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200820230436436.png)]
3.Git安装
1.Linux平台上安装
Git 的工作需要调用 curl,zlib,openssl,expat,libiconv 等库的代码,所以需要先安装这些依赖工具。
在有 yum 的系统上(比如 Fedora)或者有 apt-get 的系统上(比如 Debian 体系),可以用下面的命令安装:
各 Linux 系统可以使用其安装包管理工具(apt-get、yum 等)进行安装:
- Debian/Ubuntu Git 安装命令为:
$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
libz-dev libssl-dev
$ apt-get install git
$ git --version
git version 1.8.1.2
- Centos/RedHat 安装命令为:
$ yum install curl-devel expat-devel gettext-devel \
openssl-devel zlib-devel
$ yum -y install git-core
$ git --version
git version 1.7.1
- 源码安装
在官网下载源码包来安装
安装指定系统的依赖包:
########## Centos/RedHat ##########
$ yum install curl-devel expat-devel gettext-devel \
openssl-devel zlib-devel
########## Debian/Ubuntu ##########
$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
libz-dev libssl-dev
解压安装下载的源码包:
$ tar -zxf git-1.7.2.2.tar.gz
$ cd git-1.7.2.2
$ make prefix=/usr/local all
$ sudo make prefix=/usr/local install
2.Windows平台上安装
官网下载安装包并运行即可;
- Git GUI :Git提供的图形界面工具;
- Git Bash :Git提供命令行工具。
4.Git配置
1.配置文件
git config 工具专门用来配置/读取相应的工作环境变量。这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。而这些变量可存放三个不同的地方:
/etc/gitconfig
文件:系统中对所有用户都普遍适用的配置。git config --system
读写这个文件。~/.gitconfig
文件:用户目录下的配置文件只适用于该用户。git config --global
读写这个文件。- 当前项目的 Git 目录中的配置文件(工作目录中的
.git/config
文件):只针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以.git/config
里的配置会覆盖/etc/gitconfig
中的同名变量。
在 Windows 系统上,Git 会找用户主目录下的 .gitconfig 文件。主目录即 $HOME 变量指定的目录,一般都是 C:\Documents and Settings$USER。
Git 还会尝试找寻 /etc/gitconfig 文件,只不过看当初 Git 装在什么目录,就以此作为根目录来定位。
2.配置个人的用户名称和电子邮件地址:
git config --global user.name "runoob"
git config --global user.email test@runoob.com
如果用了 --global
,更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。
如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
3.文本编辑器
设置Git默认使用的文本编辑器, 一般可能会是 Vi 或者 Vim。如果你有其他偏好,比如 Emacs 的话,可以重新设置:
git config --global core.editor emacs
4.差异分析工具
在解决合并冲突时使用哪种差异分析工具,比如要改用 vimdiff 的话:
git config --global merge.tool vimdiff
Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,opendiff 等合并工具的输出信息。你也可以指定使用自己开发的工具。
5.查看配置信息
检查已有的配置信息
git config --list 命令
git config user.name 命令,直接查阅某个环境变量的设定
显示内容:
http.postbuffer=2M
user.name=runoob
user.email=test@runoob.com
runoob
有时候会看到重复的变量名,说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig), Git 实际采用的是最后一个。
这些配置我们也可以在 ~/.gitconfig 或 /etc/gitconfig 看到,如下所示:
vim ~/.gitconfig
显示内容:
[http]
postBuffer = 2M
[user]
name = runoob
email = test@runoob.com
个人账户:(个人账户信息存储在:C:\Users\asus\ .gitconfig中)
user.name=liupcoder
user.email=LiuP@QQ.com
5.Git工作流程
- 从远程仓库中克隆代码到本地仓库作为工作目录;
- 在克隆的资源上添加或修改文件;
- 如果其他人修改了,你可以更新资源;
- 提交前查看修改,将代码提交到暂存区;
- 提交代码到本地仓库,本地仓库中保存修改的各个历史版本;
- 修改完成后,如果发现错误,可以撤回提交并再次修改并提交。需要和团队共享代码时,将代码push到远程仓库。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ltU7rXVW-1603884530275)(C:%5CUsers%5Casus%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200820231711397.png)]
6.本地仓库
- **工作区:**包含.git文件夹的目录,主要用于存放开发的代码;
- 暂存区:(.git文件夹中的index文件就是暂存区,也可叫做stage,暂存区用来临时保存修改文件的地方;(二进制的),暂存区有时也叫作索引(index);
- 版本库:.git隐藏文件夹就是版本库,版本库中存储很多配置信息、日志信息和文件版本信息。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vIffsPaP-1603884530277)(C:%5CUsers%5Casus%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200821142119174.png)]
基本步骤:
-
图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage, index),标记为 “master” 的是 master 分支所代表的目录树。
-
“HEAD” 实际是指向 master 分支的一个"游标"。图示的命令中出现 HEAD 的地方可以用 master 来替换。
-
objects 标识的区域为 Git 的对象库,位于 “.git/objects” 目录下,里面包含创建的各种对象及内容。
-
当对工作区修改(或新增)的文件执行 “git add” 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
-
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
-
当执行 “git reset HEAD” 时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
-
当执行 "git rm --cached " 命令时,会直接从暂存区删除文件,工作区则不做出改变。
-
当执行 “git checkout .” 或者 "git checkout – " 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
-
当执行 “git checkout HEAD .” 或 "git checkout HEAD " 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
7.创建仓库
-
创建本地仓库:
git init
初始化仓库;生成.git的隐藏文件夹;git init newrepo
指定目录下创建; -
git add *.c
告诉 Git 开始对这些文件进行跟踪;将文件加入暂存区,跟踪状态文件变为已跟踪转态; -
git commit -m '初始化版本日志'
将暂存区中的文件修改提交到本地仓库;(文件加入暂存区后才能提交); -
git clone 远程仓库地址 ( https://gitee.com/liu_peng_nb/LpRepository01.git )
从远程仓库克隆;git clone <repo> <directory>
克隆到指定文件夹;
几种效果等价的git clone
写法:
git clone http://github.com/CosmosHua/locate new
git clone http://github.com/CosmosHua/locate.git new
git clone git://github.com/CosmosHua/locate new
git clone git://github.com/CosmosHua/locate.git new
git clone 时,可以所用不同的协议,包括 ssh, git, https 等,其中最常用的是 ssh,因为速度较快,还可以配置公钥免输入密码。各种写法如下:
git clone git@github.com:fsliurujie/test.git --SSH协议
git clone git://github.com/fsliurujie/test.git --GIT协议
git clone https://github.com/fsliurujie/test.git --HTTPS协议
8.基本操作指令
-
git status
命令:进入某个本地仓库后,查看里面文件当前的状态;(git status -s 简洁查看)文件状态:
M
文件发生了修改;??
为untracked 未跟踪状态(未被纳入版本控制);A
为tracked 已跟踪状态(被纳入版本控制);- unmodified 未修改状态;
- modified 已修改状态;
- staged 已暂存状态
D
本地手动删除了该文件;AM
已加入到缓存后,又有改动;
-
git diff
查看执行git status
的结果的详细信息;(显示已写入缓存与已修改但尚未写入缓存的改动的区别)- 尚未缓存的改动:
git diff
- 查看已缓存的改动:
git diff --cached
- 查看已缓存的与未缓存的所有改动:
git diff HEAD
- 显示摘要而非整个 diff:
git diff --stat
- 尚未缓存的改动:
-
git reset abc.txt
(git reset HEAD abc.txt
):将跟踪转态文件转回未跟踪转态(取消已缓存的内容); -
git rm abc.txt
删除文件;只是删除工作区中的文件,本地仓库中并没有删除;需要加入到缓存区中,再提交才能删除;- 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项
-f
,git rm -f <file>
- 如果把文件从暂存区域移除,但仍然希望保留在当前工作目录中,(仅从跟踪清单中删除),使用 --cached 选项,
git rm --cached <file>
- 进入某个目录中执行此语句,会递归删除该目录下的所有文件和子目录和文件:
git rm –r *
- 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项
-
git mv
命令用于移动或重命名一个文件、目录、软连接;如:git mv README README.md
-
git log
查看日志记录;敲回车不断查看,最后q退出页面;git log --oneline
查看简洁版;git log --graph
查看历史中什么时候出现了分支、合并;git log --reverse
逆向显示所有日志;git log --reverse --oneline
;git log --author
只查找指定用户的提交日志git log --author=Linus --oneline -5
git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges
指定日期;
-
将文件添加到忽略列表:一般需要Git管理代码和页面,其他都不用,所以其他文件可加入忽略列表;在工作目录中创建一个.gitignore文件(文件名固定),列出要忽略的文件;(Windows中不支持创建该文件,使用命令,模拟的是Linux系统;)
touch .gitignore
9.分支管理
使用分支可以从开发主线上分离开来,在不影响主线的同时继续工作。
创建分子命令:git branch (branchname)
列出在本地的分支:git branch
切换分子:git checkout (branchname)
切换分支的时,Git 会用该分支的最后提交的快照替换你的工作目录的内容, 所以多个分支不需要多个目录。
合并分支命令:git merge
创建新分支并立即切换到该分支下:git checkout -b (branchname)
删除分支:git branch -d (branchname)
10.Git标签
-
发布一个版本时,通常先在版本库中打一个标签(tag),这样就唯一确定了打标签时刻的版本。无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
-
Git 的标签虽然是版本库的快照,但其实它就是指向某个 commit 的指针(跟分支很像,但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
git tag v1.0
:打上标签
-a 可选项:创建一个带注解的标签, 记录这标签是啥时候打的,谁打的,会让你添加个标签的注解。
git tag -a v1.0
Git 会打开你的编辑器,让你写一句标签注解。
git tag -a v0.9 85fc7e7
发布的版本忘记打标签,可以追加标签;
git tag
查看所有标签;
指定标签信息命令:git tag -a <tagname> -m "runoob.com标签"
git tag -d v1.1
删除标签;
git show v1.0
查看此版本修改的内容;
11.远程仓库:
1.添加远程仓库:
-
git remote add <shortname> <url>
添加一个新的远程git仓库,同时指定一个可引用的缩写;(shortname默认习惯使用origin) -
ssh-keygen -t rsa -C "youremail@example.com"
生成SSH Key,SSH加密的key; -
GitHub中,点击头像旁的三角》Settings》左边选择SSH and GPG keys》New SSH key》随意设置标题,添加对应的key值》添加成功;
-
验证是否成功:ssh -T git@github.com ;(对应的邮箱)
-
创建新的远程仓库;
-
git remote rm
名称 移出一个远程仓库;(远程仓库依然存在,只是移出在本地仓库中的内容)(此名称是查看远程仓库信息时显示的)
注:一个本地仓库可以添加多个远程仓库;
2.提取远程仓库:
-
从远程仓库下载新分支与数据:
git fetch
;执行完后需执行git merge
远程分支到你所在的分支 -
从远端仓库提取数据并尝试合并到当前分支:
git merge
-
git remote
查看远程仓库;会显示origin;git remote -v
显示具体的远程仓库地址;git remote show origin
能显示更详细的信息; -
从远程仓库中拉取和抓取:
-
git fetch origin master
从名为 origin 的远程上拉取名为master 的分支到本地分支 origin/master中,不会自动merge(合并) (手动合并:git merge origin/master
) -
git pull origin master
从远程仓库中拉取最新版本并merge到本地仓库;(如果本地仓库不是从远程克隆的,是本地创建,并且仓库中有文件,从远程仓库中拉取文件会报错:fatal:refusing to merge unrelated histories
),可在git pull 后加–allow-unrelated-histories
-
git merge origin/master
时,它的意思是合并名为 origin/master 的分支到当前所在分支
注:涉及到远程以及分支,要分开写;没有涉及远程仓库的没有直接关系;
-
3.推送到远程仓库
推送新分支与数据到某个远端仓库:git push [alias] [branch]
如:git push origin master
将 [branch] 分支推送成为 [alias] 远程仓库上的 [branch] 分支
4.删除远程仓库
git remote rm [别名]
12.分支概念
-
master :主要进行项目的发布;一般情况,不将代码提交到此分支;
-
develop :开发分支;主要是提交代码的分支;是基于master分支的一个克隆(复制);
公司一般在develop分支的基础上为每个程序员再创建的一个分支;项目经理检测合格后,才允许合并到develop分支上。
-
release :测试分支;主要进行代码的测试,是基于develop分支的克隆;
-
bugfix :修复bug的临时分支;当产品发布成功后,发现这个产品有bug,需要修复bug时,创建这个临时分支;
git branch #查看本地分支
git branch -r #查看远程分支
git checkout 分支名 #切换分支
git checkout -b 分支名 #创建分支,并且切换到该分支
13.Git工作流程
-
项目经理创建初始项目,并提交到远程仓库;
-
各组员将代码从远程仓库拉取下来;
-
本地基于master分支创建一个develop分支(master分支克隆);
git checkout -b develop #创建基于master分支的克隆的develop分支,并且切换到develop分支;
-
将本地的develop分支推送到远程仓库(Gitee)
git push origin develop
-
将本地开发好的功能推送到远程
git add . git commit -m '新增的一个实体类' git pull #拉取远程的代码;如果有冲突,进行冲突更改 git push origin develop
-
阶段性功能开发完成;
-
基于develop分支在本地创建一个release分支;
git checkout develop #选中develop分支 git checkout -b release #创建release分支,并切换到该分支
-
将release分支推送到远程
git push origin release
-
测试人员对release分支进行测试;
-
开发人员针对测试报告进行修改bug(已修复完成)
-
将修改完bug的代码提交到远程
git add . git commit -m '修改完bug' git pull git push origin release
-
合并release分支和develop分支;
#要合并那个分支时,首先要选中这个分支 git checkout develop git merge 要合并的分支名(release) #合并分支
-
将合并后的分支提交到远程;
git add . git commit -m '修改完bug' git pull git push origin develop
-
现在所有的bug修改完,并且已合并到develop分支上;
-
将develop分支内容合并到master分支,进行项目发布;
git checkout master git merge develop
-
将master分支的内容提交到远程;
git add . git commit -m '修改完bug' git pull git push origin master
-
给当前的项目打一个tag(里程碑 master)
#在本地项目库上打一个tag git tag -m '-v1.0产生研发完成' v1.0 #将这个里程碑推送到远程 git push origin v1.0
-
项目运行过程中出现bug,需要修复bug;
-
首先获得tag
git tag #获取里程碑
-
基于master创建一个(bugfix-里程碑)的版本号的bug修改分支;
git checkout master git checkout -b bugfix-v1.0 #该分支为临时分支,bug修改完成后要删除
-
将bugfix-v1.0分支推送到远程;
git push origin bugfix-v1.0
-
修改bug完成;
-
将bugfix-v1.0合并到develop分支;
git checkout develop git merge bugfix-v1.0 git push origin develop
-
将develop合并到master分支;
git checkout master git merge develop git push origin master
-
打一个新的里程碑;
git tag -m 'v1.1版本修复xxxbug完成' v1.1
-
将新的里程碑推送到远程;
git push origin v1.1
如果其中的内容如有什么错误,非常乐意各位阅读者们指出来,小编定会即使的更正。