Git 命令速查表

前言
Git 是一个 分布式版本控制系统 ,主要用于跟踪溯源文件的版本。开发人员常常使用 Git 来做项目的源代码版本控制。Git 最初的设计目标包括快速、数据完整、分布式、非线性工作流(例如在不同计算机上运行数千个并行分支),它是一款免费的开源软件,可在 GPL-2.0 许可下共享。
与绝大多数的分布式版本控制系统一样,它与 客户端-服务器系统 不同。Git 可以维护整个 存储仓库(Repository, 也称为 repo)的本地副本,拥有历史记录和版本跟踪功能,同时可以脱机(无网络)或者脱离中央服务器。 存储仓库 会在每一台计算机的目录中,并带有额外的隐藏配置、记录文件来提供版本控制。Git 可以在两个共享历史记录的仓库之间同步更改、克隆。对于多人合作,Git 可以与远程计算机进行仓库同步等操作。虽然每台计算机的 存储仓库 (具有相同的历史记录)都是对等的,但开发人员通常使用一个中央服务器来作为远程仓库托管,来保存集成副本。

Git 最初是由 Linus Torvalds 创建的,刚开始仅仅是用于在 Linux 内核开发中进行版本控制。 Git 这个商标则是由软件自由保护协会注册,标志着 Git 在开源社区中得到官方的认可和持续的发展潜力。如今, Git 已然成为版本控制系统的事实标准。他是最受欢迎的分布式版本控制系统,截至 2022 年,几乎近 95% 的开发人员将其作为首要的版本控制系统。他是专业的开发人员中最广泛使用的源代码管理工具。
历史
2005 年 4 月份,在 Linux 的 BitKeeper (一款源代码管理工具,自 2002 年来用于 Linux 开发) 免费许可证被撤销后,Torvalds 开始开发 Git。 BitKeeper 的版权持有者 Larry McVoy 声称 Andrew Tridgell 通过对 BitKeeper 协议进行逆向开发,创建了 SourcePuller 。这一事件也促使了同期的另一个版本控制系统 Mercurial 的诞生。
此时的 Torvalds 想要一个与 BitKeeper 相似的分布式系统,但是那时的市面上并没有任何一个免费版的系统能符合他的需求。他举了一个例子,一个源代码管理系统需要 30s 才能打上补丁并更新所有相关的元数据,并且他指出这无法满足 Linux 内核开发的需求,因为与其他的维护人员同步可能需要同时执行 250 次这样的操作。而在他的设计标准里,他明确地指出修补时间应不超过 3s ,并且添加了一下三个目标:
- 以并发版本系统(CVS)为例,说明哪些操作不该做;如有疑问,请做出完全相反的决定。
- 支持类似 BitKeeper 这样的分布式工作流程。
- 包含强大的安全保护措施,以防止意外或恶意损坏。
意料之中的,这些标准淘汰了当时所有的版本控制系统,所以 Torvalds 在 Linux 内核 2.6.12-rc2 开发版本发布以后立刻着手开发了自己的版本控制系统。
Git 的开发正式启动于 2005 年 4 月 3 日。 Torvalds 于同年的 4 月 6 日宣布了该项目,并在次日实现了自托管。 4 月 18 日完成了多分支的首次合并。 Torvalds 实现了他的性能目标; 4 月 29 日,新型的 Git 进行了基准测试,以每秒 6.7 个补丁的速度向 Linux 内核树记录补丁。 6 月 16 日, Git 管理了内核 2.6.12 版本。
Torvalds 于 2005 年 7 月 26 日将维护工作移交给了该项目的主要贡献者 Junio Hamano 。 Hamano 负责了 2005 年 12 月 21 日的 1.0 版本发布。
关于命名
Torvalds 曾讽刺地调侃过 git 这个名字(在英式英语的俚语中意为“令人讨厌的人”):“我是个自负的混蛋,我所有的项目都是我自己命名。起初是 ‘Linux’ ,现在是 ‘git’ 。 Git 的帮助手册将其描述为“愚蠢的目录追踪器”。
源代码中的 ReadMe 文件对此有更进一步的阐述:
1 | - "git" can mean anything, depending on your mood. |
Git 的源代码将该程序称之为“来自地狱的信息管理器”。
了解 Git
我们从经典源代码存储库中的一个基本示例开始,如图 1 所示。在经典源代码存储库中,包含文件和子文件夹的文件夹将作为内容进行处理( CVS 和 Git 实际上不处理文件夹,仅处理路径位置)。存储库保存内容的所有版本,而工作目录是修改代码的位置。正常的操作是将代码从存储库检出到工作目录,并将在此工作目录中所作的更改提交会存储库中内容的新版本。

每次提交都会创建一个新的内容子版本,该内容派生自先前修改的父版本,如图 2 所示。内容存储为一系列版本(也成为快照),通过创建的父子关系链接提交操作。通过提交在父版本和子版本之间发生更改的信息称为更改集。这一系列的版本成为流或分支。在 SVN 中,主流称为 trunk ;在 CVS 中,它通常称为 HEAD ;在 Git 中,一般命名为 master 。分支在实施项目中用于分离特定功能的开发或用于旧版本的维护。

到目前为止, Git 真的与经典源代码存储库工具很相似,但相似之处也就到此为止了。 CVS 和 SVN 的一大特点是它们有一个中央存储库。 Git 是去中心化的,多个存储库可以在软件开发中协同工作,每个开发人员的工作和通信方式与任何基于服务器的 Git 存储库相同。
Git 的工作原理
一旦理解了 Git 的主要原理,就会发现它非常简单。
首先, Git 处理快照中的内容,每次提交一个快照,并且
工作流程
如下是基本的工作流程:

1. 克隆仓库
如果你要参与一个已有的项目,首先需要将远程仓库克隆到本地:
1 | git clone http://github.com/username/repo.git |
2. 创建新分支
为了避免直接在 main 或 master 分支上进行开发,通常会创建一个新的分支,用来在本地进行开发。
1 | git checkout -b new-feature |
3. 开发、增删改查
利用各种 IDE 进行代码开发、添加或删除不必要的文件。
4. 暂存文件
将修改过的文件添加到暂存区,以便进行下一步的操作:
1 | git add filename |
5. 提交更改
将暂存区的更改提交到本地的仓库,并添加提交信息:
1 | git commit -m "Add new feature" |
6. 拉取最新更改
在推送本地更改之前,最好先从远程仓库拉取最新的更改,以避免冲突:
1 | git pull origin main/master |
7. 推送更改
将本地的提交推送到远程仓库:
1 | git push origin new-feature |
8. 创建 Pull Request(PR)
在 Github 或其他托管平台上创建 Pull Request ,邀请团队成员进行代码审查。 PR 合并后,你的更改就会合并到主分支。
9. 合并更改
在 PR 审核通过合并后,可以将远程仓库的主分支合并到本地分支:
1 | git checkout main |
10. 删除分支
如果不再需要新功能分支,可以将其删除:
1 | git branch -d new-feature |
或者从远程仓库删除分支:
1 | git push origin --delete new-feature |
Git 工作区、暂存区和版本库
- 工作区: 即本地电脑能看到的目录。
- 暂存区: 英文叫 stage 或 index 。一般存放在 .git 目录下的 index 文件中,所以暂存区有时也叫做索引(Index)
- 版本库: 工作区有一个隐藏目录 .git ,这个不算工作区,而是 Git 的版本库。

1. 工作区
工作区是本地的项目目录,可以在目录中进行文件的创建、修改和删除操作。工作区包含了当前项目的所有文件和子目录。
特点:
- 显示项目的当前状态。
- 文件的修改在工作区中进行,但这些修改还没有被记录到版本控制中。
2. 暂存区
暂存区是一个临时存储区域,它包含了即将被提交到版本库中的文件快照,在提交之前,你可以选择性地将工作区中的修改添加到暂存区。
特点:
- 暂存区保存了将被包括在下一个提交中的更改。
- 你可以多次使用 git add 命令来将文件添加到暂存区,直到你准备好提交所有更改。
常用命令:
1 | git add filename # 将单个文件添加到暂存区 |
3. 版本库
版本库包含项目的所有历史版本记录。
每次提交都会在版本库中创建一个新的快照,这些快照是不可变的,确保了项目的完整历史记录。
特点:
- 版本库分为本地版本库和远程版本库。这里主要指本地版本库。
- 本地版本库存储在 .git 目录中,它包含了所有提交的对象和引用。
常用命令:
1 | - git commit -m "Commit message" # 将暂存区的更改提交到本地版本库 |
子仓库
- 创建:
当我们的项目伴随着时间的增长越来越大的时候,单一的仓库便不再方便管理,这时候就需要将部分功能提取出来单一作为一个仓库管理,这时候就会出现仓库里面包含仓库的情况。这时候就需要 git submodule
添加子仓库。
1 | git submodule add https://github.com/#yourname#/#repositoryname#.git path |
注意: 添加完子仓库后,一定记得先 commit
提交保存后,在进行其他操作,养成保存的良好习惯。
- 删除:
- 进入包含子模块的父仓库根目录。
- 使用命令
git submodule deinit 子仓库路径
,将子仓库从父仓库的配置中删除。 - 使用命令
git rm 子仓库路径
,删除子仓库所有文件。 - 进入 .git/module ,删除相关仓库文件夹。
- 提交修改,使用命令
git commit -m “备注"
。
多人协作
对于非仓库管理者而言,因为没有任何的权限,无法进行 push
操作,首先需要将项目克隆至本地,这样可以获取代码并在本地进行修改,修改完后需要进行 pull request
操作请求仓库管理者进行代码合并。
什么是 fork ?
fork
即在自己的 GitHub 账户中创建一个原始仓库的副本,该操作会使得副本仓库包含原始仓库的所有代码和历史记录,此时能够在副本中独立进行修改和开发,且不影响原始仓库。如果你想要将你的修改合并到原始仓库中,可以向原始仓库提交 “Pull Request(拉取请求)”,请求将你的修改该合并到原始仓库,待仓库管理员同意后即可合并。这是一种多人协作方式,常见于开源项目的贡献和团队合作。
什么是 Pull Request ?
Pull Request 是协作机制,常用于开源项目或团队协作中。此操作是将自己的修改提交到项目的管理者,请求将这些修改合并到原始仓库中。Pull Request 一般会伴随着 fork
同时使用。