git改变历史

本文详细介绍如何使用版本控制系统进行复杂的操作,如撤销提交、合并提交、精简版本库等高级技巧,帮助读者掌握版本控制的深入应用。

一、悔棋
对最近一次提交修改
对刚刚进行的一次或几次提交进行修改或撤销。
1、查看当前版本库的最新两次提交
这里写图片描述
2、修改最新提交的说明
这里写图片描述
3、查看修改后的记录:
这里写图片描述
4、修补提交:最近一次的操作是移动文件时,将原始文件welcome.txt删除了,现在恢复,被重新放回到暂存区了。但是工作区还是有README文件的:
这里写图片描述
5、对最新的提交进行修补
这里写图片描述
6、查看最近的2次提交日志:
这里写图片描述

多步悔棋

多次提交合并
可以取消最新连续的多次提交。多次提交合并为一个完整的提交。
1、查看版本库最近的三次提交
这里写图片描述

将最近的两次提交压缩为一个,并修改提交说明:
1、使用–soft 参数调用重置命令,回到最近两次提交之前:
这里写图片描述
2、查看版本状态和最新的日志(该日志是回到前2步后的日志):
这里写图片描述
3、执行提交操作,即完成最新两个提交压缩为一个提交操作:
这里写图片描述
4、查看提交日志
这里写图片描述

不能直接修改任意处的提交说明,会导致新的提交说明。只能提交合并了。

回到未来:对于历史提交,如果更改其中的一个提交(抛弃提交或合并提交),都会使后续提交发生连锁反应。因为后续提交中都有一个属性是parent的哈希值。
1、查看历史提交
这里写图片描述
2、先把历史提交做一个标记:
这里写图片描述
这里写图片描述
这里写图片描述
3、查看被标记的日志
这里写图片描述

任务:将标记为D的提交取消,或者与标记为C的提交合并。
这里写图片描述

这里写图片描述

以下是第一种情况:抛弃D提交

1、首先,将HEAD指针切换到C,也就是D的父提交,此时处于非跟踪状态(与master不一致)
这里写图片描述
2、将标记为E提交在当前HEAD(也就是标记C)上重放,其中master^与标记E指向同一提交 E。
这里写图片描述
3、将标记为F提交在当前HEAD(也就是标记E)上重放,其中master与F指向同一提交F:
这里写图片描述
4、查看日志,发现D提交不见了,而且最近的两次提交哈希值也不同:
这里写图片描述
5、查看最近的两次提交:
这里写图片描述
6、将master分支重置到新的提交上。要先切换到master分支:
这里写图片描述
这里写图片描述
7、查看分支图:
这里写图片描述

在抛弃D操作之前,工作区的文件:
这里写图片描述
执行抛弃D操作之后,工作区的文件:
这里写图片描述
而且暂存区也没有,完全丢失了:
这里写图片描述

以上都是抛弃D提交的操作,现在恢复原始的样子,

执行CD提交合并操作:

1、恢复初始状态,在master分支上执行:
这里写图片描述

2、将HEAD头指针换换到D(也就是要被合并的提交)
这里写图片描述

3、后退两步,以便C和D融合,此时HEAD指向B:
这里写图片描述

4、重新执行提交,提交说明重用C提交的提交说明:
这里写图片描述
5、将E提交在当前HEAD上重放:
这里写图片描述
6、将F提交在当前HEAD上重放:
这里写图片描述
7、查看日志,发现看不见C的标签:
这里写图片描述
8、将master分支指向最新的提交,先切回到master;
这里写图片描述
9、查看分支图:
这里写图片描述
10、重新恢复:
这里写图片描述

丢弃历史
最早的历史可能不希望也没有必要继续保存,需要抛弃部分早期历史提交的精简版本库用于和他人共享。

假设希望把里程碑C之前的历史提交全部清除,
1、查看里程碑C指向的目录树
这里写图片描述
2、直接从该目录树创建提交
这里写图片描述
3、查看提交,发现这个提交没有历史,也就是没有parent:
这里写图片描述
4、将master分支上里程碑C之后的提交变基到新的根提交上:
这里写图片描述
5、查看日志,当前master分支已经精简了
这里写图片描述
6、虽然提交精简了,但是本地文件并没有变化:
这里写图片描述

<think>我们正在讨论Git中如何改变HEAD指针的问题。根据用户的问题“gitchangeheadpointer”,我们需要解释HEAD指针的作用以及如何改变它。引用[1]提到切换分支时HEAD会改变,引用[2]展示了使用`gitcheckoutHEAD`来恢复文件,引用[4]展示了切换分支和合并时HEAD的变化,引用[5]提到了标签和分支的区别,其中HEAD通常指向当前分支。HEAD是当前分支的引用,它指向当前所在分支的最新提交。改变HEAD的指向通常有以下几种方式:1.切换分支:使用`gitcheckout<branch>`或`gitswitch<branch>`(Git2.23+)可以切换到指定分支,此时HEAD会指向该分支的最新提交。2.分离头指针(detachedHEAD):使用`gitcheckout<commit-hash>`或`gitcheckout<tag>`可以让HEAD直接指向某个具体的提交,而不是分支。在这种状态下,你不在任何分支上。3.重置操作:使用`gitreset`可以移动当前分支指向(同时也移动HEAD,因为HEAD指向当前分支,而分支指针被重置),但注意重置操作改变历史,需谨慎。4.使用`gitsymbolic-ref`:这是直接操作HEAD引用的底层命令,但一般不建议普通用户使用。根据引用[1]:切换分支时,工作目录会改变,如果切换到一个旧分支,工作目录会恢复到该分支最后一次提交的样子。如果Git不能干净地切换(比如有未提交的修改),它会阻止切换。引用[2]展示了使用`gitcheckoutHEAD--<file>`来恢复工作目录中的文件,这不会改变HEAD指针本身(HEAD已经指向当前提交),但会改变工作目录的文件。因此,改变HEAD指针的常用方法是切换分支或检出特定的提交。下面我们详细说明:###1.切换分支改变HEAD当你切换分支时,HEAD会指向新分支的最新提交。例如:```gitcheckoutfeature-branch#现在HEAD指向feature-branch分支的顶端```###2.检出特定提交(分离头指针)你可以检出某个提交,此时HEAD直接指向该提交,而不是分支:```gitcheckout2d9263c#2d9263c是某个提交的哈希值```这时你会看到提示:Youarein'detachedHEAD'state.###3.使用`gitreset`改变当前分支和HEAD如果你在当前分支上,想要将当前分支(以及HEAD)回退到某个提交,可以使用`gitreset`:```gitreset--hard2d9263c#将当前分支和HEAD都重置到提交2d9263c,并且工作目录也重置```注意:`--hard`选项会重置工作目录和暂存区,所以谨慎使用。###4.使用`gitbranch-f`强制移动分支引用,然后切换你也可以直接移动当前分支的引用,然后通过切换分支来改变HEAD:```gitbranch-fmaster2d9263c#将master分支强制指向2d9263cgitcheckoutmaster#然后切换回master,此时HEAD指向master,而master指向2d9263c```注意:直接使用`gitbranch-f`改变分支引用可能会覆盖历史,所以在共享分支上要小心。根据引用[4]中的例子,合并操作也会改变HEAD,因为合并后当前分支会向前移动(快进合并)或生成一个新的合并提交,此时HEAD也随之移动。###安全注意事项-在改变HEAD之前,确保工作目录是干净的(没有未提交的修改),否则可能会丢失工作。-在分离头指针状态下,新提交不会属于任何分支,如果你切换分支,这些提交可能会被丢弃(除非你创建新的分支指向它们)。综上所述,改变HEAD指针的主要方法是切换分支或检出提交。另外,重置和分支强制移动也可以间接改变HEAD。下面我们用一个简单的例子来演示:假设我们有如下提交历史:```A--B--C(master,HEAD指向master,即提交C)```我们想将HEAD指向提交B:-方法1:分离头指针```gitcheckoutB的哈希值```此时HEAD直接指向B,不在任何分支上。-方法2:重置master分支(如果我们想回退master分支)```gitreset--hardB的哈希值```现在master分支指向B,HEAD仍然指向master。-方法3:创建新分支指向B并切换```gitbranchnew-branchB的哈希值gitcheckoutnew-branch```现在HEAD指向new-branch,而new-branch指向B。根据用户的问题,我们提供了多种改变HEAD指针的方法。用户可以根据需要选择合适的方式。为了巩固理解,我们可以提出相关问题:§§相关问题§§1.在Git中,分离头指针状态有什么作用?2.使用`gitreset`移动HEAD指针时,`--soft`、`--mixed`和`--hard`选项有什么区别?3.如何在不切换分支的情况下让HEAD指向另一个分支的最新提交?4.在改变HEAD指针时,如何避免丢失未提交的工作?</think>### 如何在 Git改变 HEAD 的指向 HEAD 是 Git 中指向当前工作位置的特殊指针,改变其指向主要有以下几种方式: #### 1. **切换分支(移动 HEAD)** ```bash git checkout <branch-name> # 传统方式 git switch <branch-name> # Git 2.23+ 推荐方式 ``` - 将 HEAD 指向目标分支的最新提交 - 工作目录会自动更新为目标分支的状态 - 示例:`git switch feature/login` [^1][^4] #### 2. **检出特定提交(分离头指针)** ```bash git checkout <commit-hash> # 如 git checkout a1b2c3d ``` - 使 HEAD 直接指向某个具体提交(而非分支) - 此时处于 "detached HEAD" 状态(不在任何分支上) - 适用于临时查看历史版本[^1][^5] #### 3. **重置当前分支(移动 HEAD 和分支指针)** ```bash git reset --soft <commit> # 仅移动 HEAD 和分支指针 git reset --mixed <commit> # 默认:同时重置暂存区 git reset --hard <commit> # 危险:重置工作目录和暂存区 ``` - 示例回退到前一个提交:`git reset --hard HEAD~1` [^4] #### 4. **恢复文件(不移动 HEAD)** ```bash git checkout HEAD -- <file> # 将文件恢复为 HEAD 指向的版本 ``` - 仅覆盖工作目录文件,不改变 HEAD 位置 - 示例:`git checkout HEAD -- config.yml` [^2] #### 注意事项: 1. 切换 HEAD 时若有未提交的修改,Git 会阻止操作(除非使用 `-f` 强制)[^1] 2. 分离头指针状态下的新提交会丢失(除非新建分支)[^5] 3. `git reset --hard` 会永久丢弃未提交的修改(谨慎使用)[^4] > **操作示意图**: > `HEAD → 当前分支 → 具体提交` > 切换分支时:`HEAD → 新分支 → 新提交` > 分离头指针时:`HEAD → 具体提交`
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值