更直观地学习 Git 命令


theme: condensed-night-purple

前言

本文参考于 Learn Git Branching 这个有趣的 Git 学习网站。

在该网站,可以使用 show command 命令展示所有可用命令。

你也可以直接访问网站的sandbox,自由发挥。

本地篇

基础篇

git commit

git commit将暂存区的修改提交到本地版本库并创建一个新的提交,新提交会指向前一个提交。

git commit -m "C2"

在这里插入图片描述

main分支是默认主分支。*表示当前分支所在,也是HEAD指针指向。我们的提交记录会提交到当前分支。

直接运行git commit会打开Git默认编辑器。

git branch

git branch在此前工作的基础上创建新的分支来指向当前的提交,以此来进行新的工作。

创建一个名为newImage的分支:

git branch newImage

在这里插入图片描述

*号依然位于main,说明当前分支仍然是main

使用以下命令切换到新分支上:

git checkout newImage

在这里插入图片描述

Git 2.23 版本引入了 git switch <branch-name> 命令来取代 git checkout命令众多功能中的切换分支功能。

最后,git branch <branch-name>git checkout <branch-name>可以合并为一条命令:

git checkout -b <branch-name>

git merge

在新建分支开发完新功能或修复完 Bug 后,我们可以将其合并回主分支。

合并bugFix分支到main分支:

git merge bugFix

在这里插入图片描述
非快进合并

可以看到,合并分支时创建了新提交,新提交的parent提交是两个分支合并之前的最新提交。

再把main分支合并到bugFix

git switch bugFix
git merge main

在这里插入图片描述
快进合并(Fast Forward)

git rebase

git rebase是另一种分支合并的方式,称为变基,具体是把一系列的提交记录复制到另一个地方。

使用git rebase可以使得提交历史更加线性。

git rebase main

在这里插入图片描述

git rebase main将当前分支(*所在)bugFix从与main分支的公共祖先提交部分开始的提交记录复制到以main分支的最新提交为起始的地方,但复制不是真的复制,是解决冲突后的复制,如图复制后的C3'提交已经与原提交C3不同了。

git rebase main中的main就是基分支,当前分支bugFix就是变基分支

我们可以写成,git rebase main bugFix来主动指定基分支和变基分支。

高级篇:在提交树上移动

HEAD 简介与 HEAD 分离

HEAD 是一个指针,通常指向当前分支名,偶尔也会指向当前提交。

git checkout C1 # 切换到 C1 提交
git checkout main # 切换到 main
git commit -m "C2" # HEAD 指向的 main 指向 C2
git checkout C2 # 切换到 C2 提交

在这里插入图片描述

git checkout C1这样将 HEAD 指针指向提交C1的行为称为 HEAD 分离(Detached HEAD)。分离前,HEAD 指向的是分支引用 main

git checkout C1中的C1其实是提交的HASH值。

查看提交记录的哈希值

git log

在这里插入图片描述

HASH 值很长,但我们只需要其前面几位可以唯一标识提交的即可,例如63dbb453fbae3d151622f4e91d3aadf90069552d我们取63dbb

查看 HEAD 指向

cat .git/HEAD

如果 HEAD 指向引用而非提交,也可以像下面查看 HEAD 指向:

git symbolic-ref HEAD

在这里插入图片描述

相对引用

前文使用 HASH 值来指定提交记录,这也叫做直接引用,难免不方便,Git 提供了相对引用的方式来指定提交:

  • <branch-name>^branch-name指向的提交的上一个提交。
  • <branch-name>^^branch-name指向的提交的前面第二个提交。
  • <branch-name>~<num>branch-name指向的提交前面第num个提交。
git checkout main^

在这里插入图片描述

强制修改分支位置

除了切换分支,相对引用用的最多的地方是移动分支。

git branch -f main HEAD~3

在这里插入图片描述

如果要移动的分支不存在会自动创建。

撤销变更

git reset

git reset回退到直接引用或相对引用指向的提交记录,之后的提交记录就撤销了。

git reset HEAD^

在这里插入图片描述

C2提交被reset后,就不存在于本地版本库中,但是其变更还在,只不过处于未暂存状态。

git reset只对本地分支有效,无法回退远程分支。

进行git reset后,如果进行推送,Git 会提示远程仓库较新需要git pull,你的代码被远程仓库覆盖。如果想要回退生效,则需要追加-f进行强制推送。

git revert

reset 英文意思有“复位”。

revert 英文意思有“恢复”。

git revert会创建新提交来撤销更改,它与待撤销提交的前面某个提交内容是相同的。

git revert HEAD

在这里插入图片描述

移动提交记录

git cherry-pick

git chery-pick用于把一些提交复制到当前提交(HEAD)的下面。

git cherry-pick C2 C4

在这里插入图片描述

交互式 rebase

git rebase 后追加 --interactive-i 选项会打开一个窗口(你配置的编辑器)显示将要被复制到目标分支的提交的哈希值和提交说明。

一个打开的示例窗口如下:

pick 63dbb45 2# Rebase 88e2af2..63dbb45 onto 88e2af2 (1 command)
#
# 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 [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# 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
# u, update-ref <ref> = track a placeholder for the <ref> to be updated
#                       to this position in the new commits. The <ref> is
#                       updated at the end of the rebase
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

在这里插入图片描述
使用git rebase经常会遇到要解决冲突的情况,解决冲突后,执行git addgit rebase --continue

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

杂项

只复制一个提交

有时候,我们开发完一个功能,需要与主分支进行合并时,会希望只合并我想要的那个提交。

我们知道,使用git merge的合并有快进合并和非快进合并两种。但是这两种合并会将我们不需要的提交也包含在主分支中。

这时候,我们可以使用git cherry-pickgit rebase -i来完成。

在这里插入图片描述

如上图,我想要将修复问题后的提交bugFix合并到main

如果使用git merge

git checkout main
git merge bugFix

在这里插入图片描述

这使得主分支 main 中就包含了 C2、C3 这些提交。

使用git cherry-pick

git checkout main
git cherry-pick C4
git branch -f bugFix main

在这里插入图片描述

修改前面的提交但不在主分支创建新提交 1

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这样做就唯一的问题就是要进行两次排序,而这有可能造成由 rebase 而导致的冲突。

修改前面的提交但不在主分支创建新提交 2

在这里插入图片描述

git checkout main
git cherry-pick C2
git commit --amend
git cherry-pick C3

在这里插入图片描述

git tag

git tag为提交记录打上标签,它可以像分支一样引用,但不会像分支一样移动。

git tag V1

在这里插入图片描述

git tag V2 C0

在这里插入图片描述

git describe

git describe查找离指定引用最近的标签。

在这里插入图片描述

在这里插入图片描述

git describe <ref>输出格式:<tag>_<numCommits>_g<hash>

高级话题

多次 rebase

在这里插入图片描述

git checkout another
git rebase side
git rebase bugFix
git rebase main
git branch -f main another

在这里插入图片描述

相对引用^中选择 parent 提交记录

相对引用^可以像~一样在后面加个数字,该数字是选择第几个 parent 提交记录。

git checkout main^2

在这里插入图片描述

^~的链式操作;

git checkout HEAD~^2~2

在这里插入图片描述

纠缠不清的分支

在这里插入图片描述

git checkout one
git cherrt-pick C4 C3 C2
git checkout two
git cherrt-pick C5 C4 C3 C2
git branch -f three C2

在这里插入图片描述

远程篇

Git 远程仓库基本操作

git clone

git clone <远程仓库URL>

远程仓库实际上就是你的本地仓库在另一台电脑上的拷贝。

git clone从远程仓库克隆一个副本到本地。

在这里插入图片描述

远程分支

上一节中的克隆产生的o/main分支就是远程分支,o是远程仓库名。你使用git clone克隆完一个仓库时,已经将远程仓库名设置为origin了。

查看远程仓库信息:

git remote -v

修改远程仓库名:

git remote rename <远程仓库名>

远程分支反映了远程仓库的状态。

切换到远程分支会自动切换到 HEAD 分离状态。

git checkout o/main

在这里插入图片描述

git fetch

git fetch <远程仓库URL>

git fetch从远程仓库下载缺失的提交记录,并更新远程分支指针。实际上就是更新远程分支。

但是git fetch不会改变你的本地分支状态,也就是不会改变你的本地仓库文件。

在这里插入图片描述

git fecth

在这里插入图片描述

git pull

使用git fetch只更新了远程分支,并未更新本地分支,还需要我们进行进一步合并,使用下面方法之一:

  • git cherry-pick origin/main
  • git merge origin/main
  • git rebase origin/main

不过,Git 的 git pull 命令将拉取和合并操作结合在了一起。

在这里插入图片描述

在这里插入图片描述

git pullgit fetchgit merge的结合。

git push

git push 不带任何参数时的行为与 Git 的一个名为 push.default 的配置有关。

查看 push.default 值。

git config --get push.default

push.default 通常具有以下几种值:

  • simple:这是 Git 2.0 及以后版本的默认值。它会将当前分支的 push 操作限制为其上游(通常是 origin 远程仓库)的同名分支。
  • current:这也是一个常见的值,它将 push 操作限制为当前分支。
  • nothing:这个选项会禁用默认的 push 行为,您需要明确指定要 push 的分支和远程仓库。
  • matching:在 Git 1.x 版本中的默认行为,它会将本地的所有分支与远程仓库的同名分支进行匹配,然后将它们都 push 到远程仓库。

修改 push.default

git config push.default <new_value>

在这里插入图片描述

git push 后还更新了 o/main 的位置。

偏离的提交历史

当你使用 git push 推送代码时,会遇到无法推送,要先与远程仓库合并的提示。这是由于远程仓库已经被你的同事修改了,你调用 API 可能已经不存在或改名了,也就是发生了冲突。

在这里插入图片描述

如何解决冲突?

① 使用 git rebase

git fetch
git rebase o/main
git push o main

在这里插入图片描述

② 使用 git merge

git fetch
git merge o/main
git push o main

在这里插入图片描述

使用 git merge 会多一个合并提交。

当然 git fetchgit merge 可以合并为 git pull

③ 使用 git pull --rebase,即 git fetchgit rebase 的结合

git pull --rebase
git push

锁定的 main

Git 锁定 main 分支是防止主分支遭到未经审核的修改。

如果你直接提交到 main,然后 push,不仅会被拒绝,还会无法再次推送。

你需要 reset main 分支到远程分支处,与远程服务器保持一致。然后新建一个 feature 分支,推送 feature 分支到服务器。

Git 远程仓库高级操作

推送主分支

在这里插入图片描述

在这里插入图片描述

想想如何完成。

使用 git mergegit rebase 都行,仁者见仁智者见智。

远程追踪

main 分支默认指定为跟踪远程分支 origin/main跟踪地意思是指定了 origin/main 为 push 的目的地和 fetch 后合并的目标。

如何自己设置分支跟踪远程分支?

方式一

git checkout -b <local branch> <remote branch>

比如 git checkout -b foo origin/main

方式二:

git branch -u <remote branch> <local branch>

例如 git branch -u origin/main foo,如果当前就在 foo 分支,还可以省略 foo

git push 的参数

实际 git push 的语法是:

git push <remote> <place>

意思是将 remote 的 place 分支没有的而本地 place 分支有的提交记录添加到 remote 的 place 分支。不仅会更新远程的 place 分支,也会更新本地的 remote/place 分支。

git push 没有参数时,会根据当前分支和它所追踪的远程分支来自动设置参数。

git push 的参数 2

将本地 source 分支推送到远程仓库的 destination 分支:

git push origin <source>:<destination>

准确地说,source 不一定是分支,也可能是标签、提交的 HASH 部分值和相对引用等等 Git 可以识别的位置。

如果目的分支 destination 不存在怎么办?

Git 会帮你自动创建的。

git fetch 的参数

git fetch origin foo

拉取远程仓库 origin 的远程分支 foo 的新提交,并放到本地的远程追踪分支 origin/foo 上,而不会影响 foo 分支。

也可以使用 <source>:<destination> 的参数格式:

git fetch origin foo~1:bar

上面命令的作用是将远程 foo 分支的上一个提交拉取到本地的 bar 分支上。

动画.gif

如果 bar 分支不存在就新建,这个和 git push 的参数行为是一致的。

没有指定参数的 git fetch 则会拉取所有提交记录。

source 参数为空的 git push 和 git fetch

1)git push orgin :foo

动画.gif

传空值 source 删除了远程的 foo 分支,连带着删除了本地的 origin/foo 分支。

2)git fetch origin :foo 则会在本地新创建一个 foo 分支。

git pull 的参数

git pull 是 git fetch 和 git merge 的结合体。

git pull origin foo 相当于

git fetch origin foo
git merge origin/foo

git pull origin foo^:bar 相当于

git fetch origin foo^:bar
git merge bar

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

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

相关文章

MySQL学习笔记23

逻辑备份&#xff1a; 1、回顾什么是逻辑备份&#xff1f; 逻辑备份就是把数据库、数据表或者数据进行导出&#xff0c;导出到一个文本文件中。 2、逻辑备份工具&#xff1a; mysqldump&#xff1a;提供全库级、数据库级别以及表级别的数据备份。 mysqldumpbinlog&#xff…

苹果签名有多少种类之TF签名(TestFlight签名)是什么?优势是什么?什么场合需要应用到?

&#xff08;一&#xff09;TestFlight 能够让您&#xff1a;邀请内部和外部的测试人员为应用程序提供反馈。 跟踪应用程序在测试过程中发现的 bug 和用户体验问题。 收集 Crash 报告&#xff0c;了解应用程序在真实设备上的运行状况。 要使用 TestFlight&#xff0c;您可以按照…

[Spring] Spring5——AOP 简介

目录 一、AOP 简介 1、什么是 AOP 二、AOP 底层原理 1、动态代理原理 2、基于接口的 JDK 动态代理 3、基于继承的 CGLib 动态代理 三、底层原理实现—— JDK 动态代理 1、使用 Proxy 类的方法创建代理对象 2、JDK 动态代理示例 四、AOP 操作术语 1、连接点 2、切入…

docker安装apisix全教程包含windows和linux

docker安装apisix 一、Windows安装1、首先需要安装docker和docker compose&#xff0c;如果直接安装docker desktop&#xff0c;会自动安装docker compose。2、重新启动电脑3、访问 Docker 的下载&#xff08;[https://www.docker.com/products/docker-desktop](https://www.do…

Java类型转换和类型提升

目录 一、类型转换 1.1 自动类型转换&#xff08;隐式&#xff09; 1.1.1 int 与 long 之间 1.1.2 float 与 double 之间 1.1.3 int 与 byte 之间 1.2 强制类型转换&#xff08;显示&#xff09; 1.2.1 int 与 long 之间 1.2.2 float 与 double 之间 1.2.3 int 与 d…

Docker01基础操作

目录 1、docker 发展历史 2、Docker 概述 2.1 容器 2.2 Docker与虚拟机的区别 2.3 容器在内核中支持2种重要技术 2.4 namespace的六项隔离 2.5 Docker核心概念 2.6 安装 Docker 2.7 Docker 镜像操作 2.8 Docker 容器操作 2.9 面试题 1、docker 发展历史 https://www.…

IO学习系列之使用多进程复制同一个文件内容

实例要求&#xff1a;使用多进程复制同一个文件内容&#xff1b;实例分析&#xff1a;1.创建一个父进程和一个子进程&#xff0c;设置光标在指定文件中的偏移量&#xff0c;实现对同一个文件的复制。2.比如&#xff1a;可以指定子进程复制文件内容的前一半&#xff0c;而父进程…

nvm 管理 node版本

下载地址 https://nvm.uihtm.com/download.html 基础命令 查看所有可安装的node版本 nvm list available 查看本地已经安装的所有版本&#xff1a; nvm list 安装指定的node版本 nvm install 14.18.1 使用指定node版本 nvm use 14.18.1 卸载指定node版本 nvm uninstall …

【网络编程】UDP数据报套接字编程和TCP流套接字编程

文章目录 1. 网络编程基础1.1 为什么需要网络编程&#xff1f;1.2 网络编程是什么&#xff1f;1.3 概念 2. Socket套接字3. UDP数据报套接字编程3.1 DatagramSocket API3.2 DatagramPacket API3.3 InetSocketAddress API 4. UDP构建服务端客户端&#xff08;一发一收&#xff0…

【Java-LangChain:使用 ChatGPT API 搭建系统-10】评估(下)-当不存在一个简单的正确答案时

第十章&#xff0c;评估&#xff08;下&#xff09;-当不存在一个简单的正确答案时 在上一章中&#xff0c;了解了如何评估 LLM 模型在 有明确正确答案 的情况下的输出&#xff0c;我们可以编写一个函数来判断 LLM 输出是否正确地分类并列出产品。 然而&#xff0c;如果 LLM …

文本分词排序

文本分词 在这个代码的基础上 把英语单词作为一类汉语&#xff0c;作为一类然后列出选项 1. 大小排序 2. 小大排序 3. 不排序打印保存代码 import jieba# 输入文本&#xff0c;让我陪你聊天吧~ lines [] print("请输入多行文本&#xff0c;以\"2333.3\"结束&am…

osg实现鼠标框选

目录 1. 需求的提出 2. 具体实现 2.1. 禁止场景跟随鼠标转动 2.2. 矩形框前置绘制 3. 附加说明 3.1. 颜色设置说明 3.2.矩形框显示和隐藏的另一种实现 1. 需求的提出 有时需要在屏幕通过按住键盘上的某个键如Ctrl键且按住鼠标左键&#xff0c;拖出一个矩形&#xff0c;实现框…

ValueError: check_hostname requires server_hostname

使用jupyter 下载js2py 异常 !pip install js2py ValueError: check_hostname requires server_hostname 一开始以为是数据源问题&#xff0c;切换阿里云 还是这个异常 结果发现是开魔法导致的&#xff0c;关闭魔法即可

Redisson集群管理工具、对Redis节点的操作

一、集群管理工具 Redisson集群管理工具提供了通过程序化的方式&#xff0c;像redis-trib.rb脚本一样方便地管理Redis集群的工具。 1、 创建集群 以下范例展示了如何创建三主三从的Redis集群。 ClusterNodes clusterNodes ClusterNodes.create() .master("127.0.0.1:…

怒刷LeetCode的第23天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;贪心算法 方法二&#xff1a;动态规划 方法三&#xff1a;回溯算法 方法四&#xff1a;并查集 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;排序和遍历 方法二&#xff1a;扫描线算法 方法…

【Java-LangChain:使用 ChatGPT API 搭建系统-3】评估输入-分类

第三章 评估输入-分类 在本章中&#xff0c;我们将重点讨论评估输入任务&#xff0c;这对于确保系统的质量和安全性至关重要。 对于需要处理不同情况下的许多独立指令集的任务&#xff0c;首先对查询类型进行分类&#xff0c;并以此为基础确定要使用哪些指令&#xff0c;具有…

英伟达NVIDIA驱动安装

一般&#xff0c;我们新的显卡上机或者新系统可能就需要重新安装显卡驱动。或者是我们在配置深度学习环境时候&#xff0c;需要手动安装驱动。 官网地址&#xff1a;官方高级驱动搜索 | NVIDIA 我们选择好自己需要的驱动后直接安装即可 下载的时候&#xff0c;选择自己需要的驱…

计算机竞赛 深度学习卷积神经网络垃圾分类系统 - 深度学习 神经网络 图像识别 垃圾分类 算法 小程序

文章目录 0 简介1 背景意义2 数据集3 数据探索4 数据增广(数据集补充)5 垃圾图像分类5.1 迁移学习5.1.1 什么是迁移学习&#xff1f;5.1.2 为什么要迁移学习&#xff1f; 5.2 模型选择5.3 训练环境5.3.1 硬件配置5.3.2 软件配置 5.4 训练过程5.5 模型分类效果(PC端) 6 构建垃圾…

第一篇:数组定义JavaScript

数组的定义 数组是一种特殊的变量&#xff0c;能够用来一次存放一个以上的值。 一维数组的定义 //使用字面量[]方式定义 var arr [1,2,3] console.log(arr)//1,2,3使用构造函数的方式定义 var arr new Array()//定义了一个空数组 var arr new Array(10)//定义了长度为1…

微服务网关:Spring Cloud Zuul 升级 Spring Cloud Gateway 的核心要点

1. 服务路由 1.1. Zuul 接收请求&#xff1a; 在routes路由规则中&#xff0c;根据path去匹配&#xff0c;如果匹配中&#xff0c;就使用对应的路由规则进行请求转发如果无法从routes中匹配&#xff0c;则根据path用“/”去截取第一段作为服务名进行请求转发&#xff0c;转发…