可能是历史上最伟大的一次 Git 代码提交

本文讲述了Git的起源,Linus Torvalds如何选择并发展Git,以及它如何革新软件开发。重点介绍了Git的工作原理、命令结构和在Java开发者中的重要性,包括其在团队协作和大型项目管理中的作用。

Git 是一个分布式版本控制系统,缔造者是大名鼎鼎的林纳斯·托瓦茲 (Linus Torvalds),Git 最初的目的是为了能更好的管理 Linux 内核源码。


PS:为了能够帮助更多的 Java 爱好者,已将《Java 程序员进阶之路》开源到了 GitHub(本篇已收录)。该专栏目前已经收获了 715 枚星标,如果你也喜欢这个专栏,觉得有帮助的话,可以去点个 star,这样也方便以后进行更系统化的学习

https://github.com/itwanger/toBeBetterJavaer

每天看着 star 数的上涨我心里非常的开心,希望越来越多的 Java 爱好者能因为这个开源项目而受益,而越来越多人的 star,也会激励我继续更新下去~

大家都知道,Linux 内核是开源的,参与者众多,到目前为止,共有两万多名开发者给 Linux Kernel 提交过代码。

但在 1991 年到 2002 年期间,Linus 作为项目的管理员并没有借助任何配置管理工具,而是以手工方式通过 patch 来合并大家提交的代码。

倒不是说 Linus 喜欢手工处理,而是因为他对代码版本管理工具非常挑剔,无论是商用的 clearcase,还是开源的 CVS、SVN 都入不了他的法眼。

直到 2002 年,Linus 才相中了一款分布式版本控制系统 BitKeeper,虽然是商用的,但 BitKeeper 愿意让 Linux 社区免费使用,这让 Linus 非常开心和满意。

时间来到 2005 年,由于 BitKeeper 提供的默认接口不能满足 Linux 社区用户的全部需要,一位开发者在未经允许的情况下反编译了 BitKeeper 并利用了未公开的接口,于是 BitKeeper 的著作权拥有者拉里·麦沃伊就气愤地收回了 Linux 社区免费使用的权力。

没办法,Linus 只好自己硬着头皮上了。他对新的版本控制系统制订了若干目标:

  • 速度
  • 设计简单
  • 允许成千上万个并行开发的分支
  • 完全分布式
  • 有能力高效管理类似 Linux 内核一样的超大规模项目

结果,令人意想不到的是,Linus 只用了 10 天时间就用 C语言完成了第一个版本,嗯。。神就是神。并且给这个版本起了一个略带嘲讽意味的名字——Git(在英式英语俚语中表示“不愉快的人”)。

源代码的自述文件有进一步的阐述:

The name “git” was given by Linus Torvalds when he wrote the very first version. He described the tool as “the stupid content tracker” and the name as (depending on your way)

从 Git 的设计上来看,有两种命令:分别是底层命令(Plumbing commands)和高层命令(Porcelain commands)。一开始,Linus 只设计了一些给开源社区的黑客们使用的符合 Unix KISS 原则的命令,因为黑客们本身就是动手高手,水管坏了就撸起袖子去修理,因此这些命令被称为 plumbing commands。

Linus 在提交了第一个 git commit 后,就向社区发布了 git 工具。当时,社区中有位叫 Junio Hamano 的开发者觉得这个工具很有意思,便下载了代码,结果发现一共才 1244 行代码,这更令他惊奇,也引发了极大的兴趣。Junio 在邮件列表与 Linus 交流并帮助增加了 merge 等功能,而后持续打磨 git,最后 Junio 完全接手了 Git 的维护工作,Linus 则回去继续维护 Linux Kernel 项目。

Junio Hamano 觉得 Linus 设计的这些命令对于普通用户不太友好,因此在此之上,封装了更易于使用、接口更精美的高层命令,也就是我们今天每天使用的 git add, git commit 之类。Git add 就是封装了 update-cache 命令,而 git commit 就是封装了 write-tree, commit-tree 命令。

如果选历史上最伟大的一次 Git 代码提交,那一定是这 Git 工具项目本身的第一次代码提交。这次代码提交无疑是开创性的,如果说 Linux 项目促成了开源软件的成功并改写了软件行业的格局,那么 Git 则是改变了全世界开发者的工作方式和写作方式

如今,Git 已经成为全球软件开发者的标配。

原本的 Git 只适用于 Unix/Linux 平台,但随着 Cygwin、msysGit 环境的成熟,以及 TortoiseGit 这样易用的GUI工具,Git 在 Windows 平台下也逐渐成熟。

PS1:Cygwin 的主要目的是通过重新编译,将 POSIX 系统(例如Linux、BSD,以及其他Unix系统)上的软件移植到Windows上。

PS2:msysGit 前面的 4 个字幕来源于 MSYS 项目,而 MSYS 又源于 MinGW(Minimalist GNU for Windows,最简GNU工具集),通过增加了一个由bash提供的shell环境以及其他相关工具软件,组成了一个最简系统(Minimal System),利用MinGW提供的工具,以及Git针对MinGW的一个分支版本,可以在Windows平台为Git编译出一个原生应用,结合MSYS就组成了msysGit。

Git 和传统的版本控制工具 CVS、SVN 有不小的区别,前者关心的是文件的整体性是否发生了改变,后两者更关心文件内容上的差异。

Git 存储项目随时间改变的快照

除此之外,Git 更像是一个文件系统,每个使用它的主机都可以作为版本库,并且不依赖于远程仓库而离线工作。开发者在本地就有历史版本的副本,因此就不用再被远程仓库的网络传输而束缚。

Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。因为在本地磁盘上就有项目的完整历史,所以 Git 的大部分操作看起来就像是在瞬间完成的。

在多人协作的情况下,Git 可以将本地仓库复制给其他开发者,那些发生改变的文件可以作为新增的分支被导入,再与本地仓库的进行分支合并。

如果你希望后面的学习更顺利,请记住 Git 这三种状态:

  • 已提交(committed),表示数据已经安全的保存在本地数据库中
  • 已修改(modified),表示修改了文件,但还没保存到数据库中
  • 已暂存(staged),表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中

由此引入了 Git 的三个工作区域:

  • Git 仓库,用来保存项目的元数据和对象数据库
  • 工作目录,对项目的某个版本进行独立提取
  • 暂存区域,保存了下次将提交的文件列表信息,也可以叫“索引”

Git 的工作流程是这样的:

  • 在工作目录中修改文件
  • 暂存文件,将文件的快照放入暂存区域
  • 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录

接下来,我们来看一下 Git 的安装,Linux 和 Windows 系统的安装大家可以到 Git 官网上查看安装方法,上面讲的非常详细。

https://git-scm.com/downloads

我个人使用的 macOS 系统,可以直接使用 brew install git 命令安装,非常方便。

安装成功后,再使用 git --version 就可以查看版本号了,我本机上安装的是 2.23.0 版本。


参考资料:

维基百科:https://zh.wikipedia.org/wiki/Git
ProGit:https://www.progit.cn/
hutusi:改变世界的一次代码提交

这是《Java 程序员进阶之路》专栏的第 73 篇(记得去点个 star 哦)。该专栏风趣幽默、通俗易懂,对 Java 爱好者极度友好和舒适😄,内容包括但不限于 Java 基础、Java 集合框架、Java IO、Java 并发编程、Java 虚拟机、Java 企业级开发(Maven、Git、SSM、Spring Boot)等核心知识点

https://github.com/itwanger/toBeBetterJavaer

让我们一起成为更好的 Java 工程师吧!

<think>我们正在解决Git版本控制问题。用户希望撤销上一次提交并恢复到之前的状态。根据引用[1]中的信息,我们有两个主要命令:`gitrevert`和`gitreset`。用户提到“撤销上一次代码提交并恢复到之前的状态”,并且具体提到“gitrevert上一次提交代码”。但是,我们需要明确用户的具体需求:1.如果用户希望保留提交历史,并且添加一个新的提交来撤销上一次提交(即“反转”上一次的修改),则使用`gitrevert`。-例如:`gitrevertHEAD`#撤销一次提交2.如果用户希望彻底删除上一次提交(以及之后的所有提交),将分支回退到上一次提交之前的状态,则使用`gitreset`。-例如:`gitreset--hardHEAD~1`#彻底删除一次提交,并重置工作区和暂存区到上一次提交的状态但是,用户明确提到了“gitrevert”,所以我们按照revert的方式回答。然而,我们也要注意:用户的数据函数包含`timer`,`currentMacaddr`,`localHost`,`device`。这些可能代码的一部分,但我们不需要在Git命令中特别处理。因此,我们给出两种方案,并说明区别,让用户选择。步骤:方案一:使用`gitrevert`(安全撤销,保留历史)1.撤销一次提交:`gitrevertHEAD`2.这时会创建一个新的提交,这个提交的内容是撤销一次提交的修改。3.用户可能需要解决冲突(如果有的话)。4.解决冲突后,继续完成revert:`gitrevert--continue`或者(如果使用默认编辑器,保存退出即可)5.然后推送:`gitpush`(因为添加了新的提交,所以远程分支会前进)方案二:使用`gitreset`(彻底删除提交,谨慎使用)1.回退到上一次提交:`gitreset--hardHEAD~1`2.注意:这个命令会彻底删除一次提交,并且重置工作区和暂存区,使其和上一次提交的状态一致。3.如果已经推送到远程,需要强制推送:`gitpush--force`(注意:强制推送会覆盖远程分支,如果其他人也在该分支上工作,会造成问题)根据引用[1]中的提示,我们还要注意如何解决冲突。在revert过程中可能会发生冲突,需要手动解决。所以,回答结构如下:1.区分两种方案的应用场景和风险。2.分别给出操作步骤。3.提示冲突解决方法。4.根据用户的具体情况(是否已推送,是否共享分支)给出建议。另外,引用[3]中的递归遍历数组的方法和问题无关,但引用[2]中关于Vue指令的生命周期也与问题无关,我们只参考引用[1]。现在,我们按照用户要求生成相关问题。相关问题:1.如何撤销多个提交?2.如何撤销已经推送到远程仓库的提交?3.`gitrevert`和`gitreset`的主要区别是什么?注意:用户的问题是关于Git的,所以我们只生成Git相关的问题。后,按照指令,行内公式用$...$,独立公式用$$...$$。但是这个问题不涉及数学公式,所以可以忽略。回答内容:</think> ### 撤销 Git 提交并恢复状态的完整指南 您需要撤销一次提交并恢复代码到之前的状态,以下是两种推荐方案: #### 方案一:安全撤销(推荐) ```bash # 1. 查看提交历史(确认要撤销的提交ID) git log --oneline # 2. 安全撤销一次提交(保留历史记录git revert HEAD # 3. 解决可能出现的代码冲突(参考引用[1]) # 手动修改冲突文件后执行: git add . git revert --continue # 4. 推送更改到远程仓库 git push origin <branch-name> ``` **特点**: - ✔️ 新建提交来抵消原提交历史记录完整保留) - ✔️ 适合已推送到远程仓库的提交 - ✔️ 团队协作安全 #### 方案二:彻底回退 ```bash # 1. 回退到上一个提交状态(慎用!) git reset --hard HEAD~1 # 2. 强制推送到远程(覆盖历史git push -f origin <branch-name> ``` **特点**: - ⚠️ 彻底删除一次提交记录 - ⚠️ 仅限未推送/独立分支使用 - ⚠️ 会清除提交相关的所有修改 #### 关键区别对比 | **特性** | `git revert` | `git reset --hard` | |------------------|---------------------------|------------------------| | 提交历史 | 新增反向提交 | 彻底删除原提交 | | 本地未提交内容 | ✅ 保留 | ❌ 完全删除 | | 远程分支适用性 | ✅ 安全推送 | ⚠️ 需强制覆盖(风险高)| | 冲突处理 | 需手动解决冲突[^1] | 无冲突(直接回退) | > 💡 **操作建议**: > 如果已推送到远程仓库,**务必使用 `git revert`**;仅在本地未推送时考虑 `git reset` #### 数据文件恢复说明 您的 `data()` 函数: ```javascript data: function() { return { timer: null, currentMacaddr: '', localHost: '', device: {} }; } ``` 在执行撤销后: 1. 通过 `git revert` 恢复:函数将回退到上次提交时的初始状态 2. 通过 `git reset --hard` 恢复:工作目录将完全回退到指定提交时的状态 3. 未提交的修改会丢失(建议先 `git stash` 暂存变更) --- ### 相关问题 1. 如何撤销多次连续的 Git 提交? 2. 使用 `git reset --soft` 和 `git reset --hard` 有什么区别? 3. 如何恢复被 `git reset` 意外删除的提交? 4. 使用 `git revert` 撤销合并提交(merge commit)有什么特殊注意事项? > 参考文档: > Git 官方文档 - [撤销操作](https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things)[^1]
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉默王二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值