IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> git教程笔记 -> 正文阅读

[系统运维]git教程笔记

git教程:https://www.liaoxuefeng.com/wiki/896043488029600/896067008724000

下面的笔记只简单记录git的一些原理,不记录具体的命令,有需要的时候再网上查具体的执行命令。
(博客图片放在github图床上,网络能访问github的情况下才看得到图片哦)

git简介

git是一个分布式的版本控制系统,最初由Linux的作者Linus用两周时间用C语言开发出来,用于管理Linux源码,方便Linux社区的志愿者为Linux贡献代码。随后github网站上线,为所有开源项目免费提供git存储,因此一大堆开源项目逐步迁移到github中。

repository

repository即版本库/仓库,其实就是相当于一个被git管理的目录,改目录下的所有文件的新增、修改、删除等操作都会被git跟踪。

git init命令可以把一个目录变成Git可以管理的仓库,仓库下会生成一个git用于管理版本库的.git目录,其中的内容不可以手动修改,否则会破坏git仓库。创建版本库时git也自动为我们创建了一个master分支。

把文件添加到版本库

可以用git add和git commit命令把文件添加到版本库,其中git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后执行git commit就可以一次性把暂存区的所有修改提交到分支,后面可以随时回退到这个历史版本。

git跟踪并管理的是修改,而非文件。

注意git只能跟踪文本文件的变化,不能跟踪图片、视频这种二进制文件的内容变化,word文件也是二进制文件,因此也跟踪不了。

git版本

版本回退

每次commit都会产生一个历史版本,回退到之前某一个版本的方法是

git log   #查看过去版本的注释和commit id
git reset --hard commit_id  #填入commit id即可回退到对应的版本

工作区和暂存区

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cr34bm10-1639130586741)(https://raw.githubusercontent.com/zhongzhh8/Images/master/img/0.jpeg)]

我们在git目录下创建和修改文件时,都处于工作区,随后使用git add命令后,文件修改被添加到暂存区,随后可以用git commit命令将暂存区的修改提交到版本库中。注意git commit只会提交暂存区的修改,不会提交工作区的修改。

用git status命令可以看到,被git add到暂存区的文件的状态是modified,没有被git add到暂存区过的文件的状态是untraced。

git diff 看代码差异

  • 查看工作区与暂存区的差异:git diff <file>
  • 查看暂存区与上一次提交(commit)的差异:git diff --staged <file>
  • 查看已缓存的与未缓存的所有改动:git diff HEAD

撤销修改

撤销修改可以分成三个场景

场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令

git checkout -- <file>  	#注意git checkout 有--时是撤销修改,没有时是切换分支。

git checkout – 命令可以使工作区返回到上一次git add或git commit的状态(如果git add过就从暂存区恢复,如果没有git add过就从版本库中恢复)。注意删除文件也是一种修改,所以误删文件时也可以用git checkout命令恢复。

场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步

git reset HEAD <file>  #先把暂存区的修改撤销掉,重新放回工作区
git checkout -- <file> #把工作区的修改撤销掉

场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考上面版本回退的命令,不过前提是没有推送到远程库。

远程仓库

远程仓库其实就是一台机器充当服务器,所有开发者都从这个远程库里pull最新的代码,并且自己本地开发完成后,把代码push到远程库并且合并到主分支上,后续其他开发者再从主分支上拉取最新代码到本地继续开发。

对于公司而言,一般是有私有的gitlab仓库,对于个人开发者而言,大多会选用公有的github仓库,免费用户注册后就可以获得git远程仓库(但是会被公开给所有开发者)。

ssh key

由于本地git仓库和远程github仓库是通过SSH加密传输的,因此需要创建SSH key,

ssh-keygen -t rsa -C "youremail@example.com"

创建key时也不需要密码,创建完后在用户主目录里找到.ssh目录,可以看到id_rsaid_rsa.pub两个文件,它们就是SSH Key的秘钥对,id_rsa是私钥,不能泄露,id_rsa.pub是公钥,可以公开。然后登录github,在用户设置的SSH Keys处填入公钥id_rsa.pub的内容就可以了。

ssh非对称加密验证原理

参考git的ssh key使用和原理

当本地主机需要登录远程主机时,本地主机向远程主机发送一个登录请求,远程收到消息后,随机生成一个字符串并用公钥加密,发回给本地。本地拿到该字符串,用存放在本地的私钥进行解密,再次发送到远程,远程比对该解密后的字符串与源字符串是否等同,如果等同则认证成功。

配了ssh key后才能实现push代码的时候不需要反复输入自己的github账号密码,更方便。当然换一台电脑再想push的时候,又要再配置一次ssh key才行,github支持添加多个ssh key,可以用多台不同的电脑push代码到远程库里。

添加远程库

在github上创建远程仓库后,它是空的,因此需要将一个本地仓库与之关联,然后将本地仓库的内容push到远程仓库上。

git remote add origin git@github.com:michaelliao/learngit.git

添加后,远程库的名字就叫做origin(git默认推荐名字),添加完远程库后就可以将本地库的内容推送上去

git push -u origin master

origin是什么意思

实际上也可以用其他名字来命名远程库,比如aMao,不过push的时候也需要用aMao来代表远程库

git remote add aMao git@github.com:michaelliao/learngit.git
git push -u aMao master

参考Git 里面的 origin 到底代表啥意思?

从远程库克隆

上面的方法是自己从本地开始建库,然后再创建远程库,并且做关联的,相当于我们是这个远程仓库的创始人了。但是我们加入开发团队时往往是已经存在远程仓库了,这个时候我们要做的是直接把远程库克隆下来,生成我们的本地仓库,然后再进行开发。

git clone + 仓库地址

git clone git@github.com:michaelliao/gitskills.git

分支管理

HEAD指向当前分支,分支指针指向提交。

创建和合并分支

一开始时只有master分支,master指针指向最新的提交。此时创建分支dev,则dev指针也指向当前的提交,可以看到master和dev还没有分家。此时再切换到dev分支上,则HEAD指向dev指针。

git-br-create

其中,创建分支和切换分支的命令分别是

git branch feature/zhanhzhong/new_branch   
git checkout feature/zhanhzhong/new_branch

查看已有分支

git branch

在新分支上开发完成并且commit之后,教程就让把新分支合并到本地master上了,但是实际上合并到本地master没有太大意义,最终还是需要合并到远程master上,才能编译、部署到现网环境中(只支持编译master)。

所以现在直接看如何将分支合并到远程仓库的master上,首先需要pull远程master下来解决冲突(因为开发期间可能有其他开发者把他们的分支合并到远程master了)

git pull origin master

git-br-feature1

按照提示解决冲突后git add、git commit命令提交,再然后push到远程库

git push origin feature/zhanhzhong/new_branch

如果远程库里没有这个分支,这个命令会默认生成一个同名的分支,并且把本地分支push到这个远程分支上。

然后就在远程的git网页上提交merge请求,让别人code review,并且点approve之后,就可以合并到远程master上了。合并后是这样的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbDxqxLQ-1639130586744)(https://raw.githubusercontent.com/zhongzhh8/Images/master/img/0-20211210171322875.png)]

删除分支

新建featue分支来开发新特性后,需要删除分支的场景主要可以分成两种:

1、feature已开发完成,并且已merge进master分支。

此时feature分支已经没有存在的意义了,即使后面再在它上面做新的修改,也无法合并进master中,所以完全可以删除此分支

git branch -d feature/zhanhzhong/dev

如果后面还要对这个新特性做修改,直接在master上新建一个分支即可,因为master上已经存在有之前开发的新特性了。

2、feature尚未开发完成,还没有merge进master分支。

这种情况一般是需求取消,或者技术方案有问题需要推倒重来。此时由于分支没有合并进master,所以删除分支会有丢失修改的风险,因此用小写的 -d 来删除分支的话力度不够,git要求用大写的 -D 来强制删除分支

git branch -D feature/zhanhzhong/dev

分支管理策略

开发原则

在git上开发时,需要保持一个基础原则:分支开发,主干发布。

方法1: master分支 + 开发者个人分支

这种简单一点,就是每个开发者在自己的个人分支上开发,开发完毕并且测试没问题后,就可以直接合并进master分支,然后进行发布。(一般快速迭代的后台适合用这种方式)

方法2: master分支 + dev分支 + 开发者个人分支

git-br-policy

这种复杂一点,除了master分支外还有一个dev分支,每个开发者需要首先把自己的修改合并入dev分支,然后过一段时间后,进行大版本发布时,再一次性把dev分支合并入master分支中。(一般大型客户端平台比如微信等,会使用这种形式,因为不允许频繁更新客户端版本)

合并策略

git rebasegit merge这两个命令都旨在将更改代码从一个分支合并到另一个分支,但二者的合并方式却有很大的不同。总的来说,merge合并后不会破坏旧分支的commit记录,但是可能会产生额外的合并commit记录;rebase合并后会破坏旧分支的commit记录,但是不会产生额外的合并commit记录,而且可以形成线性的commit历史记录,非常直观。(用git log --graph命令看点线图)

  • 融合代码到公共分支的时使用git merge, 而不用git rebase
  • 融合代码到个人分支的时候使用git rebase,可以不污染分支的提交记录,形成简洁的线性提交历史记录。

因此下面的例子中,merge部分的举例是将个人分支合并到master分支中,rebase部分的距离是将master分支合并到个人分支。

merge

参考https://backlog.com/git-tutorial/cn/stepup/stepup1_4.html

情况1(Fast Forward): 从master上创建分支后,直到合并时,都没有其他开发者修改master分支的状态。

分支

这种情况非常简单,直接把原本指向master最新commit结点的HEAD移动到分支的最新commit结点上就可以了。

fast-forward合并

由于这种方式非常流畅,所以叫做快进模式。分支合并时,git默认使用Fast Forward模式。

情况2: 从master上创建分支后,到合并时,已经有其他开发者修改过master分支的状态。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iijfmtri-1639130586746)(https://raw.githubusercontent.com/zhongzhh8/Images/master/img/capture_stepup1_4_3.png)]

这种情况下需要将二者合并(无论是否需要解决冲突)会生产一个新的commit,然后将master上的HEAD移动到这个commit上。

结合了两个修改的合并提交

情况三(--no-ff:如果设定了non fast-forward选项(--no-ff参数),那么即使在能够fast-forward合并的情况下也会生成新的提交并合并。

non fast-forward合并

执行non fast-forward后,分支会维持原状。那么要查明在这个分支里的操作就很容易了。

rebase

参考【Git】:git rebase和git merge有什么区别?

如果是用merge方法将master分支合并到Feature分支,那么就会在Feature分支上新增一个commit结点,然后把HEAD移动到这个结点上。

git-merge

而如果使用rebase方法,那么就相当于把Feature分支的所有commit都移动到目标分支的最新commit的后面,rebase会为Feature分支上的所有已有的commit都创建新的commit来重写commit记录这种方式叫做reapply(重放),即把已有的commit重新在代码上应用一遍。最后就形成线性的提交记录,可以更清晰的看到项目的历史提交。

git-rebase

总结

总的来说,

  • git merge优点是合并后不破坏原分支的代码提交记录,缺点就是会产生额外的提交记录。由于远程master分支需要清晰的区分每个开发者的分支合并记录,所以开发者将Feature分支合并到master时应该使用merge方法。
  • git rebase 优点是无须新增提交记录到目标分支,rebase后可以将对象分支的提交历史续上目标分支上,形成线性提交历史记录,进行review的时候更加直观。由于个人的Feature分支只有自己使用,所以怎么方便怎么来,所以开发者将远程master分支合并到本地的Feature分支时可以使用rebase方法。

git pull 与 git pull --rebase的区别

参考简单对比git pull和git pull --rebase的使用

开发者将远程master分支合并到本地的Feature分支的命令有两句:

git pull origin master
git pull --rebase origin master

二者的区别在于

git pull = git fetch + git merge
git pull --rebase = git fetch + git rebase

也就是说,git pull是用merge方法,git pull --rebase是用rebase方法,后者可以形成线性的提交记录,更加直观。

其他

stash暂存

开发的时候经常会出现这样的情况,我正在开发分支dev1,但是需要临时切换到分支dev2去修改一下代码,而此时必须将dev1上的内容git add和commit之后才能切换分支。但是此时dev1上还没开发完,还不想commit,怎么办呢?这个时候就可以用git的stash功能把当前工作现场暂存起来

git stash

可以看到此前修改的代码都不见了,再用git status查看工作区,可以看到工作区是干净的。

此时可以直接切换分支了,在分支dev2上开发完成后,再切换回分支dev1,查看暂存的修改、将暂存的修改恢复出来

git stash list 
git stash pop

此时之前暂存的工作现场又恢复出来了,可以继续开发。

push -u 和 -f

-u参数有什么用

push和pull命令格式都是先写源分支,后写目的分支

git push <远程主机名> <本地分支名>:<远程分支名>
git pull <远程主机名> <远程分支名>:<本地分支名>   
//git pull其实是由git fetch和git merge组成的,也可以先fetch下来看差异,再决定是否merge

push一般会省略远程分支名,直接用

git push <远程主机名> <本地分支名>

相当于将本地分支推送到同名的远程分支上,如果不存在同名的远程分支,则会新建一个这样的远程分支,然后把内容push过去。

第一次使用 git push -u origin master 之后,-u代表将origin设置为默认主机,那么以后就可以直接

  • 使用 git pull 代替 git pull origin master 来拉取代码
  • 使用 git push 代替 git push origin master 来推送代码

上面是设置了master分支与origin远程主机的master分支之间的关联,如果是其他分支,则也是一样的方法

git push -u origin feature/zhanhzhong/tapd1125

-f 参数

参考从程序员枪杀案谈git push -f

分支开发,主干合并,也可以分成两种情况:

1、本地feature分支开发完成后,push到远程的对应的feature分支上,然后再将远程feature分支与远程master合并。这种情况下,由于远程只有自己一个人在使用,那么只需要用git push命令就可以每次都正常的push上去。

2、本地feature分支开发完成后,先合并进本地master分支,然后再将本地master分支push到远程master分支上。这种情况下,由于远程master由很多人都在使用,因此有可能会出现本地master的版本比远程master版本落后(因为别的开发同学在我们之前往master里提交过代码),导致push失败,此时也有两种解决方法:

  • 先把远程master pull到本地master上,解决了冲突,把本地master更新到最新版本,然后再push上去,一般都是使用这种方法。
  • 强行用git push -f origin master将本地master覆盖到远程master上,这种情况下其他同学在master上的提交内容会丢失掉,所以一般不推荐使用这种方法。

因此可见,git push -f 是风险非常大的操作,很容易影响到别人的工作,比如其他同事修复了一个bug,但是远程master上的代码被你覆盖了,导致这个bug依旧存在而大家都以为已经修复了,这样就很容易造成公司财产的损失。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 16:07:48  更:2021-12-11 16:10:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:38:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码