【Linux】【git】创建使用+分支管理+场景模拟

文章目录

  • 引子
  • [1. 创建 提交 删除](#1. 创建 提交 删除)
    • [init - - 创建一个初始化的本地仓库](#init - - 创建一个初始化的本地仓库)
    • [config - - 对本地仓库的配置](#config - - 对本地仓库的配置)
    • [add - - 新增](#add - - 新增)
    • [commit - - 提交](#commit - - 提交)
    • [rm - - 删除](#rm - - 删除)
  • [2. 状态查看 和 版本回退](#2. 状态查看 和 版本回退)
    • [log - - 日志](#log - - 日志)
    • [status - - 查看](#status - - 查看)
    • [diff - - 比较](#diff - - 比较)
    • [reset - - 版本回退](#reset - - 版本回退)
    • [reflog - - 参考日志](#reflog - - 参考日志)
  • [3. 撤销修改](#3. 撤销修改)
    • [checkout - - 让 工作区 回到最近一次 添加 / 提交](#checkout - - 让 工作区 回到最近一次 添加 / 提交)
    • [reset - - 版本回退](#reset - - 版本回退)
  • [4. 分支管理](#4. 分支管理)
    • [branch - - 新建、查看、删除本地分支](#branch - - 新建、查看、删除本地分支)
    • [checkout - - 切换分支](#checkout - - 切换分支)
    • [merge - - 合并](#merge - - 合并)
    • [stash - - 保存工作区内容、取出](#stash - - 保存工作区内容、取出)

引子

git 用作版本管理,是开发人员必须掌握的工具之一。笔者想借由一些基础语法和操作入手,尝试将 git 的工作结构融入其中,以便那些和我一样想要开始学习 git 的朋友能更好的认识这个工具的本质。

🎯写在前面:

  • git 涉及的管理区域需要仔细体会。
  • git 管理的是修改(添加、修改、删除),而不是文件,简单来说对一连串时间主导的 commit obj 的索引的管理,就是 git 的管理。
  • HEAD 指针指向分支的最后一次 commit!!回滚版本实际就是 HEAD 指针前移!!
  • 本篇内容将从本地仓库讲起,冲突问题本地仓库和远端的处理模式基本一致,最后在介绍远端的相关命令,有助于对git模型的整体理解。

1. 创建 提交 删除

init - - 创建一个初始化的本地仓库

  • 命令:git init

在新建仓库里能看到 .git 文件,是自动生成的仓库区,不要手动修改!我们在此外的区域进行管理即可。

config - - 对本地仓库的配置

  • 命令:git config [option],在建好的仓库目录下可以对该仓库进行信息配置。
    • -l:查看仓库配置信息;
    • user.name "用户名":设置仓库所属用户名;
    • user.email "用户邮箱":设置仓库所属用户邮箱;
    • --unset user.name:删除仓库所属用户名;
    • --unset user.email:删除仓库所属用户邮箱;
    • --global:一台服务器下创建多个本地仓库时,加上这个选项,会在该服务器下的所有本地仓库中生效。不过,使用该选项创建后,要想删除内容,需要同样用该选项,删除才会生效。

add - - 新增

  • 命令:git add 路径1 [路径2 ...],将本地文件 / 文件夹提交到暂存区。

介绍一下版本库里的区域:

  • objects 对象库
    • add 新增工作区的修改的时候,会将修改的内容写入一个 git 对象中,放入对象库中保存。这其实就做到了文件的版本管理。
  • stage 暂存区:
    • 存储的是 git 对象中的索引,是一个轻量化的区域。

commit - - 提交

  • 命令:git commit -m "描述",将暂存区的内容写到 [master(图示)] 分支下。

  • master 分支树:

    • 存储的同样是 git 对象中的索引;
    • 由一个指针指向分支结构,我们只要找到这个指针就可以找到一个分支中的所有内容。

rm - - 删除

  • 命令:git rm [filename],像比与在终端先 rm filename 再进行 add 操作,git 提供的 rm 将这两步合成了一步。使用完就可以直接 commit 提交了。

2. 状态查看 和 版本回退

log - - 日志

  • 命令:git log,可以查看到 HEAD 指针及其之前的版本信息
    (如果版本发生过回退操作,则可能会出现,HEAD 指针之后仍存在历史提交版本的情况,这些情况 log 就看不到了,需要用到 reflog
    • --pretty=oneline:规划成一行,以易懂的形式展示。
    • --graph:将分支规划成图显示在前面。
    • --abbrev-commit:将 id 进行缩写显示。
  • 结合 ".git" 文件的内容一起看一下:
    • HEAD 指向的内容是最后一次 commit 生成的 git 对象,这也是分支 master 的头头;
    • 所有的 git 对象都存在 object 下,记录着每一个 commit 的详细信息;
    • 暂存区的内容都在 index 里。

status - - 查看

  • 命令:git status "描述",查看本地、暂存库中的文件状态。

diff - - 比较

  • 命令:git diff [file],显示 已写入暂存区已经被修改但尚未写入暂存区文件 的区别。
    • 尚未提交到暂存区的改动:git diff [file];
      • 这里的结果绿框是改动前,-1 的含义是改动前的文件的第一行被修改了;
      • 橙框是改动后,+1,2 的含义是从第一行起的连续两行被改动了;
    • 查看 版本库工作区 的区别:git diff HEAD [-- file]。

reset - - 版本回退

reset 可以将版本库中的操作进行回退

也可以回退到当前版本(工作区、暂存区有修改,可以使用 git reset 让工作区、暂存区和版本库一致,相当于撤回工作区、暂存区的修改)。

a. 回退到指定版本

  • 命令:git reset [option] [HEAD] [filename],这里的HEAD指的是指针,即 git 对象的 ID。
    • --soft:只回退版本库;
    • --mixed:回退暂存库、版本库,是 默认选项
    • --hard:回退工作区、暂存区、版本库。慎用,工作区的新增内容会全部消失。
选项 工作区 暂存区 版本库
--soft vers1,vers2 vers1,vers2 vers1
--mixed(默认项) vers1,vers2 vers1 vers1
--hard vers1 vers1 vers1

b. 回退到 当前/上一版本

  • 命令:git reset [option] HEAD[^^] [filename],直接跟 HEAD 是回退到当前版本,在 HEAD 后加 ^ 就是回退到上一个版本,加 ^^ 就是回退到上上个版本。
    • 选项的控制范围也是一样的,如果不加,就是默认 --mixed,让暂存区和版本库一致。
场景模拟1_1
复制代码
在一个仓库中我做了三次提交:
第一次创建提交:file1(里面的内容是version 1)
第二次创建提交:file2、file3
第三次修改提交:file1(里面的内容是version 1\nversion2)

这里要做的是将版本回退到第一次提交,然后版本再次返回,回退到第三次提交

如上操作,在回退到第一版时,输入 git log 是只有第一次提交的记录的,我们能顺利回退完全是因为在最开始打印了第三次的提交 id。

在已经 git log 不出原来信息的情况,又要怎么回退到第三次提交呢?

reflog - - 参考日志

  • 命令:git reflog,可以叫做显示可引用的历史版本记录,会记录所有出现过的提交信息。
场景模拟1_2
复制代码
接着上面的场景模拟1_1,在 git reflog 中可以找到所有的记录!!

ps:如果版本提交次数太多,想要恢复的那个 id 找不到了,就恢复不了咯~~~

3. 撤销修改

撤销修改这一节,适用于如下情况:我们想把本地的内容撤销掉,恢复上一个版本的内容。撤销的目的主要是,不要让本地代码影响远程仓库!

这里引入一个远程仓库的概念,我们能接触到的几个分区大概就是这样:

复制代码
工作区 --> 暂存区 --> 版本库 --> 远端仓库
      add     commit     push

而撤销修改的前提就是,需要撤销的内容还没有 push,没有推送至远端,否则这些撤销修改都是没有意义的。

本地 git 仓库存在以下这三种分区,对于要撤销的修改就会有三种状况:

情况 工作区 暂存区 版本库 处理方式
只有修改,还没 add xxx git checkout -- [filename]
没有 commit xxx xxx git reset HEAD [filename]
add、commit 都做了 xxx xxx xxx git reset --hard HEAD^ [filename]

checkout - - 让 工作区 回到最近一次 添加 / 提交

  • 命令:git checkout -- [filename],这里必须要加 - - 否则这个命令就不是这个意思咯

reset - - 版本回退

复制代码
...具体见上一个板块 ~~

4. 分支管理

这一节牵扯到多个分支的问题,之前因为都是以一个分支举例,所以需要进一步说明一个细节:被 HEAD 指向的分支,是当前工作分支。使用下面这个命令可以查看当前本地分支情况。

branch - - 新建、查看、删除本地分支

  • 命令:git branch查看当前本地分支情况 ,其中带 * 号的就是当前工作分支。
  • 命令:git branch 分支名新建分支
    • 注意:分支在当前的版本建立,也就是说创建分支的时候,master 和 dev 里放的都是最后一次操作的索引。
  • 命令:git branch -d 分支名删除本地分支。在有提交的情况下,是不能删除的。
  • 命令:git branch -D 分支名强制删除本地分支
    • 不能删除当前所在分支,想要删除一个分支,必须先切换出这个分支才行。

checkout - - 切换分支

  • 命令:git checkout [option] 分支名,切换到指定分支。
    • -b:切换到指定分支,如果没有该分支则创建再切换
场景模拟2_1

merge - - 合并

  • 命令:git merge [option] 分支名,可以将指定分支的内容合并进当前分支。
    • --no-ff:不使用 fast-forward 模式,可以在 log 中看出该次提交是来自 merge 的,同时带上 -m "描述" 选项,进行一次提交。
场景模拟2_2

接着上个场景2_1

注意,这里 merge 的时候给出的信息中有一个 fast-forward,这个 快速模式 意思就是通过改变了 master 的指向,快速合并。如果是 fast-forward 模式,会分辨不出来是 merge 进来的还是正常提交的。

场景模拟3(合并冲突)

如果在 merge 的时候,两个分支都对相同内容有改动,就会产生冲突,需要我们去手动解决。<<<<HEAD 和 === 之间的是当前分支的改动,=== 和 >>>dev 之间的是分支dev的改动。

非 fast-forward (no-ff) 模式的合并,去看他的分支,能清楚的看出是 merge 进来的内容。

如果想要普通的 merge 也可以这样看出过程,需要在 merge 后加上 --no-ff 选项

stash - - 保存工作区内容、取出

stash 又是一个新区域咯~~

  • 推入
    • 命令:git stash / git stash push,可以将所在分支的 工作区中的已经被 git 追踪管理的内容 保存在 stash 中。这份暂存的内容会有一个默认的 msg,内容是当前分支的最近一次提交的 msg,想要自己定义更详细的内容,建议使用下面的命令;
    • 命令:git stash save "msg content",储存时自定义 msg。
  • 查看
    • 命令:git stash list,查看 stash 中存了哪些内容,行开头是 stash 的名称和序号,idx 为 0 是栈顶,一切操作不带 idx 的都默认为对栈顶进行操作。
  • 应用 / 弹出
    • 命令:git stash pop [idx],将 stash 中存储的内容取出至工作区,不带 idx 默认从栈顶弹出。
    • 命令:git stash apply [idx],将 stash 中存储的内容应用至工作区,stash 中不删除,即可以多次应用,不带 idx 默认应用栈顶内容。
  • 删除
    • 命令:git drop [idx],将 idx 标记的 stash 从 list 中丢弃,不带 idx 默认丢弃栈顶内容。

首先声明这样一个场景:我们在日常开发的时候为了保证主分支(线上分支)的稳定,新功能和 BUG 修改工作都应该基于主分支,在自己本地的新建分支上完成,测试通过后 merge 进主分支!git 的分支管理提供给我们如上便利,同时还能实现多人共同协作...

假设我们正在分支 dev 进行新功能开发,本地工作区有内容未提交,但是此时有一个新 bug 需要马上处理。如果这时候我们直接 git checkout master 转回主分支并进行 git checkout -b dev_fix_bug,进入 dev_fix_bug 会发现 dev 编辑的未提交内容都会显示出来,这是我们不希望看到的。此时就需要用到 stash 命令,在 dev 开发分支上将未提交的代码保存!

stash 的暂存只在该分支上有效,当该分支上有 stash 的情况下,pull 了远端最新的代码,或者工作区有改动,导致行内冲突,这样的冲突也是需要我们手动去解决的。

相关推荐
꧁坚持很酷꧂23 分钟前
Linux Ubuntu18.04下安装Qt Craeator 5.12.9(图文详解)
linux·运维·qt
李菠菜32 分钟前
解决Windows系统下Git克隆时报错“unable to checkout working tree”的方法详解
windows·git
island131441 分钟前
【git#4】分支管理 -- 知识补充
大数据·git·elasticsearch
凉、介41 分钟前
PCI 总线学习笔记(五)
android·linux·笔记·学习·pcie·pci
电鱼智能的电小鱼1 小时前
EFISH-SBC-RK3588无人机地面基准站项目
linux·网络·嵌入式硬件·机器人·无人机·边缘计算
电鱼智能的电小鱼1 小时前
基于 EFISH-SBC-RK3588 的无人机环境感知与数据采集方案
linux·网络·嵌入式硬件·数码相机·无人机·边缘计算
小诸葛的博客2 小时前
详解Linux中的定时任务管理工具crond
linux·运维·chrome
一默19912 小时前
CentOS 7.9升级OpenSSH到9.9p2
linux·运维·centos
船长@Quant2 小时前
协作开发攻略:Git全面使用指南 — 引言
git·版本控制·源代码管理·协作开发
keep intensify2 小时前
Linux常用指令
linux·服务器·php