版本控制:Git 完全指南

328 阅读11分钟

 参考文献:

  1. git-scm.com/docs
  2. www.bootcss.com/p/git-guide…
  3. www.runoob.com/manual/gith…

Git 概述

Git

Git 是一款革命性的 分布式版本控制系统,它彻底改变了软件开发团队管理代码的方式。与传统的集中式版本控制系统不同,Git 赋予每个开发者完整的代码仓库副本,这意味着您可以在没有网络连接的情况下继续工作,随时随地提交更改、创建分支和查看历史记录。这种分布式架构不仅提高了工作效率,还大大增强了数据安全性 - 即使中央服务器出现故障,每个开发者的本地仓库都保存着完整的项目历史。

Git 的核心在于其独特的数据存储方式。它不像传统系统那样只记录文件差异,而是每次提交都会创建整个项目的快照,并使用加密哈希确保数据的完整性。这种设计让版本回退变得轻而易举,您可以精确回溯到项目历史的任何一个时间点。更令人惊叹的是,Git 的分支系统几乎没有任何开销 - 创建、切换和合并分支的操作瞬间完成,这使得功能开发、bug修复和实验性工作可以完美并行,而不会互相干扰。

在实际应用中,Git 展现出惊人的灵活性。无论是个人开发者管理小型项目,还是跨国团队协作开发复杂系统,Git 都能完美适应。它支持多种工作流程,可以与 GitHub、GitLab 等现代开发平台无缝集成,成为持续集成和持续交付流程的核心组件。正是这些卓越特性,使 Git 从众多版本控制系统中脱颖而出,成为当今软件开发领域不可或缺的标准工具,为数百万开发者提供了高效、可靠的代码管理解决方案。

Git 诞生

2005年,当Linux内核开发团队突然失去BitKeeper版本控制系统的使用权时,谁也没想到这会催生出一个改变软件开发历史的工具。Linus Torvalds——这位创造了Linux操作系统的天才程序员,面对这个危机展现出了惊人的创造力。

怀着对现有版本控制系统的不满,Linus开始着手设计一个全新的系统。他设想的Git必须满足几个关键要求:它必须是分布式的,让每个开发者都能独立工作;它必须足够高效,能处理像Linux内核这样庞大的项目;最重要的是,它必须完全开源,永远不再受制于商业公司的决策。

在短短几周内,Linus就完成了Git的初始版本。这个新系统采用了革命性的"快照"存储方式,而非传统的差异存储,使得版本控制更加可靠和高效。其轻量级分支设计让代码实验和功能开发变得前所未有的简单。

最初作为Linux内核开发专用工具的Git,很快展现出惊人的潜力。开源社区迅速接纳了这个新工具,GitHub等平台的兴起更使其成为全球开发者的标配。如今,Git已经远远超出了Linus最初的设想,成为软件开发领域最重要的基础设施之一,持续推动着全球协作编程的革新。

分布式 VS 集中式

分布式版本控制系统(DVCS)和集中式版本控制系统(CVCS)是两种不同的版本控制系统模型,它们在数据存储和工作流程管理上有所不同。

1️⃣ 数据存储方式

  • 集中式(CVCS):像图书馆借书
    • 所有代码都存放在中央服务器(类似图书馆总馆)
    • 开发者只能"借出"代码副本,修改后必须"归还"到中央服务器
  • 分布式(DVCS):人手一本的百科全书
    • 每个开发者电脑上都有完整的代码库和历史记录
    • 可以随时在本地修改和提交,不需要立即同步到中央服务器

2️⃣ 工作方式对比

  • 集中式:必须联网办公
    • 所有操作(提交、查看历史等)都需要连接服务器
    • 服务器宕机=全组停工
    • 适合办公室固定工位的团队
  • 分布式:随时随地工作
    • 本地就能完成大部分操作
    • 没网络也能继续写代码、提交记录
    • 适合远程办公或经常出差的开发者

3️⃣ 团队协作差异

  • 集中式:单一信息中心
    • 所有变更必须经过中央服务器中转
    • 合并代码要排队等待
    • 类似传统的纸质文件审批流程
  • 分布式:点对点协作
    • 开发者之间可以直接交换修改
    • 可以灵活选择何时同步到主仓库
    • 类似现代的云端协作文档

Git 安装

  1. 下载安装包

    • 官方下载地址:git-scm.com/download
    • 支持 Windows、macOS 和 Linux 全平台,具体下载方式请参考官方下载指南。
  2. 验证安装

    # 查看安装路径
    $ which git        # macOS/Linux
    $ where git        # Windows
    
    # 查看版本号
    $ git --version
    
  3. 基础配置(首次使用必做)

    # 设置全局用户信息(提交时显示)
    $ git config --global user.name "您的姓名"
    $ git config --global user.email "您的邮箱"
    
    # 启用彩色终端输出
    $ git config --global color.ui auto
    
    # 优化日志显示格式
    $ git config --global format.pretty "%h - %an, %ar : %s"
    

    查看当前配置:

    $ git config --list
    
  4. 高级配置建议

    # 设置默认编辑器为VSCode
    $ git config --global core.editor "code --wait"
    
    # 启用自动换行转换(跨平台协作时很重要)
    $ git config --global core.autocrlf input  # macOS/Linux
    $ git config --global core.autocrlf true   # Windows
    

提示:所有配置保存在 ~/.gitconfig 文件,可直接编辑

Git 工作流

git-trees.png

Git的工作流程包括以下几个主要步骤:

  1. 初始化仓库:使用 git init 命令在项目目录中初始化一个新的Git仓库,或者使用 git clone 命令克隆一个已有的仓库到本地。
  2. 添加和提交文件:使用 git add 命令将文件添加到暂存区,然后使用 git commit 命令将暂存区的文件提交到本地仓库。
  3. 分支管理:使用 git branch 命令创建、切换和删除分支。分支可以用来同时进行多个任务、实验新功能或独立开发不同的功能。
  4. 同步远程仓库:使用 git remote 命令添加远程仓库,并使用 git push 命令将本地仓库的提交推送到远程仓库。使用 git fetchgit pull 命令从远程仓库获取最新的更新。
  5. 解决冲突:当多个人同时修改同一文件并提交到远程仓库时,可能会出现冲突。使用 git diff 命令查看冲突,手动解决冲突后使用 git addgit commit 提交解决方案。
  6. 版本回退:使用 git log 命令查看提交历史,使用 git checkout 命令回退到特定的提交版本。
  7. 标签管理:使用 git tag 命令创建和管理标签,标签可以用来标记重要的版本或里程碑。

远程仓库

1. 注册账号

远程仓库可以是 Github,也可以是 码云 Gitee(推荐国内用户使用),这里以 Github 为例,首先你需要创建一个账号,点击前往 >>

2. 配置SSH Key

由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要设置:

第1步:创建SSH Key。在用户主目录下,看看有没有 .ssh 目录,如果有,再看看这个目录下有没有 id_rsaid_rsa.pub 这两个文件,如果已经有了,可直接跳到下一步。

提示:macOS 会隐藏 .ssh 目录,可以通过 cmd + shift + . 快捷键展示隐藏目录。

如果没有,打开 Shell(Windows下打开Git Bash),创建SSH Key:

$ ssh-keygen -t rsa -C "你的邮件地址"

然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。

如果一切顺利的话,可以在用户主目录里找到 .ssh 目录,里面有 id_rsaid_rsa.pub 两个文件,这两个就是SSH Key的秘钥对。

其中,id_rsa 是私钥,不能泄露出去, id_rsa.pub 是公钥,可以放心地告诉任何人。

提示:

在windows系统下,如果出现 “ssh-keygen” 不是内部或外部命令,解决的办法是:

  1. 首先找到 “ssh-keygen” 的安装目录,一般位于 “C:\Program Files\Git\usr\bin” 下。
  2. 将该路径添加环境变量的Path字段中。

第2步

登录Github → 点击右上角个人头像 → Settings → SSH and GPG keys → New SSH Key

在添加面板中,

  • Title:设置SSH key 标题,可任意填写

  • Key:将 id_rsa.pub 文件内容拷贝至此

然后点击 Add SSH Key 就可以看到你创建的SSH Key了,如下图所示:

git-sshkeys.png

为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。

当然,GitHub允许你添加多个Key。假设你有两台电脑,一台在公司,一台在家里,那你只需要把每台电脑的Key都添加到GitHub,就可以在家里或者在公司推送代码了。

确保你拥有一个GitHub账号后,我们就即将开始远程仓库的学习。

3. 创建远程库

1)登陆GitHub,然后,在右上角找到点击 + 按钮,再选择 New Repository 创建一个新的仓库:

git-create-repository.jpg

2)关联远程仓库:

git-remote.jpg

根据是否已有本地仓库来选择关联方式,这里以 已有本地仓库 为例:

# 将远程仓库地址添加到本地 Git 配置中,并命名为 origin
$ git remote add origin https://github.com/LiHongyao/Teaching.git
# 将当前分支重命名为 master(-M 表示强制重命名)
$ git branch -M master
# 将本地 master 分支推送到远程 origin 仓库,-u 参数设置上游跟踪,后续可直接使用 git push 简化操作
$ git push -u origin master

3)推送成功后,可以立刻在GitHub页面中看到远程库的内容。从现在起,只要本地作了提交,就可以通过如下命令更新远程仓库:

$ git push

SSH 警告

当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:

The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?

这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。

Git会输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了:

Warning: Permanently added 'github.com' (RSA) to the list of known hosts.

这个警告只会出现一次,后面的操作就不会有任何警告了。

如果你实在担心有人冒充GitHub服务器,输入yes前可以对照 GitHub的RSA Key的指纹信息 是否与SSH连接给出的一致。

4. 克隆远程库

在终端通过如下指令即可克隆远程仓库:

$ git clone <仓库地址>

Git仓库地址有以下几种形式:

  1. HTTP(S)协议:通过HTTP(S)协议访问远程Git仓库。需要具有读取权限。

    示例:https://github.com/<username>/<repository>.git

  2. SSH协议:通过SSH协议访问远程Git仓库。需要在远程服务器上设置SSH密钥,并具有对应的读取权限。

    示例:git@github.com:<username>/<repository>.git

  3. Git协议:使用Git协议访问远程Git仓库。通常使用默认的Git端口(9418)。

    示例:git://github.com/<username>/<repository>.git

当你从远程仓库克隆时,实际上Git自动把本地的 master 分支和远程的 master 分支对应起来了,并且,远程仓库的默认名称是 origin

要查看远程库的信息,用 git remote -v

git remote -v
origin	https://github.com/LiHongyao/Blogs.git (fetch)
origin	https://github.com/LiHongyao/Blogs.git (push)

上面显示了可以抓取和推送的 origin 的地址。如果没有推送权限,就看不到push的地址。

分支管理

git_branchs.png

Git分支是代码开发的独立时间线,本质是指向提交对象的轻量级指针,现代Git默认创建的主分支名为 main(之前是 master),作为代码的稳定基线,开发者可随时创建新分支(如feature/login)进行隔离开发,每个分支维护独立的提交历史。

核心优势:

  1. 并行开发:团队成员可同时在多个分支上工作,互不干扰
  2. 版本控制:通过release/v1.0等分支管理不同版本
  3. 安全实验:在分支尝试新功能,失败可随时丢弃

标准操作流程:

  1. 创建分支:git switch -c new-feature
  2. 开发提交:在分支内自由提交代码
  3. 合并回主支:通过git merge --no-ff保留合并记录
  4. 冲突处理:当多人修改相同代码时需手动解决

1. 分支分类

Git常用的分支分类包括以下几种:

  1. 主分支(Main/Master)

    存储生产环境稳定代码,所有发布版本均基于此分支。默认分支名已统一为main

  2. 开发分支(Develop)

    集成功能开发成果的基线分支,日常开发的核心分支。

  3. 功能分支(Feature)

    开发独立功能或需求,命名规范为feature/xxx。完成后合并回develop分支。

  4. 发布分支(Release)

    准备新版本发布,进行最终测试、版本号更新等。命名规范为release/vX.X.X

  5. 热修复分支(Hotfix)

    紧急修复生产环境Bug,从main分支创建,修复后合并回maindevelop

  6. 标签(Tag)

    标记特定版本(如v1.0.0),是不可变的版本快照

2. 分支管理策略

Git分支管理策略是指团队在协同开发过程中如何使用和管理Git分支的一套规则和约定。以下是几种常见的Git分支管理策略:

  1. 主分支管理策略(Master Branch Only):
    • 仅使用主分支(mainmaster)作为唯一开发线
    • 所有功能开发和Bug修复直接在主分支提交
    • 适用于个人项目或微型团队,强调简单性
  2. 功能分支管理策略(Feature Branch Workflow):
    • 为每个功能/任务创建独立分支(命名如feature/xxx
    • 功能分支基于主分支创建,开发完成后通过合并请求(MR/PR)回归主分支
    • 适用于中小型团队,实现功能隔离和并行开发
  3. Git Flow管理策略(Git Flow Workflow):
    • 标准化分支结构:主分支(main)、开发分支(develop)、功能分支(feature/*)、发布分支(release/*)、热修复分支(hotfix/*
    • 严格定义分支生命周期和合并规则
    • 适用于需要版本控制的中大型项目
  4. 委托合并管理策略(Pull Request Workflow):
    • 开发者通过个人分支提交代码,经Pull Request流程审查后合并
    • 强制代码评审和自动化测试验证
    • 适用于开源项目或强调代码质量的团队

以上仅是几种常见的Git分支管理策略,实际上,团队可以根据自身需求和开发流程制定适合自己的分支管理策略。关键是确保分支的清晰划分、合理的合并流程以及良好的协作沟通,以确保团队的代码管理和版本控制的高效性和可靠性。

3. 分支图解

Git 将每次提交按时间顺序串联成一条开发线,这条线就是一个分支。初始状态下,系统会自动创建名为master的主分支,它始终指向最新的提交节点,而HEAD指针则指向当前活跃的master分支,共同标记着代码库的当前状态:

git_branch_1.png

每次提交,master 分支都会向前移动一步,这样,随着你不断提交,master 分支的线也越来越长。

当我们创建新的分支,例如 dev 时,Git 新建了一个指针叫 dev,指向 master 相同的提交,再把 HEAD 指向 dev,就表示当前分支在 dev 上:

git_branch_2.png

从现在开始,对工作区的修改和提交就是针对 dev 分支了,比如新提交一次后,dev 指针往前移动一步,而 master 指针不变:

git_branch_3.png

假如我们在 dev 上的工作完成了,就可以把 dev 合并到 master 上。Git怎么合并呢?最简单的方法,就是直接把 master 指向 dev 的当前提交,就完成了合并.

git_branch_4.png

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

git_branch_5.png

4. 解决冲突

比如在 master 分支和 feature 分支上同时对某个文件进行了修改并且提交,如下所示:

git_branch_6.png

那我们在合并分支的时候就会遇到冲突的情况,遇到冲突之后,直接到冲突的文件中解决冲突,然后再次 add + commit即可,此时,合并之后的结构如下:

git_branch_7.png

标签管理

Git 标签是用于给代码库中的特定提交打上有意义的标记,通常用于表示版本号、发布版本或重要的里程碑。

Git 标签管理的主要策略包括:

  1. 版本标签:使用标签来表示软件的版本号。一般情况下,版本标签会和发布分支相关联,例如将一个稳定的发布分支打上版本标签,以便跟踪和记录软件的版本历史。
  2. 里程碑标签:使用标签来标记项目中的重要里程碑。这些里程碑可以是关键功能的完成、重要的bug修复、重要事件的发生等。里程碑标签可以帮助团队成员追踪项目进展和重要事件的发生时间。
  3. 发布标签:使用标签来标记正式发布的版本。发布标签通常与特定的版本号或发布日期相关联,用于标识可供用户下载和使用的软件版本。

Git 标签管理的优势包括:

  • 标记重要版本和里程碑,方便跟踪和回溯软件的发展历程。
  • 提供可靠的版本控制,确保发布版本的一致性和稳定性。
  • 与分支管理结合使用,使版本控制更加灵活和可控。

在使用 Git 标签管理时,一些常用的指令包括:

  • 创建:git tag <tagname> / git tag -a <tagname> -m "<message>"
  • 查看:git tag / git show <tagname>
  • 推送:git push origin <tagname>
  • 删除(本地):git tag -d <tagname>
  • 删除(远程):git push origin --delete <tagname>

标签管理的策略可以根据团队的需求和项目的特点进行灵活调整,例如可以设定特定的命名规范、版本号规则、标签注释的格式等,以便更好地组织和管理标签信息。重要的是,团队成员应该遵循一致的标签管理策略,以确保标签的准确性和可维护性。

团队协作

1. Collaborators

项目负责人可通过仓库设置添加协作者:

  • 路径:Settings → Access - Collaborators → Add people
  • 流程:受邀者通过注册邮箱接收邀请 → 点击View Invitation确认加入

2. Fork & Pull request

开源协作流程一般都会使用 Fork & Pull request 的模式:

  1. 贡献者Fork原仓库到个人账号
  2. 在个人副本上独立开发
  3. 通过Pull Request向原仓库提交变更请求
  4. 原仓库维护者审核后决定是否合并

3. Organization & Team

我们可以通过创建组织的形式来实现团队协作,创建组织的流程如下:

  1. 用户菜单选择New organization
  2. 选择免费计划
  3. 填写组织基本信息
  4. 创建成功

创建组织之后,你可以:

  • 建立多仓库
  • 管理成员权限
  • 设置团队分组

提示:所有协作方式均保持原仓库独立性,通过权限控制确保代码安全。

Git 指令大全

1. 基础操作

指令描述
git init创建本地仓库
git clone <url>克隆远程仓库
git status查看工作区状态
git add [.][*][<filename>]提交修改至缓存区
git commit -m "commit message"提交至版本库
git rm --cached <file>移除文件(暂存区)
git restore <file>撤销工作区修改
git restore --staged <file>撤销暂存区修改
git diff查看未暂存的修改
git diff --cached查看已暂存的修改
git log [--graph]查看提交历史
git reflog查看所有操作历史
git reset --hard <commit-id>版本回退(会丢失工作区修改)
git reset --soft <commit-id>版本回退(保留修改到暂存区)

2. 标签管理

指令描述
git tag <tag_name>创建轻量标签
git tag -a <tag_name> -m "message"创建带注释标签
git tag查看所有标签
git show <tag_name>查看标签详细信息
git tag -d <tag_name>删除本地标签
git push origin :refs/tags/<tag_name>删除远程标签
git push origin <tag_name>推送单个标签
git push origin --tags推送所有本地标签
git checkout -b <branch> <tag>基于标签创建分支

3. 分支管理

指令描述
git branch查看本地分支
git branch -r查看远程分支
git branch -a查看所有分支
git branch <branch_name>创建分支
git checkout <branch_name>切换分支
git checkout -b <branch_name>创建并切换分支
git branch -d <branch_name>删除已合并分支
git branch -D <branch_name>强制删除未合并分支
git merge <branch_name>合并指定分支到当前分支
git merge --no-ff <branch>合并分支(保留合并历史)
git rebase <branch>变基操作
git stash暂存当前工作状态
git stash list查看暂存列表
git stash pop恢复并删除最新暂存
git stash apply恢复但不删除暂存
git stash drop删除指定暂存

4. 远程操作

指令描述
git remote -v查看远程仓库信息
git remote add <name> <url>添加远程仓库
git remote remove <name>删除远程仓库
git push origin <branch>推送分支到远程
git push origin --delete <branch>删除远程分支
git fetch origin获取远程更新
git pull origin <branch>拉取并合并远程分支
git push --tags推送所有标签

5. 高级操作

指令描述
git cherry-pick <commit>选择性合并提交
git bisect start二分查找问题提交
git submodule add <url>添加子模块
git worktree add <path> <branch>添加工作树
git blame <file>查看文件修改历史
git gc清理不必要的文件并优化仓库

6. 配置相关

指令描述
git config --list查看所有配置
git config --global user.name "name"设置全局用户名
git config --global user.email "email"设置全局邮箱
git config --global core.editor "vim"设置默认编辑器
git config --global alias.<alias> <cmd>设置命令别名

扩展

1. 可视化工具

  • GitHub Desktop官方下载
  • GitKraken:跨平台Git客户端
  • SourceTree:免费的Git GUI工具

2. GitHub Pages

Github page 是一个免费的静态网页托管服务,您可以使用 Gitee Pages 托管博客、项目官网等静态网页

具体操作如下:

第1步:创建一个仓库,命名为:<username>.github.io,比如:zhangsan.github.io

第2步:上传静态文件到仓库根目录或子目录,比如:zhangsan.github.io/www

第3步:浏览器输入地址:zhangsan.github.io/www/index.h…

3. 国内代码托管

平台网址特点
码云(Gitee)gitee.com国内访问快,企业级功能
Codingcoding.net腾讯云旗下,DevOps全流程

4. 取消跟踪

实际开发中,你可能不小心将 node_modules 或一些缓存文件提交至了远程仓库从而导致文件体积特别大,最终导致 push/pull 时特别慢。这个时候我们就需要取消Git对该文件的追踪啦。

  1. 查看当前指定分支下追踪的文件(非必须):

    $ git ls-tree -r master --name-only
    
  2. 停止追踪但不删除文件:

    $ git rm -r --cached <file_or_dir>
    
  3. 更新 .ignore

    $ echo "<file_or_dir>" >> .gitignore
    
  4. 提交变更

    $ git add .gitignore
    $ git commit -m "停止追踪文件"
    $ git push
    

5. 分支冲突解决流程

  1. 拉取最新代码:

    $ git fetch origin
    
  2. 设置上游分支(首次需要):

    $ git branch --set-upstream-to=origin/<branch> <branch>
    
  3. 合并代码:

    $ git merge origin/<branch>
    
  4. 解决冲突后提交:

    $ git add .
    $ git commit -m "解决合并冲突"
    $ git push
    

6. 同步Fork仓库

如果Fork源仓库更新了内容,要更新Fork之后的内容,操作如下:

# 1. 查看远程信息
$ git remote -v

# 2. 添加上游仓库(Fork 的仓库)
$ git remote add upstream <original_repo_url>(Fork 源仓库地址)

# 3. 获取更新
$ git fetch upstream

# 4. 合并到本地
$ git merge upstream/main

# 5. 推送到自己的仓库
$ git push origin main

7. git fetch vs. git pull

git_fetch_pull.png

git fetchgit pull 是 Git 中用于获取远程代码更新的两个命令,它们之间的区别如下:

  • git fetch:执行 git fetch 命令会从远程仓库下载最新的提交和分支信息,但不会自动合并或更新本地分支。它只是将远程仓库的内容下载到本地,并更新远程分支的引用。可以理解为将远程仓库的代码更新拉取到本地的一个暂存区域,但不会直接影响当前工作区的代码。可以通过 git fetch origin <branch> 指定特定的分支进行更新。
  • git pull:执行 git pull 命令会从远程仓库下载最新的提交和分支信息,并尝试自动合并或更新当前分支。它包含了 git fetchgit merge 两个步骤,先将远程仓库的代码更新拉取到本地,然后自动执行合并操作,将远程分支的更新应用到当前分支。如果当前分支有未提交的修改,可能会导致合并冲突。

综上所述,git fetch 主要用于获取远程仓库的最新代码,而不会自动合并或更新当前分支,适合在查看远程更新、比较分支差异等情况下使用。而 git pull 则会自动合并远程分支的更新到当前分支,适合在需要及时同步远程更新并自动合并的情况下使用。

需要注意的是,使用 git pull 命令时,如果当前分支有未提交的修改,可能会导致合并冲突。在执行 git pull 之前,建议先提交或保存当前分支上的修改,以避免可能的冲突。

8. git stash pop vs. git stash apply

git stash popgit stash apply 是 Git 中用于恢复暂存的工作区修改的两个命令,它们之间的区别如下:

  • git stash pop:执行 git stash pop 命令会从暂存堆栈中恢复最近一次的暂存,并将恢复的修改应用到当前工作区。同时,该恢复的暂存记录会从暂存堆栈中移除。如果有多个暂存记录,git stash pop 会自动恢复最新的记录。
  • git stash apply:执行 git stash apply 命令会从暂存堆栈中恢复最近一次的暂存,并将恢复的修改应用到当前工作区。与 git stash pop 不同的是,git stash apply 不会移除恢复的暂存记录,仍然保留在暂存堆栈中。如果有多个暂存记录,需要通过指定索引来选择恢复特定的记录。

总结来说,git stash popgit stash apply 的作用是相同的,都用于从暂存堆栈中恢复修改。不同之处在于 git stash pop 在恢复修改后会自动将该暂存记录从堆栈中移除,而 git stash apply 则保留该暂存记录。选择使用哪个命令取决于你的需求,如果你希望在恢复修改后将暂存记录从堆栈中删除,可以使用 git stash pop;如果希望保留暂存记录以备将来使用,可以使用 git stash apply

常见问题

  1. fatal: protocol error: bad pack header

    $ git config --global pack.windowMemory 256m
    
  2. error: RPC failed; curl 56 OpenSSL SSL_read: Connection was reset, errno 10054

    # 原因:被墙了
    # 解决:
    1. 获取ip
    访问
    https://fastly.net.ipaddress.com/github.global.ssl.fastly.net#ipinfo 
    获取cdn域名以及IP地址
    
    访问 
    https://github.com.ipaddress.com/#ipinfo
    获取cdn域名以及IP地址
    2. 将域名与获取的ip添加映射关系
    # fix git clone github project failed
    199.232.69.194 github.global.ssl.fastly.net
    140.82.114.4 github.com
    添加到 windows中的 C:\Windows\System32\drivers\etc\hosts 文件中;
    
    3. 然后cmd命令窗口中执行下列命令刷新dns
    ipconfig /flushdns
    
  3. unable to access..., errno [502,10053]

    fatal: unable to access '': OpenSSL SSL_read: Connection was aborted, errno 10053

    fatal: unable to access '': The requested URL returned error: 502

    git config --global --unset http.proxy 
    git config --global --unset https.proxy
    

    由于网络原因,可能需要多次重试:git push 指令

  4. fatal: unable to access: OpenSSL SSL_read: Connection was reset, errno 10054

    git config --global http.sslVerify "false"
    
  5. fatal: The remote end hung up unexpectedly error: failed to push some refs to

    git push origin master
    
  6. fatal: unable to access : LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443

    git config --global --unset http.proxy
    
  7. fatal: unable to access : Failed to connect to github.com port 443 after 2086 ms: Connection refused

    git config --global http.proxy http://127.0.0.1:1080
    git config --global https.proxy http://127.0.0.1:1080