梁山企业网站建设,wordpress 框架,wordpress媒体库略缩图,开发一个物流app需要多少钱目录 Reference前言版本控制系统Git的诞生配置Git配置用户名和邮件配置颜色配置.gitignore文件 Git的基础用法初始化仓库克隆现有的仓库添加暂存文件提交变动到仓库比较变动查看日志Git回退Git重置暂存区 Git版本管理重新提交取消暂存撤销对文件的修改 Git分支Git分支的优势Git… 目录 Reference前言版本控制系统Git的诞生配置Git配置用户名和邮件配置颜色配置.gitignore文件 Git的基础用法初始化仓库克隆现有的仓库添加暂存文件提交变动到仓库比较变动查看日志Git回退Git重置暂存区 Git版本管理重新提交取消暂存撤销对文件的修改 Git分支Git分支的优势Git的数据结构分支本质基础指令保留分支历史分支的应用策略开发策略bug分支feature分支 解决冲突 Git多人协作远程仓库推送分支抓取分支git rebase变基 Git标签标签的意义创建标签删除标签推送标签到远程 Reference
简介 - Git教程 - 廖雪峰的官方网站 (liaoxuefeng.com)
前言
为什么突然对Git这么感兴趣可能是因为在一次面试中被问到了一个我答不上来的Git相关问题那一刻我觉得这技术债得还一还了。
用了这么久的GitHub和Gitee我才意识到我对Git的理解还只是停留在表层。每天的push和pull似乎成了例行公事却很少深入思考它们背后的原理。
为什么要这么深入地研究Git真相是不论你是在日常开发中还是在技术面试中一旦展示出对Git原理和操作的娴熟掌握总能让你鹤立鸡群。想想看当别人还在用图形界面点来点去时你已经在终端里飞速敲出命令这不仅仅是效率的提升更是一种极客精神的体现。
而学习Git的过程确实也让我发现这不仅仅是一项技术更像是一门艺术什么样的天才能够设计出这么巧妙的工具原来是Linus啊那没事了
版本控制系统
版本控制是一种记录一个或若干文件内容变化以便将来查阅特定版本修订情况的系统。 有了它你就可以将选定的文件回溯到之前的状态甚至将整个项目都回退到过去某个时间点的状态你可以比较文件的变化细节查出最后是谁修改了哪个地方从而找出导致怪异问题出现的原因又是谁在何时报告了某个功能缺陷等等。
版本控制系统发展可以分为三个阶段
本地版本控制系统集中式版本控制系统分布式版本控制系统
Git属于分布式版本控制系统客户端并不只提取最新版本的文件快照 而是把代码仓库完整地镜像下来包括完整的历史记录。 这么一来任何一处协同工作用的服务器发生故障事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作实际上都是一次对代码仓库的完整备份。 Git的诞生
到 2002 年Linux 系统已经发展了十年了代码库之大让 Linus 很难继续通过手工方式管理了整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码BitKeeper 的东家 BitMover 公司也免费授权 Linux 社区使用这个版本控制系统。后来 BitMover 公司发现社区有人试图破解 BitKeeper 的协议于是 BitMover 公司收了回 Linux 社区的免费使用权。
所以Linus 花了两周时间自己用 C 写了一个分布式版本控制系统也就是 Git。
不由得佩服人家的灵感和效率
配置Git
配置用户名和邮件
安装完 Git 之后要做的第一件事就是设置你的用户名和邮件地址。 这一点很重要因为每一个 Git 提交都会使用这些信息它们会写入到你的每一次提交中不可更改
$ git config --global user.name R1ck
$ git config --global user.email xxxgmail.com配置颜色
下面的命令让 Git 显示颜色会让命令输出看起来更醒目
$ git config --global color.ui true配置.gitignore文件
有些时候你必须把某些文件放到 Git 工作目录中但又不能提交它们比如保存了数据库密码的配置文件等等就可以使用忽略特殊文件 .gitignore 来很方便的解决这个问题。
各种现成的种配置文件: https://github.com/github/gitignore
下面是一些例子
假设你在 Windows 下进行 Python 开发Windows 会自动在有图片的目录下生成隐藏的缩略图文件如果有自定义目录目录下就会有Desktop.ini文件因此你需要忽略 Windows 自动生成的垃圾文件
# Windows:
Thumbs.db
ehthumbs.db
Desktop.iniPython编译产生的.pyc、.pyo、dist等文件或目录也可以被忽略掉
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build当然我们也可以编写例外规则例如避免.*这个规则把.gitignore也排除了
# 排除所有.开头的隐藏文件:
.*
# 排除所有.class文件:
*.class# 不排除.gitignore和App.class:
!.gitignore
!App.classGit的基础用法
初始化仓库
通过git init命令可以把目录变成 Git 可以管理的仓库
$ git init同时在当前目录下多了一个.git的目录这个目录是 Git 来跟踪管理版本库的
克隆现有的仓库
当你执行 git clone 命令的时候默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。
克隆仓库的命令是 git clone url
如果你想在克隆远程仓库的时候自定义本地仓库的名字可以通过额外的参数指定新的目录名
例如下面这条命令把目标目录名变成了mydocs
$ git clone https://github.com/xxx/xxx mydocs添加暂存文件
用命令git add可以告诉 Git把指定文件添加到暂存区域
$ git add readme.txt我们可以通过git add .将当前目录下的所有文件添加到暂存区域
提交变动到仓库
用命令git commit告诉 Git把文件提交到仓库
$ git commit -m wrote a readme file-m后面输入的是本次提交的说明最好是有意义的
我们可以通过git add命令分多次暂存不同的文件然后通过git commit一次性整合提交到仓库
在git commit之前git add并不会向仓库中添加对象
git commit只会提交所有暂存区中的文件
比较变动
git status命令可以让我们时刻掌握仓库当前的状态显示仓库中距离上一次提交后被修改过的文件
而使用git diff 文件名则可以查看该文件中的具体修改
一般来说我们在add完所有文件后可以通过git status来确保仓库的状态、查看是否有修改错的文件
查看日志
git log会显示出每一个commit版本、作者以及说明 而git log --prettyoneline则会显示得更简洁和整齐只包含commit版本和说明
Git回退
在 Git 中用HEAD表示当前版本也就是最新的提交 上一个版本就是HEAD上上一个版本就是HEAD^ 往上n个版本可以写作HEAD~n
当我们希望将版本回退到上一个版本则可以使用git reset命令
$ git reset --hard HEAD^Git重置
git reflog用来记录我们的每一次命令 当我们不希望再回退到上一个版本时可以通过git reflog命令找到回退之前的的commit id并使用git reset --hard 具体的id来恢复 暂存区 工作区有一个隐藏目录.git其中存放了暂存区stage以及版本库
git add命令实际上就是把要提交的所有修改放到暂存区Stage然后执行git commit就可以一次性把暂存区的所有修改提交到分支。
Git版本管理
重新提交
如果你在最后一次提交后意识到忘记添加了某些更改git commit --amend 允许你修正这个错误。这个命令会重新提交暂存区中的文件更新上一次的提交。
新的提交将代替之前提交的内容
旧有的提交在git log分支提交历史中会被删除不过仍然可以在 git reflog 中找到方便撤销
取消暂存
git reset HEAD file可以用于取消暂存将上一次通过add提交到暂存区的该文件撤销这对你想进行独立的commit提交非常有用
撤销对文件的修改
git checkout -- file会将对文件在本地的任何修改都消除掉即使该文件的修改还没有提交到暂存区 我们可以理解为该操作是将版本库中的对应文件覆盖到本地
所以该命令也可以被用于恢复本地被错删的文件
Git分支
Git分支的优势
分支用于将工作从开发主线上分离开来以免影响开发主线。在很多版本控制系统中这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。
Git 处理分支的方式可谓是难以置信的轻量创建新分支这一操作几乎能在瞬间完成并且在不同分支之间的切换操作也是一样便捷。 与许多其它版本控制系统不同Git 鼓励在工作流程中频繁地使用分支与合并哪怕一天之内进行许多次。
Git的数据结构
Git在处理分支时之所以能做到轻量与保存数据的方式有关。
在进行add暂存操作时会为每一个文件计算校验和。然后会把当前版本的文件快照会以blob对象的形式保存到 Git 仓库中而校验和则加入到暂存区域等待提交。
在进行commit提交操作时Git会为每一个子目录生成树对象该对象负责记录目录结构并保存着指向各文件快照 blob对象的索引。 接下来生成一个提交对象commit object并保存指向根目录树对象的指针当然该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。 这个父对象指的就是上一次提交时产生的提交对象。下面这张图会比较直观每一次提交产生的提交对象串成了一个链表或者说一条时间线。 分支本质
Git 的分支其实本质上仅仅是指向提交对象的可变指针。
Git 的默认分支名字是 mastermaster分支会在每次提交时自动向前移动。
一开始的时候master分支是一条线Git 用master指向最新的提交再用HEAD指向master就能确定当前分支以及当前分支的提交点
当我们创建新的分支例如v1.0时Git 新建了一个指针叫v1.0指向master相同的提交再把HEAD指向v1.0就表示当前分支在v1.0上 此时我们也可以看出Git在创建分支时并不需要拷贝原本分支的文件仅仅是添加了一个指针工作区的文件没有任何变化
删除分支时我们也只需要将指针给删掉就行
如果我们不考虑复杂的合并冲突问题当两个分支在一条时间线上时合并这两个分支要做的仅仅是将分支指针沿时间线移动
基础指令
我的git中的默认分支从master改为了main所以后文中的默认分支均用main指代
我们可以使用git branch 分支名来创建分支 并使用git checkout 分支名来切换到指定分支
或者在checkout命令后使用-b参数同时执行创建和切换
git checkout -b dev使用git branch我们还能查看一共存在哪些分支以及当前处在哪个分支当前分支前面会标一个*号
我们在dev分支上进行文件修改后如果想将dev上的修改合并到main分支可以先切回main分支并使用git merge指令 git merge指令用于合并指定分支到当前分支
git checkout main
git merge dev合并完后如果不再需要dev分支在git branch后加上-d参数即可删除指定分支
git branch -d dev当然如果我们容易将git checkout 分支名切换分支和git checkout -- file撤销修改弄混也可以用git switch来切换分支
git switch也可以通过-c参数来同时完成创建和切换的操作 保留分支历史
当我们直接用Fast forward模式合并分支后如果删除分支则会丢掉分支信息
我们可以通过--no-ff参数在合并时生成一个新的commit
这样相当于被合并的分支的指针会留在该分支的最后一个commit而Head则会执行新的commit
此时当我们使用git log --graph展示分支和合并历史时就能直观地看到时间线上有一个合并的点 分支的应用策略
开发策略
再日常开发中分支管理的基本原则如下 master分支应该是非常稳定的也就是仅用来发布新版本平时不能在上面干活 开发和更新代码都在dev分支上进行也就是说dev分支是不稳定的到某个时候比如1.0版本发布时再把dev分支合并到master上并在master分支发布1.0版本 团队成员每个人都可以从dev分支上创建属于自己的分支并将自己的修改合并到dev分支上。 bug分支
当我们需要修复bug时也可以开一个临时的分支修复完在合并并删除临时分支
当然如果手头分支的开发还没做完我们可以使用git stash将当前的工作进度存起来
等我们在主分支修完bug可以再回到自己的分支
使用git stash apply可以将工作区恢复到之前保存的工作进度当然stash里的内容还需要使用git stash drop来删除或者使用git stash pop恢复的同时把stash内容也删了
而如果我们想将主分支修复的bug补丁复制到当前分支通常自己的分支也存在同样的bug那么可以使用git cherry-pick bug分支名将修bug所做的补丁复制到当前分支而不需要merge整个主分支
当然我们也可以在自己的分支修完bug再将改动复制到主分支
feature分支
添加新功能时也可以新建一个feature分支
如果这个功能分支开发到一半不想要了可以使用git branch -D强制删除分支而不需要像-d参数只能在合并后删除分支
解决冲突 在工作中经常会出现团队成员与自己修改了dev分支的同一处文件并且改动不一致。 而且如果此时团队成员开发更快已经提前合并到dev分支上那么自己再进行合并时就会出现冲突 此时我们需要手动解决冲突后才能提交 使用git status查看出现冲突的文件 查看具体冲突文件会发现git已经自动将冲突位置标出以及冲突分支间的差异 修改完冲突即可使用commit提交并合并 当我们使用git cherry-pick命令复制提交时也可能出现代码冲突
当我们解决完冲突可以使用--continue参数让Cherry pick 过程继续执行
git cherry-pick --continueGit多人协作
远程仓库
我们使用到最多的Gir远程仓库即github它不仅仅是开源社区也通过远程仓库功能连接起不同团队成员的本地Git让团队协作变得方便
一般来说远程仓库的默认名称是origin
使用git remote -v可以查看自己绑定的远程仓库的详细信息
推送分支
推送分支使用git push指令先指定远程分支然后是被merged的本地分支
例如git push origin master
抓取分支
当我们进行推送时如果发现远程仓库已经有最新提交且存在冲突则需要先用git pull把最新的提交抓取下来在本地合并
在本地解决完冲突再使用git push origin branch-name推送 即可成功
git rebase变基
git base能通过挪动提交的位置使得分叉的提交历史整理成一条直线
Git标签
标签的意义
发布一个版本时通常先在版本库中打一个标签tag
标签与分支类似就是指向某个commit的指针
而标签的引入则是给某个commit设置一个有意义的别名方便人们根据版本快速查询commit
创建标签
首先切换到要打标签的分支上
使用git tag name就可以打一个新标签默认该标签是打在最新提交的commit上的
当然一个可以在最后指定commit id将标签打在指定commit上 例如
git tag v0.9 fb8b190用命令git tag可以查看所有标签
删除标签
使用-d参数可以删除指定标签
git tag -d name
推送标签到远程
要将特定的标签推送到远程仓库使用命令 git push origin tagname。如果你想一次性推送所有本地标签可以使用 git push origin --tags。