惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
G
Google Developers Blog
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Engineering at Meta
Engineering at Meta
B
Blog
博客园_首页
量子位
博客园 - 叶小钗
L
LangChain Blog
T
The Blog of Author Tim Ferriss
云风的 BLOG
云风的 BLOG
Blog — PlanetScale
Blog — PlanetScale
F
Fortinet All Blogs
S
SegmentFault 最新的问题
宝玉的分享
宝玉的分享
D
DataBreaches.Net
雷峰网
雷峰网
The Cloudflare Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
TaoSecurity Blog
TaoSecurity Blog
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
The GitHub Blog
The GitHub Blog
I
Intezer
H
Help Net Security
The Hacker News
The Hacker News
The Register - Security
The Register - Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
AWS News Blog
AWS News Blog
V
V2EX
Microsoft Security Blog
Microsoft Security Blog
T
Tenable Blog
Spread Privacy
Spread Privacy
A
Arctic Wolf
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
Schneier on Security
Schneier on Security
C
CERT Recently Published Vulnerability Notes
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Last Watchdog
The Last Watchdog
Latest news
Latest news
T
Troy Hunt's Blog
L
LINUX DO - 热门话题

Dejavu's Blog

甲骨文 ARM 实例部署 Gemma 4 模型 Headscale + Tailscale 组建虚拟专用网 在 Linux 上使用 Yubikey OpenPGP 应用 BuyVM VPS 块存储挂载教程 Alpine Linux 服务器配置指南 Alpine Linux 安装 Cloudflared Docker 多容器共享中心数据库 安装 Komari 服务器监控工具 Scaleway VPS 安装 Debian Linux Debian 13 下部署 AsmBB 论坛 使用 Kopia 自动化备份服务器数据 给 Docker 启用 IPv6 支持 Netcup 服务器安装自定义 ISO 镜像 烽火 HG5582A 光猫开启桥接模式 Docker 自托管 Shlink 短链服务 部署 Obsidian LiveSync 实时同步服务指南 我的 2025 年不完全回顾 Linux 下 Intel 核显驱动配置与硬件加速 Fedora Linux 安装配置记录 2025 年优雅地自托管 RSS 服务 Woodpecker CI 和 Gitea 实现 Hugo 自动部署 Gitea/Forgejo 集成 Woodpecker CI/CD 在 Blinko 中使用 Ollama 作为 AI 供应商 Docker 部署 Gitea/Forgejo Plausible CE 启用城市级地理位置识别 Blinko 开源 AI 知识库 Docker 部署指南 Netcup 免税账号注册及购买服务器全记录 Docker 自托管 Cloudreve Pro 私有网盘服务 GiffGaff SIM 卡使用体验和注意事项 简体中文互联网在变得糟糕吗? 如何低成本申请 S/MIME 证书用于个人邮件服务 迁移到 NameCrane Mail 域名邮箱套件服务 香烟与咖啡 在 Windows 中使用 Yubikey 的 OpenPGP 应用 Windows 11 IoT LTSC 养老指南 巧用浏览器生成 HAR 文件批量下载所需网页资源 聊聊静态网站的评论系统 在 Hugo 站点中优雅地展示实况照片 使用 snac 部署一个简洁优雅的 ActivityPub 实例 当 25 岁来临的时候 断网的这两年 从 Bitwarden/Vaultwarden 到 KeePassXC 也许是 Android 上最好的本地播放器 - 椒盐音乐 2023 半年小结 写一个好玩的 Hugo 货币汇率转换短代码 写一个 Hugo 短代码将不同类别的总字数统计转换为书名显示 海信 Touch Lite 墨水屏音乐阅读器的简单体验 从 Debian 11(bullseye) 无感升级到 Debian 12(bookworm) 使用 GitHub Actions 自动提交 URL 到 IndexNow 批量重写 Git 历史提交记录 使用 cgit 托管小小的也很可爱的 Git 服务器 在 Debian 上使用 stagit 和 Nginx 的简单 Git 服务器 托管简单 Git 服务器的一些尝试 使用 stagit 自托管纯静态 Git 存储库 使用 Docker 快速部署单人 Fediverse 实例 我是如何建立自己的个人博客的? 简单、隐私友好的谷歌分析替代品,Plausible 自托管部署指南 服务器使用 Cloudflare CDN 的最佳实践 甲骨文服务器分配并启用 IPv6 地址 Cloudflare WAF 防护策略简易指南 Mastodon 服务器批量导入自定义表情 低成本自托管 Mastodon 实例简明指南 自托管服务指南──有了服务器可以做什么? 使用 Miniflux + RSSHub 打造个人 RSS 阅读器 构建支持多种 CPU 架构的 Docker 镜像 一个可自托管的静态短链接应用 别了,二〇二二! Duplicacy CLI 进阶使用指南 Duplicacy CLI 备份工具的基本使用 初探 Cloudflare 零信任 - 通过 Docker 部署 Bitwarden 密码管理器 Yubikey 转运日志及上手指南 初探 Cloudflare 零信任 — 通过 Cloudflare Tunnel 搭建 SSH 聊天室 初探 Cloudflare 零信任 - 通过 Cloudflare Tunnel 访问服务 某科学的 PGP 算号指南 2022 年的 MacBook Air M1 使用体验及应用推荐 使用 Vercel 和 Supabase 自托管 Cusdis 评论系统 为什么你的搜索引擎不好用? 个人在 Windows 上常用软件清单 macOS 基础开发环境设置指南 在 macOS 上使用 Canokey 的 OpenPGP 应用 提取 Windows UWP 应用商店的安装包以供离线安装 Git 版本控制学习笔记(一) 使用 Notion 管理 GitHub Star 项目 使用 Vercel 免费部署 Giscus 评论系统 将博客评论从 Utterances 无缝迁移到 Giscus Canokey 签名和认证应用指南 Canokey 的基本使用指南 Canokey Pigeon 揽件日志及简单开箱 关于 Google Play 保护机制和 DRM 安全等级的那些事 记录一次捡垃圾装机 GitHub 使用 GPG 密钥提交签名认证 使用 Scoop 管理 Windows 下的软件和开发环境 Windows Terminal+PowerShell 7 打造 Windows 下最好用的终端 一个好用的 Telegram 文件批量上传/下载工具 Clash for Windows 优雅地使用 TUN 模式接管系统流量 全平台搭建 Hexo 静态博客指南 尝试将 Manjaro 作为主力操作系统使用 Hexo 进行 SEO 优化的基本指南 使用本地代理给 Git 和 NPM 加速 使用 flowerss 部署 Telegram RSS 订阅机器人
Git 版本控制学习笔记(二)
Dejavu Moe · 2023-02-25 · via Dejavu's Blog

准备

在本文中,我们使用 GitHub 作为远程仓库服务器,先创建一个新的 Git 远程仓库,我们的 Git 之旅从这里开始。本文记录过程中,创建的远程仓库: MoeOffice/Git-Travel

Git 中的命令和参数繁多且灵活,不可能全部都记得,本文在 ChatGPT 的帮助下完成,作为方便自己日后查阅的 Cheat Sheet

git init 初始化

在本地初始化一个 Git 仓库

mkdir Git-Travel
cd Git-Travel
git init
# 输出
Initialized empty Git repository in /Users/dejavu/MoeOffice/Git-Travel/.git/

git remote 远程仓库

git remote 命令用于管理本地 Git 仓库与远程仓库之间的连接

add 添加

添加远程仓库,用法

git remote add <name> <url>

# 比如
git remote add origin [email protected]:MoeOffice/Git-Travel.git

注意: origin是默认的远程仓库名称,通常是指 Git 仓库的主机或者托管平台。当你使用 git clone 命令从一个远程 Git 仓库中克隆代码库时,Git 会自动为你设置一个名为 origin 的远程仓库,以便在将来能够与原始代码库进行交互。

通常情况下,origin 是指向远程代码仓库的 URL 地址,通过它可以访问和操作远程代码库。在进行 Git 操作时,你可以使用 origin 来指代远程代码库,例如 git push origin master 表示将本地分支的变更推送到远程仓库 origin 上的 master 分支。

需要注意的是,origin 只是一个默认的远程仓库名称,你可以使用其他名称来代替它。当你需要与多个远程仓库交互时,可以使用不同的名称来标识它们,例如 git remote add upstream <url> 可以将一个新的远程仓库添加到本地仓库中,并指定它的名称为 upstream

remove 删除

从本地 Git 仓库删除远程仓库

git remote remove <name>

# 比如
git remote remove origin

# 现在查看信息,应该输出为空
git remote -v

为了继续学习,我们将远程仓库添加回来

rename 重命名

重命名远程仓库

git remote rename <old-name> <new-name>

# 比如
git remote rename origin upstream

# 现在查看信息
git remote -v
upstream	[email protected]:MoeOffice/Git-Travel.git (fetch)
upstream	[email protected]:MoeOffice/Git-Travel.git (push)

为了继续学习,我们将远程仓库命名改回来

git remote rename upstream origin

git pull 拉取

我在远程仓库做了一些更改,现在我想让本地仓库同步这些更改,用法

git pull <remote> <branch>

# 比如
git pull origin master
From github.com:MoeOffice/Git-Travel
 * branch            master     -> FETCH_HEAD

git push 推送

我在本地仓库做了一些更改

# 先提交更改
git add . 
git commit -m 'add push.txt'
[master f6e02ff] add push.txt
 1 file changed, 1 insertion(+)
 create mode 100644 push.txt

现在要把本地仓库的更改推送到远程仓库用法

git push <remote> <branch>

# 比如
git push origin master
# 输出
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 467 bytes | 467.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:MoeOffice/Git-Travel.git
   c8fa602..f6e02ff  master -> master

使用 git push 删除远程仓库

# 方式一:推送删除远程仓库
git push origin --delete need-deleted
# 输出
To github.com:MoeOffice/Git-Travel.git
 - [deleted]         need-deleted
 
# 方式二:推送一个空分支到远程仓库
git push origin :another-need-deleted
# 输出
To github.com:MoeOffice/Git-Travel.git
 - [deleted]         another-need-deleted

git fetch 获取

现在有其他协作人员修改了远程仓库(新的代码提交、新的分支或标签),这时候我就可以从远程仓库获取最新的信息(但不会自动合并到本地分支),用法

git fetch <remote>

# 比如
git fetch origin master

# 或者直接 git fetch (因为我们现在只有一个远程仓库)
git fetch
# 输出
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 582 bytes | 194.00 KiB/s, done.
From github.com:MoeOffice/Git-Travel
 * [new branch]      master     -> origin/master

git fetch -p 获取远程仓库最新信息,并执行「修剪」操作,比如删除已经不存在的远程分支引用,下面是个例子

# 模拟情况
# 新建一个分支
git checkout -b push/need-p 
# 推送分支
git push
# 输出
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'push/need-p' on GitHub by visiting:
remote:      https:#github.com/MoeOffice/Git-Travel/pull/new/push/need-p
remote:
To github.com:MoeOffice/Git-Travel.git
 * [new branch]      push/need-p -> push/need-p
branch 'push/need-p' set up to track 'origin/push/need-p'.

# 切换回主分支 master
git checkout master

现在我们在远程仓库删除这个分支 push/need-p,查看现在的本地分支

git branch -a

# 输出
  dev
* master
  new-branch
  push/need-p	# 注意这里
  remotes/origin/dev
  remotes/origin/master
  remotes/origin/new-branch
  remotes/origin/push/need-p	# 注意这里

注意上面输出信息,虽然仓库已经删除了 push/need-p 分支,但是本地仓库现在还不知道,仍然有对该分支的远程引用

# 如果直接使用 git fetch
git fetch
git branch -a
# 输出
  dev
* master
  new-branch
  push/need-p
  remotes/origin/dev
  remotes/origin/master
  remotes/origin/new-branch
  remotes/origin/push/need-p

可以看到并没有删除对已经删除分支的远程引用,这时候我们就需要 git fetch -p

git fetch -p
# 输出
From github.com:MoeOffice/Git-Travel
 - [deleted]         (none)     -> origin/push/need-p

pull vs fetch

git pull 和 git push 似乎有点让人迷惑,他们有什么不同呢?我们可以理解为:git pull = git fetch + merge

git fetchgit pull 都是用于从远程 Git 仓库中获取更新并合并到本地代码库的命令。虽然它们都可以获取远程仓库中的最新代码,但它们的行为和用途有所不同。

具体来说,git fetch 命令会将远程 Git 仓库中的所有更新都下载到本地仓库中,但并不会自动合并这些更新到本地分支中。因此,如果你想查看远程仓库中的最新更新,或者想在本地工作的分支中手动合并远程分支,可以使用 git fetch 命令来获取更新。

另一方面,git pull 命令会自动将远程分支中的最新更新合并到当前本地分支中,相当于在 git fetch 命令之后自动执行了 git merge 命令。因此,如果你只是想快速地将最新更新合并到本地分支中,可以使用 git pull 命令。

总之,git fetchgit pull 的区别在于:

  • git fetch 只是将远程分支的最新更新下载到本地,不会自动合并到当前本地分支中,需要手动执行合并命令。
  • git pull 则会自动将远程分支中的最新更新合并到当前本地分支中,相当于在 git fetch 命令之后自动执行了 git merge 命令。

通常情况下,建议先使用 git fetch 命令查看远程仓库的最新更新,然后再根据需要手动执行合并命令或者使用 git pull 命令快速合并更新。这样可以更好地控制代码库的状态和变更历史。

git checkout 切换

git checkout 是 Git 命令中的一个非常常用的命令,主要用于在不同的分支、标签和提交之间进行切换。常见的用法:

  • git checkout <branch>:切换到名为 <branch> 的分支。例如 git checkout develop 切换到名为 develop 的分支
  • git checkout -b <new-branch>:创建一个新的名为 <new-branch> 的分支,并切换到该分支。例如 git checkout -b feature-branch 创建一个名为 feature-branch 的新分支,并切换到该分支
  • git checkout <commit>:切换到指定的提交,其中 <commit> 可以是提交哈希值或分支名称。例如 git checkout a1b2c3d4 将切换到哈希值为 a1b2c3d4 的提交
  • git checkout <tag>:切换到指定的标签。例如 git checkout v1.0.0 切换到 v1.0.0 标签
  • git checkout -- <file>:将指定的文件恢复到上一次提交的状态。例如 git checkout -- index.html 将 index.html 文件恢复到上一次提交的状态(放弃修改)
  • git checkout <branch> -- <file>:将指定分支中的文件复制到当前分支中。例如 git checkout feature-branch -- index.htmlfeature-branch 分支中的 index.html 文件复制到当前分支中
# 比如
git checkout -b new-branch
Switched to a new branch 'new-branch'

接下来就可以对新分支做一些提交了

git branch 分支管理

git branch 分支管理是 Git 工作流中很重要的功能,基本操作

  • git branch:列出本地所有分支,当前分支前面会有一个星号 (*)。
  • git branch -r:列出远程仓库的所有分支。
  • git branch -a:列出本地和远程仓库的所有分支。
  • git branch <branchname>:创建一个名为 branchname 的新分支。
  • git branch -d <branchname>:删除名为 branchname 的分支。分支必须先被合并到其他分支才能被删除。
  • git branch -D <branchname>:强制删除名为 branchname 的分支,即使该分支没有被合并。
  • git branch -m <newbranchname>:重命名当前所在的分支为 newbranchname
  • git branch -f <branchname> <commit>:将 branchname 分支指向指定的 commit
  • git branch --set-upstream-to=<remote>/<branchname>:设置本地分支跟踪远程分支。
  • git branch --merged:列出已经被合并到当前分支的分支。
  • git branch --no-merged:列出还没有被合并到当前分支的分支。

git tag 标签管理

git tag 命令用于给 Git 仓库中的某个提交打标签,可以理解为 Git 版本库的快照。通过给某个重要的提交打上一个有意义的标记,以便在后续查找和管理。

Git 中的标签分为两种:

  • 轻量标签(lightweight tag): 指向某个提交的引用,没有附加信息,它只是指向该提交的指针
  • 附注标签(annotated tag):一个独立的 Git 对象,它有自己的校验和,包含标签名称、标签创建者、标签日期、标签注释等附加信息
# 创建一个轻量标签
git tag v1.0.0

# 创建一个附注标签
git tag -a v1.0.0 -m "First version released" 123b45b1

在 GitHub 上,如果我们要发布一个 Releases,必须要指定一个 Tag,这个 Tag 一般是指向 GitHub Releases 的轻量标签。简单实践:

# 创建一个轻量标签
# 附加 -s 选项进行签名
git tag -s 0.1.1

# 查看这个标签的信息
git show 0.1.1
# 或者
git tag -v 0.1.1
# 输出
object f64b9334924167684e7a0689767249592771c59a
type commit
tag 0.1.1
tagger DejavuMoe <[email protected]> 1677308704 +0800

new tag 0.1.1
gpg: Signature made Sat Feb 25 15:05:20 2023 CST
gpg:                using EDDSA key D513573ED5AC8495FE0E47788422222222222222
gpg: Good signature from "Dejavu Moe <[email protected]>" [ultimate]

# 将标签推送到远程仓库
# 推送所有标签
git push origin --tags 
# 或者推送指定标签号
git push origin 0.1.1
# 输出
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 323 bytes | 323.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:MoeOffice/Git-Travel.git
 * [new tag]         0.1.1 -> 0.1.1

# 删除指定标签
git tag -d <tagname>
# 删除远程仓库指定标签
git push origin :refs/tags/<tagname>

仓库有其他协作者发布了新的标签,我们可以获取指定标签

git fetch origin <tagname>
// 比如
git fetch origin 0.1.2

git reset 回退

git reset 用于取消已经提交的变更、移动 HEAD 指针、重置暂存区和工作目录等操作,用法:

  • git reset --mixed <commit>:将 HEAD 指针和索引(暂存区)都移动到指定的提交,同时撤销当前提交之后的所有变更,但是保留工作目录中的修改,这是默认的操作模式。例如 git reset --mixed HEAD~2 可以撤销最近的两次提交并保留修改。
  • git reset --soft <commit>:将 HEAD 指针移动到指定的提交,但不会改变索引和工作目录,也不会撤销提交。这个模式常用于撤销一次提交,但是仍然希望保留提交所做的变更,以便在之后再次提交。例如 git reset --soft HEAD~1 可以将 HEAD 指向上一个提交,并将上一个提交的变更保留在暂存区中,以便在之后再次提交。
  • git reset --hard <commit>:将 HEAD 指针、索引和工作目录都移动到指定的提交,同时完全撤销当前提交之后的所有变更,这个模式 非常危险,因为它会丢失未提交的变更。只有在确定要放弃所有未提交的变更时才应该使用这个模式。例如 git reset --hard HEAD~3 可以将 HEAD 指向三次提交之前的状态,并完全撤销后续的所有变更。

git revert 撤销

git revert 命令可以用于撤销一个或多个提交,同时创建一个新的提交来保存撤销操作,这样可以 保留 原有的提交 历史记录,并在之后的开发中进行修改和调整。用法

git revert <commit>

# 同时撤销多个提交
git revert <commit1> <commit2> ...

# 撤销最近的提交
git revert HEAD

# 撤销某一段提交
git revert <start>..<end>

git merge 合并

将一个分支的更改合并到另一个分支,这是 Git 中最常用的操作之一。用法

  • git merge <branch>:将名为 <branch> 的分支合并到当前分支。例如 git merge feature-branch 将把 feature-branch 分支中的修改合并到当前分支中。
  • git merge --no-ff <branch>:执行不快进合并(non-fast-forward merge),将名为 <branch> 的分支合并到当前分支,同时创建一个新的合并提交。例如 git merge --no-ff feature-branch 将把 feature-branch 分支中的修改合并到当前分支中,并创建一个新的合并提交。
  • git merge <commit>:将指定的提交合并到当前分支。例如 git merge a1b2c3d4 将把提交哈希值为 a1b2c3d4 的提交合并到当前分支中。
  • git merge --abort:取消当前的合并操作,并返回到合并之前的状态。
# 比如
git checkout master
git merge new-branch
# 输出
Updating f6e02ff..0f2009a
Fast-forward
 new-branch.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 new-branch.txt

git base 重放

git rebase 是 Git 命令中的一个常用命令,用于将一个分支的修改合并到另一个分支中。与 git merge 命令不同,git rebase 命令会将本地未提交的修改「移动」到目标分支的最新提交之上。下面是一些常见的用法:

  • git rebase <branch>:将当前分支的修改“移动”到名为 <branch> 的分支的最新提交之上。例如 git rebase master 将当前分支的修改“移动”到 master 分支的最新提交之上。
  • git rebase -i <commit>:以交互模式(interactive mode)执行 rebase,可以让开发者自定义合并策略。例如 git rebase -i HEAD~3 将进入交互模式,让开发者自定义合并策略。
  • git rebase --continue:在解决完冲突后继续执行 rebase 操作。
  • git rebase --abort:取消当前的 rebase 操作,并回到 rebase 操作之前的状态

现在我创建了一个新的分支 dev,并在上面做了一些提交,然后将 dev 合并到 master 分支

git checkout master
git merge dev

# 输出
Updating 0f2009a..f64b933
Fast-forward
 dev1.txt | 0
 dev2.txt | 0
 dev3.txt | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dev1.txt
 create mode 100644 dev2.txt
 create mode 100644 dev3.txt

现在我想让 dev 分支的提交基于 master 分支进行重放(使用交互模式)

# 将最近三次的提交合并为一次
git rebase -i HEAD~3

在交互模式下,我们可以看到可以使用的操作

pick 56a630f Add dev1.txt
pick 306483f Add dev2.txt
pick f64b933 Add dev3.txt

# Rebase 0f2009a..f64b933 onto 0f2009a (3 commands)
#
# 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
#
# 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.

编辑完成后

Successfully rebased and updated refs/heads/master.

git stash 贮藏

假如现在我们在某个分支做了一些工作(但是还没完成,暂时不能 push),这时候这个分支急需进行操作(比如 rebase)。

git stash 命令用于将工作区中的修改暂时贮藏起来,以便稍后恢复。这在需要切换分支或者打补丁时非常有用,用法:

  • git stash save "message":保存当前工作目录中的修改,并添加一条描述信息,以便在后续的工作中更好地区分每个 stash。例如 git stash save "Save unfinished work"
  • git stash list:列出所有已保存的贮藏操作
$ git stash list
stash@{0}: Save unfinished work
stash@{1}: WIP on feature-branch: 1c53f7f Add new feature
  • git stash show stash@{n}:查看指定 stash 的详细信息,例如 git stash show stash@{0}
  • git stash apply stash@{n}:将指定 stash 中的修改应用到当前分支上,这会将 stash 中的修改应用到当前分支上,并将这些修改从 stash 中删除。例如 git stash apply stash@{0}
  • git stash pop:将最新的 stash 中的修改应用到当前分支上,这会将最新的 stash 中的修改应用到当前分支上,并将这些修改从 stash 中删除。例如 git stash pop
  • git stash drop stash@{n}:放弃(删除)指定 stash 中的修改。例如 git stash drop stash@{1}
  • git stash clear:清空所有的 stash

注意 恢复 stash 贮藏操作,如果与当前工作目录暂存区的修改冲突,也要先修改冲突才能再进行 stash 应用的相关操作。

git cherry-pick 挑选提交

我们知道,Git 的每次提交(commit)都会生成一个唯一的哈希值。git cherry-pick 命令可以将某个提交的更改应用到当前分支中(而无需将整个分支合并过来),并自动生成一个新的提交,这个新的提交包含了指定提交的更改,用法:

注意 git cherry-pick 会自动解决冲突。

git reflog 回溯

我感觉将 git reflog 称为「回溯」应该还是挺形象的,它用于查看本地仓库历史操作记录的命令。在平时的 Git 操作中,除了 git log 查看提交日志,用的比较多的就是 git reflog

f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{0}: checkout: moving from push/need-p to master
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{1}: checkout: moving from master to push/need-p
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{2}: checkout: moving from dev to master
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{3}: checkout: moving from new-branch to dev
0f2009a (origin/new-branch, new-branch) HEAD@{4}: checkout: moving from master to new-branch
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{5}: rebase (finish): returning to refs/heads/master
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{6}: rebase (start): checkout HEAD~3
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{7}: rebase (abort): updating HEAD
0f2009a (origin/new-branch, new-branch) HEAD@{8}: rebase (start): checkout HEAD~3
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{9}: merge dev: Fast-forward
0f2009a (origin/new-branch, new-branch) HEAD@{10}: checkout: moving from dev to master
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{11}: checkout: moving from master to dev
0f2009a (origin/new-branch, new-branch) HEAD@{12}: checkout: moving from dev to master
f64b933 (HEAD -> master, origin/master, origin/dev, dev) HEAD@{13}: commit: Add dev3.txt
306483f HEAD@{14}: commit: Add dev2.txt
56a630f HEAD@{15}: commit: Add dev1.txt
0f2009a (origin/new-branch, new-branch) HEAD@{16}: checkout: moving from master to dev
0f2009a (origin/new-branch, new-branch) HEAD@{17}: merge new-branch: Fast-forward
f6e02ff HEAD@{18}: checkout: moving from new-branch to master
0f2009a (origin/new-branch, new-branch) HEAD@{19}: commit: Create a new branch
f6e02ff HEAD@{20}: checkout: moving from master to new-branch
f6e02ff HEAD@{21}: commit: add push.txt
c8fa602 HEAD@{22}: initial pull