Git 时间线管理

news2024/11/18 11:23:10

Git 时间线管理

这一部分主要讲的是 取消(undo) 变化 和在不同的时间锚点跳来跳去,以 command 为主。

设计到的commits有:

  • checkout
  • restore
  • reset
  • revert

checkout

checkout 的一部分作用,即切换分枝在 git 分支操作 中有提到过,不过 checkout 本身的用途更多。有些开发甚至觉得 checkout 的功能太多了,最终将功能分割之后生成了新的 switchrestore

除了分支管理之外,checkout 还能用来还原文件和 undo history。

checkout commit

下面会 checkout 一个 commit hash:

# 可以完整cv整个hash,或者截取前 7 位作为hash key
➜  basic git:(main)git checkout f8b2e15
Note: switching to 'f8b2e15'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at f8b2e15 start work on outline and characters
➜  basic git:(f8b2e15)git status
HEAD detached at f8b2e15
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        git.md

nothing added to commit but untracked files present (use "git add" to track)

现在解释一下 detached HEAD 是什么意思,正常情况下,当前 branch 指向当前 commit,而当前 head 指向当前 branch,也就可以理解成是当前 commit 的 reference,这个时候的 head 是当前 commit 的 symlink:

HEAD
branch
commit2
commit

软件上看起来是这样的:

在这里插入图片描述

但是当直接 checkout 到一个 commit 之后,当前的分支依旧之乡最后一个 commit,HEAD 则是只想当前的 commit:

HEAD
commit
branch
commit2

也就是说 HEAD 从 branch 上分离(detach)了,软件上看起来是这样的:

在这里插入图片描述

这时候的 HEAD 直接作为当前 commit 的 reference。

checkout commit 的用途有

  1. 查看原始文件

    大多是时候发生在某个版本不工作了,然后要要 revert 到某一个版本

  2. 创建一个新的分支

    就像 switch 到一个新的分支会创建一个新的历史一样,checkout 到某一个 commit 也会创建一个新的历史分支

    ➜  basic git:(main)git checkout f8b2e15
    ➜  basic git:(f8b2e15)git switch -c new-ch2
    Switched to a new branch 'new-ch2'
    ➜  basic git:(new-ch2)git commit -m "create new version of ch2"
    [new-ch2 12da43a] create new version of ch2
    1 file changed, 1 insertion(+)
    create mode 100644 ch2.txt
    ➜  basic git:(new-ch2)

    此时的分支看起来如下:

    在这里插入图片描述

    此时的 HEAD 不是一个 detached 状态,而是重新绑定到了新创建的 new-ch2 分支上。而该分支没有保存的变化,依旧保存在另一个分支上。

如果没有做任何的变动,想要切换到原有的分支,可以直接使用 git checkout branchname 执行。

git checkout HEAD~

具体语法为:git checkout HEAD~1,其中 HEAD~ 后跟数字,如果是 1 就惠滚到上一个 commit,以此类推。

图解如下:

在这里插入图片描述

顺便上面的 mermaid 语法为:

gitGraph
  commit id: "HEAD~5"
  commit id: "HEAD~4"
  commit id: "HEAD~3"
  commit id: "HEAD~2"
  commit id: "HEAD~1"
  commit type: HIGHLIGHT

运行如下:

➜  basic git:(new-ch2)git checkout main
Switched to branch 'main'
➜  basic git:(main)git checkout HEAD~2
Note: switching to 'HEAD~2'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at b18e966 update chapter 1

在这里插入图片描述

这个时候返回有两个方法:

  1. 记住原本分支

  2. 使用 git switch -,该指令会切换到上一个所在的分支,如:

    ➜  basic git:(b18e966)git switch -
    Previous HEAD position was b18e966 update chapter 1
    Switched to branch 'main'
    

git checkout HEAD

该指令可以用于重制已经修改的文件,这里会用一个新的 repo 做例子,初步设置如下:

➜  undo git:(main)touch cat.txt dog.txt
➜  undo git:(main)echo "first commit" > cat.txt
➜  undo git:(main)echo "first commit" > dog.txt
➜  undo git:(main)git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        cat.txt
        dog.txt

nothing added to commit but untracked files present (use "git add" to track)
➜  undo git:(main)git add .
➜  undo git:(main)git commit -m "first commits"
[main (root-commit) 6c98eb0] first commits
 2 files changed, 2 insertions(+)
 create mode 100644 cat.txt
 create mode 100644 dog.txt
➜  undo git:(main) cat cat.txt
first commit
➜  undo git:(main)echo 'second commit' >> cat.txt
➜  undo git:(main)echo 'second commit' >> dog.txt
➜  undo git:(main)cat cat.txt
first commit
second commit
➜  undo git:(main)git add .
➜  undo git:(main)git commit -m "second commit"
[main 5a999a7] second commit
 2 files changed, 2 insertions(+)

# 重复若干次

准备完了之后就可以用 git checkout HEAD <file>,缩写为 git checkout -- <filename> 去重制操作了,如:

➜  undo git:(main) git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   cat.txt
        modified:   git.md

no changes added to commit (use "git add" and/or "git commit -a")
➜  undo git:(main)git checkout HEAD cat.txt
Updated 1 path from 4899106
➜  undo git:(main)git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   git.md

no changes added to commit (use "git add" and/or "git commit -a")

➜  undo git:(main)git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   cat.txt
        modified:   dog.txt
        modified:   git.md

no changes added to commit (use "git add" and/or "git commit -a")
➜  undo git:(main)git checkout -- *.txt
➜  undo git:(main)git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   git.md

no changes added to commit (use "git add" and/or "git commit -a")

这个的使用场景可能在:

  1. 你真的搞砸了很多

  2. 重制 db 文件

    比如说我们的项目就是从 csv 中读取 db 文件的,然后每天都必须要更新 csv 中的 ref date,这个时候更新分支就会因为 csv 不 match 导致 conflict。

restore

像上文提到的,restore 是一个比较新的命令,用于重置一些 checkout 的功能。

git restore

该指令可以用于重制已经修改的文件,对标 git checkout HEAD <file>

➜  undo git:(main)git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   dog.txt
        modified:   git.md

no changes added to commit (use "git add" and/or "git commit -a")
➜  undo git:(main)git restore dog.txt
➜  undo git:(main)git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   git.md

no changes added to commit (use "git add" and/or "git commit -a")
➜  undo git:(main)

restore --source

另一个 flag 可以用来将当前文件还原到几个 commit 之前,语法为:git restore --source <HEAD~1|hashedvalue> <filename>,还愿的方法使用上一条指令即可。

例:

➜  undo git:(main)cat dog.txt
first commit
second commit
third commit
➜  undo git:(main)git restore --source HEAD~2 dog.txt
➜  undo git:(main)cat dog.txt
first commit
➜  undo git:(main)git restore dog.txt
➜  undo git:(main)cat dog.txt
first commit
second commit
third commit

restore --staged

具体指令:git restore --staged <file>,这条指令可以将已经 staged 文件拉出来,如:

➜  undo git:(main)touch wrongfile.txt
➜  undo git:(main)git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   git.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        wrongfile.txt

no changes added to commit (use "git add" and/or "git commit -a")
➜  undo git:(main)git add .
➜  undo git:(main)git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   git.md
        new file:   wrongfile.txt

➜  undo git:(main)git restore --staged wrongfile.txt
➜  undo git:(main)git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   git.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        wrongfile.txt

顺便,如果直接用 git status,git 会提示可以用什么指令进行操作,如 git restore --staged <file>...git add <file>...git restore <file>..

reset

git reset 用于重置 commits,我主要用来将几个 commits squash 到一个 commits 里面去,使用 git rest 会保留当前的变化。

案例:

➜  undo git:(main) git log --oneline
da7603f (HEAD -> main) mistake commit2
a34f0c8 mistake commit
50840de third commit
5a999a7 second commit
6c98eb0 first commits
(END)

➜  undo git:(main) git reset 50840de
Unstaged changes after reset:
M       cat.txt
M       dog.txt
M       git.md
➜  undo git:(main)git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   cat.txt
        modified:   dog.txt
        modified:   git.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        wrongfile.txt

no changes added to commit (use "git add" and/or "git commit -a")
➜  undo git:(main)git log --oneline
50840de (HEAD -> main) third commit
5a999a7 second commit
6c98eb0 first commits
(END)

可以看到,本来的变化没有丢还在这里。

对于 git 来说,它会重新将 HEAD 指向提供的 commit hash 值,并且将中间的变化保存在 working directory 中。

我常用的做法就是清理分支上的 commits(尽量保证一个修 bug 的 MR/PR 一个 commits,功能性的保证有理由的 staging,一般来说小功能在 3 个以下,大功能 5 个一下这样),或者是将当前的变化带到其他的分支上。当然,后者用 git stash 也可以。

如果想要将当前的变化和修改的文件全都删除,可以加上 --hard 这个 flag,其语法为 git reset --hard <commit>,如:

➜  undo git:(main) git add .
➜  undo git:(main)git commit -m "mistake commit"
[main fa07782] mistake commit
 2 files changed, 2 insertions(+)
➜  undo git:(main) git log --oneline
fa07782 (HEAD -> main) mistake commit
0608200 fourth commit
50840de third commit
5a999a7 second commit
6c98eb0
➜  undo git:(main)git reset --hard HEAD~1
HEAD is now at 0608200 fourth commit
➜  undo git:(main) git status
On branch main
nothing to commit, working tree clean
➜  undo git:(main) git log --oneline
0608200 (HEAD -> main) fourth commit
50840de third commit
5a999a7 second commit
6c98eb0 first commits
(END)

revert

revert 和 reset 有点像,但是 revert 会保留之前的 commit,将文件放到 working directory 中,并且创建一个新的 commit 说明之前的 commit 被 revert 了。

举例说明:

➜  undo git:(main) git log --oneline
fbd7250 (HEAD -> main) mistake commit2
2f0f2ce mistake commit
0608200 fourth commit
50840de third commit
5a999a7 second commit
6c98eb0 first commits
(END)

➜  undo git:(main)git add .
➜  undo git:(main)git commit -m "mistake commit"
[main 2f0f2ce] mistake commit
 3 files changed, 36 insertions(+), 1 deletion(-)
➜  undo git:(main) git add .
➜  undo git:(main)git commit -m "mistake commit2"
[main fbd7250] mistake commit2
 1 file changed, 1 insertion(+)
➜  undo git:(main) git log --oneline
➜  undo git:(main) git revert 0608200
error: Your local changes to the following files would be overwritten by merge:
        git.md
Please commit your changes or stash them before you merge.
Aborting
fatal: revert failed
➜  undo git:(main)git revert 0608200
Auto-merging cat.txt
CONFLICT (content): Merge conflict in cat.txt
Auto-merging dog.txt
CONFLICT (content): Merge conflict in dog.txt
Auto-merging git.md
CONFLICT (content): Merge conflict in git.md
error: could not revert 0608200... fourth commit
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".
➜  undo git:(main)git add .
➜  undo git:(main)git revert --continue
[main 6c50464] Revert "fourth commit"
 2 files changed, 1 insertion(+), 1 deletion(-)
 delete mode 100644 wrongfile.txt
➜  undo git:(main) git status
On branch main
nothing to commit, working tree clean
➜  undo git:(main) git log --oneline
6c50464 (HEAD -> main) Revert "fourth commit"
fbd7250 mistake commit2
2f0f2ce mistake commit
0608200 fourth commit
50840de third commit
5a999a7 second commit
6c98eb0 first commits
(END)

可以看到,working tree clean 标记修改的文件已经没有了,但是修改的 commits 还存在。

从个人经验上来说,我用 revert 就是为了修正某些已经实现的功能(by fixing one bug we created more bugs),但是别的同事机器上已经有了那个 commits,不可能说重改整个历史,这样别人做的 commits 也没有了。

即,如果所有的变化都是本地的,那么使用 reset 会方便些。如果变化推到了 remote,但是 没有其他的同事 使用这个 branch,使用 reset 也可以。否则就应该使用 reset。

reference

  • HEAD and ORIG_HEAD in Git

  • What is HEAD in Git?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/451602.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESP32-s2芯片esp32-s2-saola-1开发板 micropython的repl连接

本文只是解决通过esp32-s2-saola-1开发板 自带microUSB 作为repl与micro python通信的问题。 如果你对esp32&#xff0c;micropython不熟&#xff0c;本文不适合你。 如果你用的不是esp32-s2&#xff0c;你不需要关心。 区分两个USB&#xff1a; 1. esp32-s2原生USB&#x…

25K 入职阿里的那天,我特么哭了

悲催的经历&#xff1a; 先说一下自己的个人情况&#xff0c;计算机专业&#xff0c;17 年本科毕业&#xff0c;一毕业就进入了“腾讯”测试 岗(进去才知道是接了个腾讯外包项目&#xff0c;可是刚毕业谁知道什么外包不外包的)。 更悲催的是&#xff1a;刚入职因为家里出现一…

什么是CDN加速?CDN加速有哪些作用?

一、什么是 CDN CDN 的全称是 Content Delivery Network&#xff0c;即内容分发网络。CDN 是在现有 Internet 基础上增加一层新的网络架构&#xff0c;通过部署边缘服务器&#xff0c;采用负载均衡、内容分发、调度等功能&#xff0c;使用户可以就近访问获取所需内容&#xff…

VMware 安装 MS-DOS7.10 并配置网络

VMware 安装 MS-DOS7.10 并设置软盘共享 1. 新建虚拟机2. 开机2.1. 这几个地方都可以开机2.2. 手速慢&#xff0c;进不了BIOS的朋友可以点这里 安装 MS-DOS7.101. 先选 1 安装 MS-DOS7.10 回车2. 欢迎页面&#xff0c;客气一下而已&#xff0c;继续 Next3. 继续王婆卖瓜4. 这步…

HDCTF 2023 Pwn WriteUp

Index 前言Pwnner分析EXP: KEEP_ON分析EXP: Minions分析EXP: 后记&#xff1a; 前言 本人是菜狗&#xff0c;比赛的时候只做出来1题&#xff0c;2题有思路但是不会&#xff0c;还是太菜了。 栈迁移还是不会&#xff0c;但又都是栈迁移的题&#xff0c;真头大。得找时间好好学学…

如何在 Java 8 中使用 Streams?结合多种案例剖析学习!

Java 8 Streams 是一个非常强大的功能&#xff0c;它提供了一种简洁、优雅的方式来处理数据集合。通过使用 Streams&#xff0c;我们可以轻松地过滤、映射、排序、聚合等操作数据。本教程将介绍 Streams 的基本概念&#xff0c;以及如何在 Java 8 中使用 Streams。本教程还包括…

【计算机视觉 | 语义分割】OVSeg:分割一切后,SAM又能分辨类别了,Meta/UTAustin提出全新开放类分割模型

文章目录 一、前言二、研究背景三、论文解读3.1 动机3.2 方法3.3 结果 一、前言 前几日&#xff0c;Meta 推出了「分割一切」AI 模型 Segment Anything&#xff0c;令网友直呼 CV 不存在了&#xff1f;&#xff01; 而在另一篇被 CVPR 2023 收录的论文中&#xff0c;Meta、UT…

《计算机网络——自顶向下方法》精炼——2.2.3-2.2.5

文章目录 引言正文HTTP报文请求行首部行实体体其他方法 HTTP响应报文实体体和初始状态行首部行 cookiecookie的运行过程Web缓存条件GET方法 引言 计算机网络在这一学科中的重要性毋庸置疑&#xff0c;而黑皮书又是这一学科的教科书级经典&#xff0c;因此本书是计算机从业者的…

微服务学习之面试知识相关总结(Redis)

文章目录 前言Redis常见面试知识1 Redis与Memcache的区别2 Redis的单线程问题3 Redis的持久化方案3.1 基础知识3.2 面试话术 4 Redis的集群方式4 Redis的常用数据类型5 Redis事务机制6 Redis的Key过期策略6.1 过期删除策略6.2 内存淘汰策略6.3 面试话术&#xff1a; 7 Redis在项…

SpringBoot(7)消息处理

消息处理 消息Java处理消息的标准规范JMSAMQPMQTTkafka 案例准备整合ActiveMQ整合RabbitMQ整合RocketMQ整合Kafka 消息 对于消息的生产者与消费者的工作模式&#xff0c;还可以将消息划分成两种模式&#xff0c;同步消费与异步消息。 同步消息就是生产者发送完消息&#xff0…

SpringCloud入门实战(七)-Hystrix服务降级入门案例

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术&#xff0c;都可以先去官网先看看&…

广州华锐互动:AR远程协作系统为电力设备状态监测提供有力支持

电力设备是电网运行的重要组成部分&#xff0c;对电网的安全稳定运行具有至关重要的作用。在电力设备状态监测中&#xff0c;如何快速、准确地诊断和解决设备故障&#xff0c;是电力企业和电力设备维护人员需要面对的重要问题。 广州华锐互动将AR增强现实技术运用到电力设备维…

美颜sdk是什么?探索美颜sdk的技术内幕

目前&#xff0c;美颜sdk作为美颜功能的实现方式&#xff0c;已经成为了各大应用开发者的热门选择之一。那么&#xff0c;美颜sdk到底是什么&#xff1f;它的技术内幕又是怎样的呢&#xff1f;本文将会为您揭开它的神秘面纱。 一、美颜sdk简述 美颜sdk顾名思义&#xff0c;就…

瑞萨开发环境搭建

使用keil环境&#xff0c;开发瑞萨renase A4M2 下载MDK 下载MDK&#xff0c;5.37 其它版本 最好使用5.30以上 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5k3XGSK5-1682182139410)(https://secure2.wostatic.cn/static/reEunrWa2vsfrcpVZC1nbo…

关于存储那些事1-----基础篇

目录 一、SSD1、简介1.1 分类1.1.1 易失性存储器1.1.2 非易失性存储器 2、SSD接口2.1 SATA接口2.2 SATA Express接口2.3 SAS接口2.4 U.2接口2.5 mSATA接口2.6 M.2接口2.7 PCI-E接口 二、闪存&#xff08;Flash memory&#xff09;1、简介1.1 NOR Flash1.2 NAND Falsh1.3 NOR Fl…

二维码图片生成工具C#winform源码

二维码图片生成工具C#winform源码 源码描述&#xff1a; 一、源码特点 采用winform进行开发,生成二维码并保存&#xff0c;欢迎下载 二、功能介绍 本源码是一个可以自动生成二维码图片的小模块&#xff0c;可以添加自己的logo图片&#xff0c;可以保存在自己想要保存的地方 …

ubuntu20.04+x86_64+virtualbox6.7 环境下编译xenomai内核和实时性测试[详解]

下面是针对实时系统Xenomai使用的一些记录,实时系统在工业自动化,机器人等智能行业是必需会用到的。 简述 xenomai是众多inux实时性解决方案中的一种,通过在linux的基础上添加一个RTOS内核cobalt,来提高linux的实时性。实时内核cobalt与非实时内核linux相结合,既能提供工…

C/C++笔记-写一个Makefile并链接QtCore库使用QString,QDebug

如下cpp代码&#xff0c;调用QDebug打印程序&#xff1a; #include <QDebug> #include <QString>int main(int argc, char *argv[]){QString testStr "hello";qDebug() << testStr;return 0; } 如下makefile&#xff1a; test: main.cppg -c -…

‘gulp‘ 不是内部或外部命令,也不是可运行的程序

出现问题&#xff1a; D:\git\renwey-web-mobile>gulp default gulp 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 两种原因 原因一&#xff1a;环境变量没有设置 原因二&#xff1a;没有安装全局的gulp&#xff0c;只安装了本地gulp&#xff0c;…

CTFShow-Web篇详细wp

CTFShow-Web篇详细wp web签到题web2web3web4web5web6web7web8 CTFShow 平台&#xff1a;https://ctf.show/ web签到题 直接F12然后Base64解码 ctfshow{19bdf375-f974-481e-8c62-0f4c3d170fb4} web2 考点&#xff1a;联合查询 先尝试使用万能密码登入 ‘ or 11# 登入成功&am…