【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 了远端最新的代码,或者工作区有改动,导致行内冲突,这样的冲突也是需要我们手动去解决的。

相关推荐
真真-真真34 分钟前
WebXR
linux·运维·服务器
轩辰~1 小时前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
雨中rain2 小时前
Linux -- 从抢票逻辑理解线程互斥
linux·运维·c++
Bessssss2 小时前
centos日志管理,xiao整理
linux·运维·centos
s_yellowfish2 小时前
Linux服务器pm2 运行chatgpt-on-wechat,搭建微信群ai机器人
linux·服务器·chatgpt
豆是浪个2 小时前
Linux(Centos 7.6)yum源配置
linux·运维·centos
vvw&2 小时前
如何在 Ubuntu 22.04 上安装 Ansible 教程
linux·运维·服务器·ubuntu·开源·ansible·devops
我一定会有钱2 小时前
【linux】NFS实验
linux·服务器
Ven%2 小时前
如何在防火墙上指定ip访问服务器上任何端口呢
linux·服务器·网络·深度学习·tcp/ip
是阿建吖!2 小时前
【Linux】基础IO(磁盘文件)
linux·服务器·数据库