Git介绍
git 诞生: Git是目前世界上最先进的分布式版本控制系统
git诞生之前当时的CVS和SVN这些集中式的版本控制系统不但速度慢,而且必须联网才可以使用。由于代码量越来越多Linus手动管理版本的方法不再适用,
于是他就和BitMover公司合作,可以免费使用其公司的BitKeeper进行代码管理和维护。直到05年BItMover公司收回了免费授权,于是linus他们设计了git。
版本控制系统:[集中式 和 分布式 版本控制系统的区别]
- 集中式
版本库是集中存放在中央服务器的,在工作时先要从中央服务器中获得最新版本然后在开始工作,工作完再将自己的修订版本推送到中央管理的服务器上去
这类系统都是一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都是通过客户端连接这台服务器,取出最新的文件或者提交更新
- 分布式
分布式版本控制系统根本没有“中央服务器”,每人的电脑都是一个完整的版本库,这样工作时就不需要联网了,以为你的电脑上就是一个完整的版本库;
如何多人协作呢?如果两个人同时修改了A文件,只需要将自己的修改推送给对方,就可以相互看到对方修改了,实际开发中很少是两个人进行版本推送,
因为可能不在一个局域网内,也可能对方没开机,所以分布式版本控制也需要一个“中央服务器”来方便相互交换
- 优点:
- 安全性更高;因为每个人电脑上都有一套完整的版本库,如果一个人的版本库出现问题,直接从另外一个人copy一份即可。
- 不需要联网、高速易用、非线性分支管理系、分布式版本控制、安全性更高
GIt基本使用
- Git配置介绍
- 使用Git的第一件事就是设置你的名字和email,这些就是你在提交commit时的签名,每次提交记录里都会包含这些信息。使用git config命令进行配置,
- 执行了配置的命令后,会在家目录(/home/项目文件夹)下建立一个叫 .gitconfig 的文件(隐藏文件,需用 ls -al 查看)使用 vim 或 cat 查看文件内容:
- 如果想使项目里的某个值与前面的全局设置有区别(例如把私人邮箱地址改为工作邮箱),可以在项目中使用 git config 命令,不带--global 选项来设置.
- 这时会在当前的项目目录下创建 .git/config,从而仅适用针对当前项目的配置。
- Git初始化配置
- 配置格式:git config --global <配置名称> <配置的值> [Git全局配置的文件]
- 配置名字:git config --global user.name "guoyapeng"
- 配置邮箱:git config --global user.email "guoyapengls@outlook.com"
-
- 配置格式:git config <配置名称> <配置的值> [Git单项目配置的文件]
- 配置名字:git config user.name "guoyapeng"
- 配置邮箱:git config user.email "guoyapengls@outlook.com"
- Git仓库的创建
-
- 方式一
- 在github.com网站上创建一个名字为gitproject供测试用的公有远程仓库,这个远程仓库可以使用下面方式进行clone到本地
- 在本地新建的文件夹目录下clone(克隆,复制)这样就意味着本地此Git文件夹就被初始化成了一个由Git管理的本地版本仓库
- git clone https://github.com/guoyapeng/gitproject
-
- 方式二
- 把未进行版本控制的文件夹进行版本控制就就在本地初始化一个新的版本库,对一个已有的文件夹让它置于Git的版本控制管理下:
-
- 通过ls -la命令会发现gitproject目录下会有一个名叫 .git 的目录被创建,这意味着一个本地普通的文件夹就被初始化成了GIt仓库
- mkdir gitproject 创建代码目录gitproject
- cd gitproject 进到代码目录
- git init 初始化Git仓库:
- Git的提交流程
-
- 创建或修改文件在工作区
- 进入之前创建的gitproject目录下,创建三个文件:touch file1 file2 file3
- 使用 vim 编辑内容,或直接 echo 添加测试内容: echo "test" >> file1 ;echo "test" >> file2 ;echo "test" >> file3
- 查看当前Git仓库的状态
- git status 文件处于untracked状态,下一步就需要用git add命令将他们加入到缓存区(Index)
- 撤销文件修改的内容
- git checkout -- 文件名 将未添加add或未提交commit的内容撤销掉
- 如果一个文件内容第一次修改时进行了添加add,但是没有进行提交commit,
- 这时对工作区的文件内容又进行了修改,此时撤销,回到的是缓存区的状态。
- 总之就是让被撤销的文件回到最后一次被git add 或 git commit的状态上去。
- 添加修改到本地缓存区
- git add file1 file2 file3 使用 git add 命令添加新创建或修改的文件到本地的缓存区(Index)
- git add . 一次全部提交
- git status 然后再次执行 git status 查看文件状态,会发现新的变化
- 查看哪些文件被修改过
- git diff 查看修改内容
- git diff --cached
- 可以使用 git diff 命令再加上 --cached 参数,看看缓存区中哪些文件被修改,为commit做好了准备
- 进入到git diff --cached 界面后需要输入 q 才可以退出
- 如果没有--cached参数,git diff 会显示当前你所有已做的但没有加入到缓存区里的修改
- 如果还要做进一步的修改, 那就继续修改, 完成之后就把新修改的文件加入add到缓存区中
- 提交修改到本地版本库
- git commit 使用 git commit 命令提交到本地代码库。当所有新建修改的文件都被添加到了缓存区,就要使用 git commit 提交到本地仓库
- git commit -m "add 3 files" 需要使用-m添加本次修改的注释,完成后就会记录一个新的项目版本,如果不加-m参数,会进入到文件中编写注释
- git commit -a -m "add 3 files" 除了用git add命令,也可用-a参数将所有没有加到缓存区的修改一起提交,但-a命令不会添加新建的文件
- 再次输入 git status 查看状态,会发现当前的代码库已经没有待提交的文件了,缓存区已经被清空
- 注意:
- 如果是修改文件,也需要使用git add命令添加到缓存区才可以提交。
- 如果是删除文件,则直接使用git rm命令删除后会自动将已删除文件的信息添加到缓存区,git commit提交后就会将本地仓库中的对应文件删除
- 查看提交日志
- git log 查看最近到最久的提交日志,显示提交人、版本号等信息
- git log --pretty=oneline 查看最近到最久的提交日志,以一行简便方式显示
- 提交后进行版本回退
- git reset --hard HEAD^ 向前回退一个版本
- git reset --hard HEAD^^ 向前回退两个版本
- git reset --hard HEAD^^^ 想向前回退几个版本就写几个^符号
- git reset --hard HEAD~100 向前回退100个版本
- git reset --hard HEAD 具体版本号 回退到具体某个版本上
- git reflog 查看以往所有的操作记录
- 创建或修改文件在工作区
Git分支使用
Git的分支可以让你在主线(master 分支)之外进行代码提交,同时又不会影响代码库主线。分支的作用体现在多人协作开发中,
比如一个团队开发软件,你负责独立的一个功能需要一个月的时间来完成,你就可以创建一个分支,只把该功能的代码提交到这个分支,
而其他同事仍然可以继续使用主线开发,你每天的提交不会对他们造成任何影响。当你完成功能后,测试通过再把你的功能分支合并到主线。
- 创建分支
- git branch develop 创建一个新的叫 develop 的分支
- git branch 查看当前的分支列表,及目前的开发环境处在哪个分支上
- 切换分支
- master 分支是 Git 系统默认创建的主分支。星号标识当前工作在哪个分支下
- git checkout develop 切换到其他分支
- git checkout -b develop 创建并切换到develop分支上
- 合并分支
- 在子分支下做完文件修改后,再在主分支下做文件修改。两个分支都有了各自不同的修改,分支的内容都已经不同,合并会产生冲突
- 先切换到master分支后,再将develop分支合并到master。-m参数仍然是需要填写合并的注释信息
- git merge -m 'merge develop branch' develop
- 删除分支
- 当完成合并后,不再需要experimental时可以使用下面的命令删除分支
- git branch -d experimental git branch -d 只能删除那些已经被当前分支的合并的分支
- git branch –D 某分支 如果强制删除某个分支的话就用 -D
- git push orgin :分支名 删除远程分支
- git push orgin --delete 分支名 删除远程分支
- 撤销合并
- 想把当前的合并修改都放弃,可以用此命令回到合并之前的状态
- git reset --hard HEAD^
- 注意冲突
- 如果两个branch分支修改的不是同一个文件,合并时不会有冲突执行上面的命令后合并就完成了
- 如果两个branch分支修改的是同一个文件,合并时就会有冲突(比如两个分支都改了一个文件file3,则合并时会失败)
- 解决冲突
- 合并失败后先用 git status 查看状态,会发现 file3 显示为 both modified
- 也可以使用 git diff 查看,先前已经提到 git diff 不加参数可以显示未提交到缓存区中的修改内容
- 使用 vim 编辑冲突文件,去掉 Git 自动产生标志冲突的 <<<< 等符号后,根据需要只保留我们需要的内容后保存,
- 然后使用 git add file3 和 git commit 命令来提交合并后的 file3 内容,这个过程是手动解决冲突的流程。
- 推送失败时解决办法
- 如果向远程推送(push)结果不是快速向前fast forward,可能会报错误。这种情况通常是因为没有使用git pull获取远端仓库的最新更新,
- 在本地修改的同时,远端仓库已经变化了(其他协作者提交了代码),此时应该先使用 git pull 合并最新的修改后再执行 git push
- 快速向前合并
- 还有一种需要特殊对待的情况在前面没有提到。通常一个合并会产生一个合并提交(commit), 把两个父分支里的每一行内容都合并进来。
- 但是如果当前的分支和另一个分支没有内容上的差异,就是说当前分支的每一个提交(commit)都已经存在另一个分支里了,
- Git就会执行一个快速向前(fast forward)操作;Git 不创建任何新的提交(commit),只是将当前分支指向合并进来的分支。
Github使用
本地远程关联过程
- 以方式一创建的本地仓库不需要关联远程服务器,创建时早已经自动关联好了
- 当仓库是使用git init初始化生成的本地仓库,需要将本地仓库与远程仓库关联
- 创建SSH-Key
- ssh-keygen -t rsa -C "guoyapengls@outlook.com" 创建ssh-key
- 回车后,id_rsa文件会生成到用户主目录的.ssh目录下去,回车回车
- cd ..后cd .ssh进入.ssh目录后ls,会有id_rea私钥、id_res.pub公钥两文件
- 添加公有密钥
- 在github的用户头像下拉栏中,选择settings设置,后选择SSH GPG keys
- cat id_res.pub 打印输出公钥,然后添加到github上的settings的SSH GPG keys上。
- 测试链接远程github
- ssh -T git@github.com 后第一次需要输入yes确认
- 关联远程仓库github
- git remote add origin 远程仓库地址 建立关联。注意在本地仓库的目录下执行此命令
- git remote rm origin 删除关联。注意在本地仓库的目录下执行此命令
-
- git remote add origin https://github.com/guoyapeng/learn-linux.git
- git remote add命令用于添加远程主机仓库。origin是主机名可以自定义
本地远程分支关联
- 创建本地分支关联远程
- git checkout dev1 origin/dev1 创建本地分支dev1,并且关联上远程分支dev1
- git checkout -b dev2 origin/dev2 创建并切换到本地分支dev2,并且关联上远程分支dev2上
- 本地推送到远程
- 注意:首先需要将远程仓库中的内容下拉下来,才可以再推送上去
- 拉取:git pull origin master --allow-unrelated-histories 解决本地库和远程库不一样的问题
- 推送:git push origin master 如果不是推送到远程的master分支,直接在后面写上相应分支名
- 真实开发连接远程
- 真实开发中,一开始是没有本地库的,应该优先创建的是远程库。就不需要对本地和远程进行手动关联了
- 从远程克隆:git clone 远程仓库地址
Git标签管理
发布一个版本时我们通常先在版本库中打一个标签(tag),这样就唯一确定了打标签时刻的版本,一般是在master分支做。
将来无论什么时候,取某个标签的版本就是把那个打标签的时刻的历史版本取出来,所以标签可以说是某个版本的快照。
- git tag 标签名 打标签
- git tag 查看所有标签
- git tag 标签名 commitID 指定commd id打标签
- git tag -a 标签名 -m "标签信息" 指定标签信息
- git checkout 标签名 切换到指定标签
- git show 标签名 查看说明文字
- git tag -d 标签名 删除标签
- git push orgin 标签名 推送标签到远程
- git push orgin --tags 一次性推送全部尚未推送到远程的本地标签
- 删除已经推送到远程的标签
- git tag -d 标签名 先从本地删除
- git push origin :refs/tags/biao标签名 再从远程删除
Git日志内容
- 查看日志
- git log git log 命令可以显示所有的提交(commit)。如果提交的历史纪录很长,回车会逐步显示,输入 q 可以退出
- git log v2.5.. Makefile fs/ 找出所有从 "v2.5“ 开始在 fs 目录下的所有 Makefile 的修改
- Git 会根据 git log 命令的参数,按时间顺序显示相关的提交(commit)
- git help log 查看git log 参数选项
- 日志统计
- 如果用 --stat 选项使用 git log,它会显示在每个提交(commit)中哪些文件被修改了,
- 这些文件分别添加或删除了多少行内容,这个命令相当于打印详细的提交记录 git log --stat
- 格式化日志
- 可以按你的要求来格式化日志输出。--pretty 参数可以使用若干表现格式,可用 medium,full,fuller,email 或 raw。
- 如果这些格式不完全符合你的需求, 你也可以用 --pretty=format 参数定义格式
- git log --pretty=oneline
- git log --pretty=short
- git log --graph --pretty=oneline
- --graph 选项可以可视化你的提交图(commit graph),会用ASCII字符来画出一个很漂亮的提交历史(commit history)线
- 日志排序
- 按默认情况,提交会按逆时间顺序显示,可以指定 --topo-order 参数,让提交按拓扑顺序来显示(就是子提交在它们的父提交前显示)
- git log --pretty=format:'%h : %s' --topo-order --graph 也可以用 --reverse 参数来逆向显示所有提交日志
难点对比差异
- 比较提交
- git diff 命令的作用是比较修改的或提交的文件内容
- git add * 将修改内容添加到本地缓存区,通配符可以把当前目录下所有修改的新增的文件都自动添加
- git status 查看当前修改的状态
- git diff --cached 命令的作用是缓存区内与上次提交之间的差别
- git commit -m 'update code' 提交代码
- 比较分支
- git diff master test 查看 test 分支和 master 之间的差别,可以使用 git help diff 详细查看其他参数和功能
- 更多比较选项
- 查看当前的工作目录与另外一个分支的差别。如查看与test分支的区别
- git checkout master
- git diff test
- 也可以加上路径限定符,来只比较某一个文件或目录
- git diff test file1
- 显示你当前工作目录下的 file1 与 test 分支之间的差别
- git diff test --stat --stat 参数可以统计一下有哪些文件被改动,有多少行被改动