Git advanced高级操作

news2025/4/23 13:12:40

这篇文章是继Git概念介绍,常用命令与工作流程整理 配图_TranSad的博客-CSDN博客

之后的一些补充,学习总结一些额外Git操作中的比较常用的操作。所以这篇文章假设你已经有了前面的基础,我就直接说一些没有提到过的部分。

Detached HEAD

在Git中我们通常把HEAD当成是指向当前分支的指针,但是,如果你检出(checkout)了一个不是本地分支的引用(例如一个标签(tag)、一个远程分支、一个SHA-1 ID或者一个相对引用如main~3),那么你将进入一个特殊的状态,称为"分离头指针"状态。

在"分离头指针"状态下,HEAD不再指向一个分支,而是直接指向一个提交。我们可以把这个状态想象为一个"匿名分支"。在这个状态下,你可以正常地进行提交,但是这些提交不会更新任何的命名分支。这个状态对于在提交历史中跳转很有用。例如,你可以检出一个特定版本的代码,进行编译和安装,然后再切换回主分支。

 如果你在"分离头指针"状态下做了提交,然后切换到其他分支(如main),那么你在"分离头指针"状态下做的提交可能会丢失。如果你想要保存在"分离头指针"状态下做的提交,你应该在切换分支之前,创建一个新的分支来引用这些提交。你可以使用git checkout -b name命令来创建并切换到一个新的分支。这个命令会创建一个新的分支,并把HEAD指针切换到这个新分支,这样你在"分离头指针"状态下做的提交就不会丢失了。

如果你直接checkout回main分支,那么记录就丢失了,因为在Git中,如果一个提交不被任何分支或标签引用,那么它就可能会在一段时间后被Git的垃圾回收机制删除。

Rebase

简短复习一下rebase的基础用法:如果你在你的feature分支上使用git rebase main,这个命令会将feature分支上的所有提交取出,然后在main分支的最新提交上重新应用这些提交。

而原来的提交如果不再被任何分支或标签引用,那么它们就可能会在一段时间后被Git的垃圾回收机制删除(也就是图中的odd commits部分)。因此,如果你需要保留原来的提交,你应该在rebase之前,通过git checkout -b name命令创建一个新的分支来引用(或者说是保存)这些提交,因为只要有分支引用它们,它们就不会被删除。

回到最初始的状态,如果你把命令用反了,即:git checkout main  git rebase feature,那么你就会把main分支的commit放到你的feature分支后面:

此时如果你在进行多人开发,那么你的本地仓库就和远程仓库的main分支不同了,这就会带来一些列问题,因为别人的main分支还是在那,所以rebase千万别用错了顺序,其次多人开发还是用merge更合适。下面是一个使用merge的正常工作流程:

  1. 首先,在你的本地仓库中,从主分支(main)检出一个新的分支(例如,feature),然后在这个新分支上进行开发。

  2. 当你的开发工作完成后,你可以切换回主分支,然后使用git merge feature命令将你的工作合并到主分支。这个操作会创建一个新的合并提交(merge commit)。

  3. 然后,你可以将主分支推送到远程仓库,然后在远程仓库中创建一个拉取请求(pull request)。这个拉取请求会显示你的更改,并请求项目的其他成员审查你的代码并将你的更改合并到项目的主分支。

现在我们再回到rebase,讲一下其他高级操作。

git rebase --interactive

git rebase --interactive是一个允许用户以交互方式对提交历史进行更为复杂操作的命令,包括压缩(squashing)、分割(splitting)、删除(deleting)提交等

首先来看一个简单的例子:当执行git rebase -i main(在feature分支上)时,Git会打开一个文本编辑器,列出所有将被移动(即应用到main分支上)的提交,如:

pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

每个提交前的pick表示该提交将被使用在此次rebase中。你可以通过调整这些行的顺序来改变提交的执行顺序。这些提交是从上到下执行的(在日志中看到的顺序是相反的),因此首先会将33d5b7a添加到main分支上。如果你在这里删除一行,那么相应的提交就会被丢弃。如果你删除了所有行,那么rebase操作将被中止。当你保存并关闭文件后,Git将根据你的指示执行rebase操作。

Squashing 压缩

"压缩"提交就是将一系列的提交合并成一个单独的提交。在合并功能分支到开发分支的时候,这可能非常有用。你可能有大量的小规模提交,当它们合并到开发分支时,可能会使其他开发者阅读起来感到困扰。下面是一个代码示例:假设第二个和第三个提交修复了第一个提交中的小问题,你可以使用squash命令将它们合并成一个单独的提交。

pick 33d5b7a Message for commit #1
squash 9480b3d Message for commit #2
squash 5c67e61 Message for commit #3

 

当你选择squash一个commit时,Git会将该commit的更改融入到前一个(即上面的)commit中。在你的示例中,9480b3d5c67e61这两个commit的更改都会被合并到33d5b7a这个commit中。这意味着所有这三个commit的更改都会被压缩到一个新的commit中。然后,Git会打开一个编辑器,让你为新的合并后的commit编写一个新的commit消息。这个消息通常默认为所有被压缩的commit消息的集合,但你可以根据需要进行编辑。最后,当你保存并关闭编辑器后,Git会完成rebase操作,你的commit历史中就会只有一个包含了所有更改的新commit,而原来的三个commit就不再存在了。

splitting 拆分

"拆分"提交就是将一个提交分解成多个单独的提交。如果一个提交中做了太多不同的更改,这可能会很有用。通过将那个提交拆分成一个或多个单独的提交,你的版本历史会变得更细粒度,更易于阅读和修改。以下是一个代码示例:假设你想将第二个提交分解成两个单独的提交,你可以使用edit命令来拆分。

pick 33d5b7a Message for commit #1
edit 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

Git将首先执行你的第一个提交(33d5b7a),然后应用第二个提交(9480b3d),这时发现第二个提交你使用了edit,git然后把你放在控制台中。在那里,你可以使用git reset HEAD~对那个提交进行混合重置,这实际上撤销了那个提交,并将修改的文件未暂存。现在,你可以分别暂存和提交文件到几个提交中。比如:

$ git add file_for_first_commit
$ git commit -m ‘first commit message’
$ git add file_for_second_commit
$ git commit -m ‘second commit message’
$ git rebase --continue

当你处理完edit命令后,git会处理最后的那个提交(5c67e61)。

deleting 删除

"删除"提交就是在提交历史中去除一个提交。假设第三个提交有问题,你可以使用drop命令删除它:

pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
drop 5c67e61 Message for commit #3

保存并关闭文件后,Git应用更改,并把你放回编辑器中以合并提交消息。保存后,Git将根据你的指示执行rebase。

需要注意的是,由于Git构建提交对象的方式,删除或更改一个提交将导致重写所有跟随其后的提交。你在仓库历史中回溯得越远,就需要重建越多的提交。如果在序列后面有很多依赖于你刚刚删除的提交的提交,这可能会导致大量的合并冲突。在上面的例子中我们就只删除了最后一个提交,所以就还好。

其他一些 git rebase --interactive commands:

  • p, pick <commit> = use commit
  • r, reword <commit> = use commit, but edit the commit message
  • e, edit <commit> = use commit, but stop for amending
  • s, squash <commit> = use commit, but meld into previous commit
  • f, fixup <commit> = like "squash", but discard this commit's log message
  • x, exec <command> = run command (the rest of the line) using shell
  • b, break = stop here (continue rebase later with 'git rebase--continue')
  • d, drop <commit> = remove commit
  • l, label <label> = label current HEAD with a name
  • t, reset <label> = reset HEAD to a label
  • m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] = Create a merge commit using the original merge commit's message (or the oneline, if no original merge commit was specified). Use -c <commit> to reword the commit message.

Git commit --amend

最后再补充个amend,amend关键字也很有用,大概就是如果你想更新你的最后一次提交,你可以使用git commit --amend -m “message for updated commit”命令。这个命令会将你的修改加入到最后一次提交中,并更新提交信息。

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

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

相关文章

镜面反射BRDF模型(Specular BRDF)

利用这些假设&#xff08;局部光学平坦表面&#xff0c;没有相互反射&#xff09;&#xff0c;可以很容易推导出一个被称为Microfacet Cook-Torrance BRDF的一般形式的Specular BRDF项。此Specular BRDF具有以下形式&#xff1a; 其中&#xff1a; D(h) : 法线分布函数 &#…

数据结构与算法十一 图的入门

一 图的入门 1.1 图的实际应用 在现实生活中&#xff0c;有许多应用场景会包含很多点以及点点之间的连接&#xff0c;而这些应用场景我们都可以用即将要学习的图这种数据结构去解决。 地图&#xff1a; 我们生活中经常使用的地图&#xff0c;基本上是由城市以及连接城市的道…

【Nginx高级篇】nginx扩容

目录 一、单机垂直扩容&#xff1a;硬件资源增加 二、水平扩展&#xff1a;集群化 &#xff08;一&#xff09;会话管理 1、Nginx高级负载均衡 2、使用sticky模块完成对Nginx的负载均衡 3、keepalive &#xff08;二&#xff09;upstream的工作流程 &#xff08;三&…

为什么别人家的ChatGPT比我家的更聪明?

文章目录 引子使用技巧技巧1&#xff1a;使用分隔符技巧2&#xff1a;结构化输出技巧3&#xff1a;整理操作步骤技巧4&#xff1a;做示范技巧5&#xff1a;给定具体的步骤技巧6&#xff1a;生成摘要技巧7&#xff1a;情感分析 好问题的三要素总结 引子 你有没有发现&#xff0…

ENVI自动地理配准栅格图像(至少一一幅图像含有地理信息)

本文就介绍一种在ENVI 5.3 (64-bit) 软件中&#xff0c;自动生成地面控制点&#xff0c;从而对遥感影像进行地理配准的方法。 我们先来看一下本文需要实现的需求。现有以下两景遥感影像&#xff0c;其中一景含有地理参考信息&#xff0c;而另一景则不含有任何地理参考信息。在…

STL常用容器_1

目录 一、string容器 1、基本概念 2、构造函数 3、赋值操作 4、字符串拼接 5、查找和替换 6、字符串比较 7、字符存取 8、插入与删除 9、获取字串 二、vector容器 1、基本概念 2、构造函数 3、赋值操作 4、容量和大小 5、插入和删除 6、数据存取 7、互换容器…

Apache Hive

Hive的概念 Hive是Facebook开源出来&#xff0c;后来贡献给力Apache .宗旨是&#xff1a;提高分析数据的能力降低分析数据的开发成本。 Hive是基于 Hadoop 的一个数据仓库工具&#xff0c;用于分析数据的。 为什么说Hive是基于Hadoop的呢&#xff1f; ​ #作为一款数据仓库软件…

依次对两数组对应位置的元素进行逻辑判断numpy.logical_and()numpy.logical_or()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 依次对两数组对应位置的元素进行逻辑判断 numpy.logical_and() numpy.logical_or() [太阳]选择题 下列代码中np.logical_or(A, B)输出的结果是&#xff1f; import numpy as np A [True, Fa…

R语言 | 正态分布

目录 一、用直方图检验crabs对象 二、用直方图检验beaver2对象 三、用QQ图检验数据是否服从正态分布 四、shapiro.test()函数 所谓正态分布又称高斯分布&#xff0c;许多统计学的理论都是假设所使用的数据服从正态分布。 一、用直方图检验crabs对象 检验数据是否服从正态分…

Kubernetes❀ 详细教程-介绍

Kubernetes❀ 详细教程-介绍 Kubernetes详细教程-介绍1. Kubernetes介绍1.1 应用部署方式演变1.2 kubernetes简介1.3 kubernetes组件1.4 kubernetes概念 Kubernetes详细教程-介绍 1. Kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个…

c++ 一个简单的请求程序

https://github.com/AHUT-GeekTeam/ESP32CAM_BaiduAI/blob/master/demo.ino HTTP格式 请求行 回车换行请求头 回车换行请求头 回车换行请求头 回车换行……请求头 回车换行 回车换行数据 jichu daima 参考黑马程序员的代码MAIN.C #include "b.h" //#include <p…

威纶通触摸屏复合式多功能按钮的使用方法

威纶通触摸屏复合式多功能按钮的使用方法 如下图所示,打开easy builder pro软件,新建一个测试项目,在元件中找到复合式多功能按钮,点击后放入画面中, 如下图所示,此时会弹出以下窗口,在动作中点击“+”图标,选择自己需要添加的动作, 如下图所示,首先添加一个位状…

C++类与对象—下

本期我们继续学习类与对象&#xff0c;没有看过上和中的小伙伴建议先看前两期内容 (2条消息) C类与对象—上_KLZUQ的博客-CSDN博客 (2条消息) C类与对象—中_KLZUQ的博客-CSDN博客 目录 1.再谈构造函数 1.1构造函数体赋值 1.2初始化列表 1.3 explicit关键字 2. static成员…

学成在线笔记+踩坑(12)——用户认证

导航&#xff1a; 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线牛客面试题 目录 1 需求分析 2 【认证模块】连接用户中心数据库 2.1 连接数据库认证 2.1.1 分析 2.1.2 实现&#xff0c;实现UserDetailsService接口 …

Golang每日一练(leetDay0064) 轮转数组、颠倒二进制位

目录 189. 轮转数组 Rotate Array &#x1f31f;&#x1f31f; 190. 颠倒二进制位 Reverse Bits &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 189. 轮转数组 Rotate Ar…

小曾同学【五周年创作纪念日】——努力向前冲的菜鸟

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c; 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。&#x1f60a; 座右铭&#xff1a;不想当开发的测试&#xff0c;不是一个好…

什么是UA?常见蜘蛛UA?怎么查询UA?

什么是UA? UA简介查看自己的UA修改它的常见用处搜索引擎蜘蛛UA大全常见蜘蛛UA标识 UA简介 UA其实是User Agent的简称。 所谓的User Agent其实就是浏览器在跟服务器通信的时候&#xff0c;一段百十来个字符的落款信息罢了。浏览器发送的每一个HTTP请求数据的头部都加了这个信息…

【C++】红黑树的插入分析及验证

文章目录 1. 红黑树概念2. 红黑树性质3. 结构定义关于默认节点为红/黑色的讨论 4. insert情况1—— uncle节点存在且为红色(g p c左斜形成一条直线)情况2——uncle节点不存在/存在且为黑色(g p c 左斜形成直线 右单旋)uncle节点不存在uncle节点存在并且为黑色 情况3——uncle节…

第7章链接:编译器驱动程序

示例程序由两个源文件组成&#xff0c;main.c 和 swap.c。 main函数初始化一个两元素的整数数组&#xff0c;然后调用swap函数来交换这一对数。 main.c void swap();int buf[2] {1, 2};int main() {swap();return 0; }swap.c extern int buf[];int *bufp0 &buf[0]; i…

【Java】Java中线程安全有哪些实现思路?

文章目录 1、使用 synchronized 关键字2、使用 ReentrantLock 类3、使用 ConcurrentHashMap 类4、使用 Atomic 类5、使用 ThreadLocal 类总结 在 Java 多线程编程中&#xff0c;线程安全是一个非常重要的概念。 线程安全通常指程序在多线程并发执行时&#xff0c;仍然能够保持正…