涛声依旧在 发表于 2024-9-9 17:32:34

Git 新手快速入门教程

一、什么是 Git

1. 作甚版本控制

版本控制是一种记录文件变化的体系,可以跟踪文件的修改历史,并允许用户在差别版本之间举行比较、恢复或合并。它重要用于软件开发过程中管理代码的变更,但也可以应用于任何需要跟踪文件变更的场景。
版本控制体系(VCS)可以资助团队协作开发,并提供以下功能:

[*]历史记录管理:版本控制体系会记录每个文件的修改历史,包罗修改内容、时间和作者等信息。这使得用户可以检察文件的演变历程,相识每次修改的目的和影响。
[*]并行开发支持:多个开发者可以同时修改同一个项目的差别部分,版本控制体系可以或许合并这些修改,并办理可能出现的冲突。
[*]备份和恢复:通过版本控制体系,可以轻松地恢复到之前的恣意版本,纵然文件丢失或破坏也可以或许通过版本控制体系举行恢复。
[*]分支管理:版本控制体系允许创建分支(Branch),开发者可以在分支上举行实验性的修改,而不会影响到重要的代码库,这使得并行开发和功能开发更加机动。
[*]版本标志:可以对紧张的版本举行标志(Tag),例如发布版本或里程碑版本,方便日后查找和引用。
常见的版本控制体系包罗 Git、Subversion(SVN)、Mercurial 等,它们都提供了类似的功能,但在实现方式和使用上有所差别。其中,Git 是如今最盛行的版本控制体系之一,被广泛应用于软件开发范畴。
2. Git 的诞生

   Git 的开发由 Torvalds(林纳斯·托瓦兹,Linux 之父)于 2005 年 4 月启动,起因是 2002 年时,用于 Linux 内核开发的专有源代码控制管理(SCM)体系 BitKeeper 撤销了其 Linux 开发的免费许可证。BitKeeper 的版权所有者 Larry McVoy 声称,Andrew Tridgell(Linux 社区重要贡献者,Samba之父)通过逆向工程破解了 BitKeeper 的协议,并创建了SourcePuller。 同一事件还刺激了另一个版本控制体系 Mercurial 的创建。
引用:Git - Wikipedia
Git 的诞生是由于 Linux 内核社区与 BitKeeper 公司之间发生了一些纠纷,导致 Linux 内核社区无法继承免费使用 BitKeeper。
由于这个事件,Linus Torvalds 决定开始开发一个新的版本控制体系,这个体系要具有以下特点:

[*]分布式:与传统的会合式版本控制体系差别,分布式版本控制体系允许每个开发者在当地完整地拷贝整个代码库,如许可以在没有网络连接的情况下继承工作,并且更容易支持分支和合并操作。
[*]性能:由于 Linux 内核的规模巨大,以是版本控制体系必须具备高效的性能,可以或许快速处理大量的文件和提交。
[*]简朴易用:Git 设计的目的之一是让用户更容易明白和使用,尽管它提供了丰富的功能,但命令和概念相对简朴,学习曲线较为平缓。
基于这些需求,Linus Torvalds 开始了 Git 的开发,并于 2005 年 4 月 3 日发布了第一个版本。随着时间的推移,Git 在开源社区中得到了广泛的认可和应用,逐渐成为了最盛行和最常用的版本控制体系之一。
3. 会合式 VS 分布式

会合式版本控制体系(Centralized Version Control System,CVCS)和分布式版本控制体系(Distributed Version Control System,DVCS)是两种差别类型的版本控制体系,它们在数据存储、工作流程和协作模式等方面有所差别。
3-1. 会合式版本控制体系(CVCS)

CVCS 是一种传统的版本控制体系,所有的文件和版本历史都存储在中央服务器上。开发者需要通过从中央服务器检出代码(checkout)来获取项目的副本,在当地举行修改后再提交到中央服务器。典型的 CVCS 包罗 CVS(Concurrent Versions System)和 SVN(Subversion)等。
https://i-blog.csdnimg.cn/blog_migrate/168d5b390b0a3cda49e0f9e95b3272f9.png
重要特点包罗:


[*]协作依赖于中央服务器:开发者必须与中央服务器保持连接,才气举行代码的获取和提交。
[*]危险点:如果中央服务器发生故障或者网络不稳固,那么开发者将无法工作。
[*]分支和合并相对复杂:通常需要由中央服务器来执行分支和合并操作。
会合式版本控制体系最大的问题就是必须联网才气工作,遇到带宽不好的情况是,提交、更新较大文件可能会十分的缓慢。而且,会合式版本控制体系容灾性差,万一中央服务器硬盘出现的数据丢失,那后果是很严肃的。
3-2. 分布式版本控制体系(DVCS)

DVCS 是一种新型的版本控制体系,每个开发者都拥有完整的代码仓库(包罗完整的历史记录)的副本。开发者可以在当地举行大部分的操作,而不需要与中央服务器保持连接。典型的 DVCS 包罗 Git、Mercurial 等。
https://i-blog.csdnimg.cn/blog_migrate/cd007cef1332f722a8da0354f471e2fd.png
重要特点包罗:


[*]分布式架构:每个开发者都可以在当地举行工作,不受中央服务器的限制。
[*]离线工作:开发者可以在没有网络连接的情况下继承工作,而且操作效率更高。
[*]分支和合并更机动:由于每个开发者都拥有完整的历史记录,因此分支和合并操作更加轻松和快速。
分布式版本体系的优点显而易见,起首,它可以完全独立的工作,不需要服务器的参与;其次,它具有很高的安全性,某一台电脑的数据丢失后,可以通过其他电脑举行恢复。
现实情况下,分布式版本控制体系也需要一个“中央服务器”,但该服务器的作用仅限于为数据的交互提供便利性。
4. Git 的工作流程

Git 的命令大全和作用,可以从这个网站查阅:workspace :: Git Cheatsheet :: NDP Software
https://i-blog.csdnimg.cn/blog_migrate/764ff36ac2957c91020923bcf2fb376b.png

[*]克隆仓库:在开始工作之前,起首需要将远程仓库克隆到当地机器上。使用git clone命令可以将远程仓库完整地复制到当地。
[*]创建分支:为了并行开发和隔离差别的功能或修复,通常会创建新的分支。使用git branch命令可以创建一个新的分支,例如:git branch feature-branch。
[*]切换分支:使用git checkout命令可以切换到创建的分支,例如:git checkout feature-branch。
[*]添加和提交更改:在所选分支上举行工作后,可以使用git add命令将更改的文件添加到暂存区,然后使用git commit命令将暂存区的更改提交到当地仓库,
[*]推送更改:如果要将当地分支的更改推送到远程仓库,可以使用git push命令,例如:git push origin feature-branch。这将把当地分支的更改推送到远程仓库中对应的分支。
[*]合并分支:当分支的工作完成后,可以将其合并到主分支(通常是master分支)或其他目的分支中。使用git merge命令可以执行分支合并,
[*]办理冲突:如果在合并分支时发生冲突(即同一文件的差别部分具有差别的更改),需要手动办理冲突。在冲突办理后,再次执行git add和git commit命令以完成合并。
[*]拉取更新:在团队协作中,如果其他人推送了更改到远程仓库,可以使用git pull命令拉取更新到当地仓库,以确保与最新代码保持同步
二、Git 的下载与安装

1. Git 的下载

Git 的下载链接:Git - Downloads (git-scm.com)
https://i-blog.csdnimg.cn/blog_migrate/dee04a41a042954fdeca184c1a4a5ad8.png
点击进链接后,可以看到有四个版本,按操作体系位数可分为 32 位和 64 位,按使用版本可以分为 Standalone Installer(独立安装程序)和 Portable(便携式),可以简朴的明白为前者需要安装,后者不需要安装可以直接使用(国内对这类不需要安装的软件也称为绿色版)。
https://i-blog.csdnimg.cn/blog_migrate/68090baed7783bc852ba4e10aa4028d0.png
本文使用的是 64 位的独立安装版本。
2. Git 的安装

以管理员身份运行 Git 安装程序。
https://i-blog.csdnimg.cn/blog_migrate/73109979a6dcb60025ed228f33d0e1e8.png
直接点Next。
https://i-blog.csdnimg.cn/blog_migrate/df329f946e941e5d87e834521e22e3f3.png
我这里选择默认的安装路径,可以根据自己的喜好更改路径,然后点击Next。
https://i-blog.csdnimg.cn/blog_migrate/8186a1970318169646536753d03b3c3b.png
按默认的勾选安装即可。
https://i-blog.csdnimg.cn/blog_migrate/16918f94e623fad9a19ae4ae660732ae.png
直接点Next。
https://i-blog.csdnimg.cn/blog_migrate/d01eb6fd810481488bdaf13b171aa090.png
选择文件的编辑器,一般都是用 VIM 作为默认的编辑器,直接点Next。
https://i-blog.csdnimg.cn/blog_migrate/5fbe96a29630ba765c6051a29cb481ed.png
决定初始化新项目(仓库)的主干名字,第一种是让 Git 自己选择,即默认名字是 master ,但是未来也有可能会改为其他名字;第二种是用户自行决定,默认是 main,当然,你也可以改为其他的名字。一般默认第一种,点击Next。
https://i-blog.csdnimg.cn/blog_migrate/709be9a9078cd15a16b7483737910111.png
   [!NOTE]
这个安装流程在之前是没有的,第二个选项下面有个NEW!,说很多团队已经重命名他们的默认主干名为 main。起因是 2020 年非裔男子 George Floyd 因白人警察暴力执法惨死而掀起的 Black Lives Matter(黑人的命也是命)运动,很多人认为 master 不恭敬黑人,号令改为 main。
接着是调整 PATH 环境变量,默认使用第二个。第三个只适合懂的人折腾。
https://i-blog.csdnimg.cn/blog_migrate/872d1f7b2572b42666038fcc205be9f9.png
   [!NOTE]
翻译如下:

[*] 仅从 Git Bash 使用 Git
这是最谨慎的选择,因为您的 PATH 根本不会被修改。您将只能使用 Git Bash 中的 Git 命令行工具。
[*] 从命令行以及第三方软件举行 Git
(推荐)此选项仅将一些最小的 Git 包装器添加到PATH中,以避免使用可选的 Unix 工具使环境混乱。您将可以或许使用 Git Bash 中的 Git,命令提示符和 Windov PowerShell 以及在 PATH 中寻找 Git 的任何第三方软件。
[*] 使用命令提示符中的 Git 和可选的 Unix 工具
Git 和可选的 Unix 工具都将添加到您的 PATH 中。
警告:这将覆盖 Windows 工具,例如 “find” and “sort”. 仅在相识其寄义后使用此选项。
选择 SSH 执行文件,按默认的即可。
https://i-blog.csdnimg.cn/blog_migrate/f4ca7d34412359e32024990b553d9870.png
   [!NOTE]
从前的 Git 2.31 都没有这个界面,估计是 2.4 开始可以使用外部的 SSH 文件。
选择HTTPS后端传输,还是按默认的来,点击Next。
https://i-blog.csdnimg.cn/blog_migrate/2472fa3478c1f3f536f8506ad821ddc4.png
   [!NOTE]
作为普通用户,只是用 Git 来访问 Github、GitLab 等网站,选择前者就行了。如果在具有企业管理证书的组织中使用 Git,则将需要使用安全通道。如果你仅使用 Git 来访问公共存储库(例如 GitHub ),或者你的组织不管理自己的证书,那么使用 SSL 后端(它们只是同一协议的差别实现)就可以了。
两个选项的具体区别,感爱好的可以去程序员社区 stack overflow 检察,链接:git - What’s the difference between OpenSSL and the native windows Secure Channel library - Stack Overflow
设置行尾符号转换, 这三种选择分别是: ① 签出 Windows 样式,提交 Unix 样式的行末端;② 按原样签出,提交Unix样式的行末端;③ 按原样签出,按原样提交。
https://i-blog.csdnimg.cn/blog_migrate/533d5c35474ad618de45b959f75a0aaf.png
那 Windows 样式和 Unix 样式到底有什么区别呢?
   GitHub 中公开的代码大部分都是以 Mac 或 Linux 中的 LF(Line Feed)换行。然而,由于 Windows 中是以 CRLF(Carriage Return+ Line Feed)换行的,以是在非对应的编辑器中将不能正常表现。
Git 可以通过设置自动转换这些换行符。使用 Windows 环境的各位,请选择推荐的 “Checkout Windows-style,commit Unix-style line endings” 选项。换行符在签出时会自动转换为 CRLF,在提交时则会自动转换为 LF 。
引用:《GitHub 入门与实践》
上面说 Mac 、Linux、Unix 的 Line Feed ,翻译过来就是换行符,用 “\n” 表示,换行符 “\n” 的 ASCII 值为 0x0A。而 Windows 的是 Carriage Return + Line Feed(回车 + 换行),用 “\r\n” 表示,回车符 “\r” 的 ASCII 值为 0x0D。
我们如今的教程就是介绍怎么安装 Windows 版 Git,以是肯定选第一项啦。
至于 “回车”(carriage return)和 “换行”(line feed)这两个概念的来历和区别?
   在盘算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打 10 个字符。但是它有一个问题,就是打字机打完一行换行的时间,要用去 0.2 秒,正好可以打两个字符。要是在这 0.2 秒内里,又有新的字符传过来,那么这个字符将丢失。
于是,研制人员想了个办法办理这个问题,就是在每行后面加两个表示结束的字符。一个叫做"回车",告诉打字机把打印头定位在左界限;另一个叫做"换行",告诉打字机把纸向下移一行。
参考程序员社区 stack overflow,链接:newline - What are carriage return, linefeed, and form feed? - Stack Overflow
接着来到设置终端模拟器与 Git Bash 一起使用,建议选择第一个选项,因为 MinTTY 3功能比 cmd 多,cmd 只不外比 MinTTY 更适合处理 Windows 的一些接口问题,这个对 Git 用处不大,除此之外 Windows 的默认控制台窗口有很多劣势,比如 cmd 具有非常有限的默认历史记录回滚堆栈和糟糕的字体编码等等。
相比之下,MinTTY 具有可调整大小的窗口和其他有效的可设置选项,可以通过右键单击的工具栏来打开它们 git-bash 。
https://i-blog.csdnimg.cn/blog_migrate/b2220c5499d40ed9c9331111355e4e17.png
接着来到选择默认的 “git pull” 举动的界面,先解释一下 git pull 是什么意思,git pull 就是获取最新的远程仓库分支到当地,并与当地分支合并。这里给出三个 git pull 的举动分别是:merge、rebase 和直接获取。
https://i-blog.csdnimg.cn/blog_migrate/035bef15baab70dd8aeb16a42a614d1a.png
一般默认选择第一项,git rebase 绝大部分程序员都用不好或者不懂,而且风险很大,但是很多会用的人也很推崇,但是用不好就是灾难。git pull 只是拉取远程分支并与当地分支合并,而 git fetch 只是拉取远程分支,怎么合并,选择 merge 还是 rebase,可以再做选择。
更详细的解释,我给各位总结了几个比较好的说明,以下是链接:
   git branch - Why does git perform fast-forward merges by default? - Stack Overflow
In git how is fetch different than pull and how is merge different than rebase? - Stack Overflow
Difference between git pull and git pull --rebase - Stack Overflow
接着是选择一个凭证资助程序, 第一个选项是提供登录凭证资助的,Git 偶然需要用户的根据才气执行操作;例如,可能需要输入用户名和密码才气通过 HTTP 访问远程存储库(GitHub,GItLab 等等)。第二个则是不使用凭证助手。
建议默认,点击Next。
https://i-blog.csdnimg.cn/blog_migrate/3462d29a4a72f033aa842e6c67c2c080.png
然后是设置额外的选项,分别是启用文件体系缓存和启用符号链接。启用文件体系缓存就是将批量读取文件体系数据并将其缓存在内存中以举行某些操作,可以明显提升性能。这个选项默认开启。启用符号链接 ,符号链接是一类特殊的文件, 其包罗有一条以绝对路径或者相对路径的形式指向别的文件或者目次的引用,类似于 Windows 的快捷方式,不完全等同类 Unix(如 Linux) 下的符号链接。因为该功能的支持需要一些条件,以是默认不开启。
建议默认,点击Next。
https://i-blog.csdnimg.cn/blog_migrate/3eb96fd83b6d2f5eb79b7138e065dede.png
最后是设置实验性选项,这些还是实验性功能,可能会有一些小错误之类的,建议不消开启。
直接点Install安装。
https://i-blog.csdnimg.cn/blog_migrate/a022931d9b540121d43497f918f026cd.png
安装完成,默认勾选的选项都去掉,点击Finish完成安装。
https://i-blog.csdnimg.cn/blog_migrate/76b18d8b0eea1bd6755bdacb6e1f45ba.png
   [!NOTE]
关于 Git 工具的 OpenSSH 设置,请详见博客末端的附录 2。
3. Git 各个软件的简朴介绍

安装好后,可以在开始菜单中,找到 Git 的文件夹,内里包罗了 Git Bash、Git CMD、Git FAQs、Git GUI、Git Release Note,下面我们就分别介绍一下这几个软件。
https://i-blog.csdnimg.cn/blog_migrate/129081ba8afaee44d3c96786ab34556b.png
3-1. Git Bash

Git Bash 是基于CMD的,在CMD的根本上增加一些新的命令与功能,平常重要用这个,功能很丰富。
https://i-blog.csdnimg.cn/blog_migrate/067db957f23feea6f39607bb7ebdef4a.png
3-2. Git CMD

Git CMD 不能说和 cmd 完全一样,只能说一模一样,功能少得可怜。
https://i-blog.csdnimg.cn/blog_migrate/1135ded49c53b26ada9b44eb81c75831.png
3-3. Git FAQs

Git FAQs 就是 Git Frequently Asked Questions(常问问题),点击图标直接就可以访问地点:FAQ · git-for-windows/git Wiki (github.com)
3-4. Git GUI

Git GUI 就是 Git 的图形化界面,可以通过它快速创建新仓库(项目),克隆存在的仓库(项目),打开存在的仓库(仓库)。这个我基本没用过,建议还是用命令行学习Git。
https://i-blog.csdnimg.cn/blog_migrate/da17d5933317a3a1a4e033ae8c037b57.png
3-5. Git Release Note

Git Release Note 就是版本说明,增长了什么功能,修复了什么 bug 之类的。一般使用浏览器打开。
https://i-blog.csdnimg.cn/blog_migrate/1091c3f5f8526224d956cc42e0131a65.png
三、Git 当地管理

1. 创建版本库

版本库(repository)又名仓库,本质上就是一个目次(文件夹),把需要控制管理的代码、文档放入到该目次下。在该目次下的所有文件的操作(添加、删除、修改、回退、查询等)都可以被管理起来。
为方便演示,我新建了一个文件来举行操作,而这个新建的文件夹就可以被称为版本库,但是此时还不是真正意义上的版本库,它跟普通的文件夹没有区别。
https://i-blog.csdnimg.cn/blog_migrate/24a926cd10c05c72f8fa0510b5a8512b.png
   [!CAUTION]
为了避免遇到各种莫名其妙的问题,请确保目次名(包罗父目次)不包罗中文。
进入文件夹,右键弹出菜单,选择“Open Git Bash here”。
https://i-blog.csdnimg.cn/blog_migrate/6bf288049eb4498f79b61f69555667b3.png
输入git init并回车可初始化版本库,执行成功后,这个文件夹才是真正 Git 版本库。同时,在文件夹中会多出一个隐藏文件夹,名为“.git”。
https://i-blog.csdnimg.cn/blog_migrate/a7406fe3682febad2c737e4b3b787f78.png
当版本库创建好后,我们就可以用它来做项目的管理了。例如,在初始化版本库后,通常都会添加一个说明文件来描述这个版本库的作用,行业默认都是新建一个名为“README”的.txt文件(普通文本文件)或者.md文件(Markdown 文件)。
我这里直接就在 Git 的命令框中创建了,使用的是touch命令创建,再用vim命令进入编辑(如果你不会 VIM,可以用最简朴的右键新建文本文件的方法新建,不外我还是建议学习一下 VIM)。
https://i-blog.csdnimg.cn/blog_migrate/193e64472b2f13b697ee31747145bb57.png
在内里我输入了“This is a version library for learning Git.”,然后保存退出。
https://i-blog.csdnimg.cn/blog_migrate/3281c586e765d883151f5f60996cd7fe.png
可以使用cat命令检察“README.md”。
https://i-blog.csdnimg.cn/blog_migrate/3e9342951dbd1c70ab1924be9250e5a2.png
根据 Git 的工作流程,此时的 README.md 还在工作区,可以通过git status命令检察仓库的状态。下图中,红色字体的“README.md”就是新增或者被修改的文件,如今还在工作区,还未提交到暂存区,括号里也提示我们可以用git add来添加到暂存区。
https://i-blog.csdnimg.cn/blog_migrate/84bb0705ba971ee29244b83fd617190a.png
使用git add README.md把 README.md 添加到 Git 的暂存区。
https://i-blog.csdnimg.cn/blog_migrate/6d14a2120027732d72d7897ea052a521.png
再次用git status命令检察仓库的状态,就可以看到 README.md 变成了绿色,已经保存到暂存区了。
https://i-blog.csdnimg.cn/blog_migrate/53fb4164879ad5f12bbebed790e1c001.png
根据 Git 的工作流程,此时 README.md 也只是存在暂存区,还并没有提交到仓库,需要使用git commit命令将 README.md 提交到仓库。
我在使用git commit命令时,会加上参数-m,用于表示本次提交的说明信息,说明信息最好统一格式,如许对于后续的 Bug 管理、版本信息追踪都会大有好处。
不外我们第一次使用时,会发现无法提交(如下图)。
https://i-blog.csdnimg.cn/blog_migrate/351e486ec3bcf4bc26100778ddc60f23.png
这个问题是由于 Git 无法检测到用户身份信息而引起的,Git 在每次提交时都需要知道提交者的姓名和电子邮件地点。可以按照命令行中提供的提示来设置用户身份信息。如下:
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
把双引号内里内容更换掉,我这里更换成我的 QQ 邮箱和英文名,如下图所示:
https://i-blog.csdnimg.cn/blog_migrate/5456f21be04d791992a43b59eaa7ab3d.png
再次提交就可以了。
https://i-blog.csdnimg.cn/blog_migrate/0fb2981523b64816a4d5beda6eadb3ff.png
这时使用git status命令检察仓库的状态,已经没有修改或新增的文件在暂存区或者工作区了。
https://i-blog.csdnimg.cn/blog_migrate/4c760141f0f375f4d99eca5c565cfe2e.png
2. 提交修改

提交修改的步骤和前面提到的一样,例如,我们给现有的 README.md 文件修改一些内容,如下图:
https://i-blog.csdnimg.cn/blog_migrate/f795296dfc032ee24cba6f259e235908.png
这时使用git status命令检察仓库的状态:
https://i-blog.csdnimg.cn/blog_migrate/6b60139e606b56fbc25065feafe3493b.png
上面的输出表示 README.md 已经修改,但是还未添加到暂存区。我们可以通过git diff检察当前的修改内容,输出格式为 Linux 内核补丁所用的格式:
https://i-blog.csdnimg.cn/blog_migrate/0e286c718438b4d9c94bd97b0b9d6371.png
新增的内容会以绿色字体表现,并且在每行开头多一个+,表示新增内容(如果是-,则表示删除内容,且字体为红色)。
如今提交修改的内容,使用的命令还是git add和git commit。
https://i-blog.csdnimg.cn/blog_migrate/6c1530d23eba20a7e163c887f6bfcd5c.png
可以通过git log检察近期的提交记录,提交记录以时间倒叙输出。
https://i-blog.csdnimg.cn/blog_migrate/106ab8be98b7397b8e6e790bc57f4db7.png
如果执行git commit之后,发现提交说明写的有问题,可以通过git commit --amend命令,修改近来一次的提交说明。输入命令后,会用 VIM 编辑器打开提交信息(还是要会 VIM ,不会的先去查一下怎么用)。
https://i-blog.csdnimg.cn/blog_migrate/905a54aac22c6c04266f1e6f793a0d99.png
修改一下提交记录,如下图(修改的内容没什么特殊寄义,只是为了示范):
https://i-blog.csdnimg.cn/blog_migrate/13ce73a41ea304257548727d8bed700c.png
保存退出后,再次用git log检察提交记录,可以看到提交信息已经更新了。
https://i-blog.csdnimg.cn/blog_migrate/a4671e8a313fcfbeff9771207e5990ca.png
如果要添加代码文件,也是类似的操作,例如新增一个.c 文件。
https://i-blog.csdnimg.cn/blog_migrate/7c9467c8bac0f343e585473b304220de.png
恣意写一些内容。
https://i-blog.csdnimg.cn/blog_migrate/269af5652022811ecbaf9e731c72691f.png
只要有新文件加进来,都可以用git status命令看到。
https://i-blog.csdnimg.cn/blog_migrate/1bc80e471b202deaa11e89637f815dee.png
顺便编译一下程序,多一个可执行文件。
https://i-blog.csdnimg.cn/blog_migrate/9987058710971ffe36842ffbbfdec5e1.png
用git status命令检察仓库。
https://i-blog.csdnimg.cn/blog_migrate/2f44e9427496bcde35b78e9a411c430b.png
提交修改的内容,使用的命令还是git add和git commit,但是同时提交两个或两个以上的文件,有两种办法。


[*] 方法一:
git add命令后面把要添加的文件全部写上,差别文件用空格隔开。
https://i-blog.csdnimg.cn/blog_migrate/264a7409d1f419d1f29d9b38987fb9bc.png
[*] 方法二:
如果要添加的文件是git status能看到的全部红色字体的文件,直接用git add .,在原来的命令上加一个.即可。
https://i-blog.csdnimg.cn/blog_migrate/c61fe412c27b922b45c79d24d3ab5c89.png
然后用git commit提交到仓库即可。
https://i-blog.csdnimg.cn/blog_migrate/63fb9a6729d491af05e10ad51267fc98.png
这时用git log检察提交记录,就有三段记录了。
https://i-blog.csdnimg.cn/blog_migrate/de950d954b9e21d751db7d93601aa051.png
3. 版本回退

在实际产品开发过程中,我们需要养成一个风俗,那就是代码或文档修改到一定程度时,要将修改的内容提交到版本库。如许,一旦后续代码或文档修改出了问题,或者误删了某些文件,还可以通过近来的一次 commit 举行恢复,这个恢复的过程就是版本回退。
在原来的 README.md 中,我重新做了修改,如下图:
https://i-blog.csdnimg.cn/blog_migrate/361102154823a5f78053eca232a02a9b.png
并且做了提交,如下图:
https://i-blog.csdnimg.cn/blog_migrate/2d8c9c82e54df05935e3ff124b778883.png
可以通过git log加上--pretty=oneline参数,检察简化版的提交记录信息:
https://i-blog.csdnimg.cn/blog_migrate/5bb975ff2ced96bda248c76c0c1e451d.png
可以看到有四条提交记录,前面黄色的数字是 commit ID,是 Git 的提交的版本 ID(跟 SVN 递增的 ID 不一样),通常是 40 个字符的十六进制字符串,这是 SHA-1 哈希算法生成的。这个 ID 通常被称为"SHA-1 哈希"或"SHA-1"。SHA-1 是一种加密哈希函数,虽然在安全上已经存在一些漏洞,但在 Git 中仍然被广泛使用。
回到正题,由于某种缘故原由,需要将版本库回退到“Added code and executable files.”这次的提交版本,可以使用git reset --hard命令来回退。但是有个条件,就是要让 Git 知道当前是什么版本,而且还要知道回退到哪个版本。
在 Git 中,用 HEAD 来表示当前版本,HEAD^ 表示上一个,HEAD^^ 表示上上一个版本,HEAD~100 表示往上 100 个版本。由上图可知,当前的 HEAD 就指在最新提交的版本上,回退到“Added code and executable files.”这次的提交版本,就是当前版本的上一次,那么执行下面命令即可:
git reset --hard HEAD^
执行结果如下图:
https://i-blog.csdnimg.cn/blog_migrate/94b9f53071e53aa6f9312a649451fe70.png
打开 README.md 检察一下,果然回退了。
https://i-blog.csdnimg.cn/blog_migrate/2e0a13c1d4d4d2a14dd0fcdd7177d92d.png
那么假设过了一段时间,需要返回之前的版本,也非常简朴,只要能找到之前版本 commit ID,就可以通过git reset命令回退就行。Git 提供了git reflog命令用于记录每次的命令,那么就可以通过git reflog找到之前版本的 commit ID。
https://i-blog.csdnimg.cn/blog_migrate/d8ac83cb2c7b1f402656006293f99fa6.png
上图红框标志的就是最后一次的版本提交记录,最开始的那串数字就是 commit ID,执行下面的命令即可。
git reset --hard 6353f69
执行结束,用git log可以看到,版本已经复原了。
https://i-blog.csdnimg.cn/blog_migrate/a645f9dc771c2373cb23f6764d510fe8.png
检察一下文件内容也是复原状态。
https://i-blog.csdnimg.cn/blog_migrate/4e5cf052c8b7c9b365b3718fb8eecfbd.png
Git 的版本回退速率之以是非常快速,重要是 Git 在内部有个指向当前版本的 HEAD 指针,回退版本时,Git 仅仅只是把 HEAD 从指向需要回退的版本。
https://i-blog.csdnimg.cn/blog_migrate/f10346b797a29ed25a4da0d6b1d2a97d.png
4. 明白工作区和暂存区

在使用 Git 管理版本时,经常会听到工作区和暂存区这两个概念,明白工作区和暂存区对于明白 Git 的很多操作十分有资助。从前面提到的 Git 的工作流程,可以看出工作区和暂存区都包罗在当地仓库内里,下面分别介绍一下这两个概念。
4-1. 工作区

当前开发程序所在目次称为工作区,比如,我前面演示用的文件夹“git_test”就是一个工作区,可以在这里新增或删除文件,也可以修改文件内里的内容。
这里特别夸大一下,隐藏文件夹“.git”不属于工作区,因为内里的内容不可以被用户修改,用户也不能在这个文件夹里新增或删除。它跟接下来要讲的暂存区有很大的关系。
https://i-blog.csdnimg.cn/blog_migrate/7ac1b7aa681037e8ed96e34851b4a0fc.png
4-2. 暂存区

先偏重讲一下隐藏文件夹“.git”,它是 Git 版本控制体系的焦点所在,它包罗了项目的版本控制信息,包罗提交历史、分支、标签等。“.git”文件夹的作用如下:

[*]版本控制信息存储:“.git”文件夹保存了项目的整个版本控制历史,包罗每个提交的内容、作者、时间等信息。
[*]分支和标签管理:Git 使用“.git”文件夹来存储和管理分支和标签信息,以便于在差别的分支之间切换,或者检察特定标签的快照。
[*]设置信息:Git 的设置信息也存储在“.git”文件夹中,包罗用户信息、远程仓库地点等。
[*]暂存区:“.git”文件夹包罗一个暂存区(stage,也叫 index),用于暂存待提交的修改,以便在提交时将其纳入版本控制。
[*]工作树状态追踪:Git 通过“.git”文件夹来追踪工作树(working tree)中文件的状态,以便确定哪些文件已经修改、添加或删除。
综上所述,我们可以知道暂存区就在“.git”内里,还有 Git 为我们自动创建的第一个分支 master,以及指向 master 的一个指针 HEAD。
https://i-blog.csdnimg.cn/blog_migrate/25118daccf141f202e5098b0fe2eb266.png
分支和 HEAD 的概念我们以后再讲,前面讲了我们把文件往 Git 版本库里添加的时间,分别用git add和git commit两步执行。实在本质上就是用git add把文件修改添加到暂存区,然后用git commit提交更改,把暂存区的所有内容提交到当前分支。因为我们创建 Git 版本库时,Git 自动为我们创建了唯一的 master 分支,以是git commit就是往 master 分支上提交更改。
可以简朴明白为,需要提交的文件修改通通放到暂存区,然后一次性提交暂存区的所有修改。
4-3. git diff 比较域

git diff命令可以对比两个版本的差异,一般会结合一些常用的参数运行,如下图所示:
https://i-blog.csdnimg.cn/blog_migrate/3346611e0770e557dceb50c4bf86d637.png
由上图可知,git diff是只比较比较工作区和暂存区(最后一次 add)的区别;git diff --cached是只比较暂存区和版本库的区别;git diff HEAD 是只比较工作区和版本库(最后一次 commit)的区别。
5. 管理修改

Git 之以是比其他版本控制体系性能优秀,重要就是它跟踪并管理的是修改,即每次版本之间的差异,而不是简朴的文件。
例如,我如今重新修改一下 README.md 的内容,新增内容如下图:
https://i-blog.csdnimg.cn/blog_migrate/b13f1443005faca6fa12fcdcc741d2bc.png
通过git status命令可以检察被修改的文件,再通过git diff可以对比工作区和暂存区的差别。
https://i-blog.csdnimg.cn/blog_migrate/3ab4cc3e96b0fc8f7ad8d2fdbb2df4d3.png
然后git add之后,再次检察仓库状态。
https://i-blog.csdnimg.cn/blog_migrate/61a4e1fe8efe5e8b8192c44af5224f62.png
先暂时不提交到 master 分支,再次修改 README.md,修改如下图:
https://i-blog.csdnimg.cn/blog_migrate/2a7f4b48a012b9d70fb90a6877d6c6c1.png
然后不举行git add,直接用git commit提交,此时可以发现提交是成功的,但是用git status检察,还是存在工作区有被修改的文件。显然,第二次的修改并没有被提交。
https://i-blog.csdnimg.cn/blog_migrate/a147ac5c2fad263fabe208c7b3ec5450.png
那就证明白 Git 管理的是修改,当用git add命令后,在工作区的第一次修改被放入暂存区并做好了被提交的准备,但是在工作区的第二次修改并没有放入暂存区,以是git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
可以通过git diff HEAD和git diff --cached分别检察仓库的情况,可以看出工作区的文件和仓库的文件是有差别的,而暂存区和仓库的并没有区别。
https://i-blog.csdnimg.cn/blog_migrate/db718a7060766b6838b8844d7dcc2c6d.png
6. 撤销修改

实际的项目开发过程中难免会犯错,比如 Bug 改错了位置、代码解释写错了等等。出现了错误的修改之后,就要及时的撤销修改,下面分别介绍差别场景下的撤销操作。
6-1. 撤销工作区的修改

如果因为某些缘故原由,我们要放弃这一次工作区的修改,可以用git checkout命令撤销修改。先使用git status命令检察一下当前版本库的状态,当前有一个工作区的修改。
https://i-blog.csdnimg.cn/blog_migrate/fa75ab143a0398cdf1a9d85bf0dae1fe.png
从前版本的 Git,第二行的括号里提示的是git checkout,如今提示的是git restore。这两个都是 Git 中用于撤销更改或者切换版本的命令,但是它们的使用方式和作用略有差别。

[*]git checkout:

[*]用法:git checkout <branch> 切换分支;git checkout <commit> <file> 恢复单个文件到指定提交版本。
[*]重要功能:

[*]切换分支:将工作区的内容切换到指定分支的最新状态,包罗所有文件和文件夹。
[*]恢复文件:将单个文件的状态恢复到指定提交版本的状态。


[*]git restore:

[*]用法:git restore <file> 恢复工作区中的文件到暂存区的状态;git restore --source=<commit> <file> 恢复单个文件到指定提交版本;git restore --staged <file> 将暂存区的文件恢复到工作区。
[*]重要功能:

[*]恢复工作区:将工作区中的文件恢复到暂存区或指定提交版本的状态。
[*]将暂存区的文件恢复到工作区。


总的来说,git checkout 重要用于切换分支和恢复单个文件,而 git restore 则用于恢复工作区中的文件到指定状态,同时也可以用来操作暂存区的文件。两者的功能有交叉,但是在实际使用时需要根据具体的情况选择合适的命令。
这里我用git checkout -- README.md来撤销修改,再次用git status检察,工作区已经clean了,并且 README.md 已经恢复到了版本库的版本。
https://i-blog.csdnimg.cn/blog_migrate/e1e642cae52ec091733bd0ddf9c9d5dc.png
6-2. 撤销暂存区的提交

对 README.md 再修改一些内容,并用git add提交到暂存区。
https://i-blog.csdnimg.cn/blog_migrate/7cab8b374bc2c2d1bc10e11df50512c2.png
使用git status检察当前版本库的状态,可以看到修改已经提交到了暂存区。
https://i-blog.csdnimg.cn/blog_migrate/f626184c2ed6eebcd11a8f7aa51a8b0d.png
如果我们想撤销这次的提交,可以看到在上图中有个 git 命令已经给出了提示,可以用git restore来撤销,之前的 Git 的版本是提示使用git reset来撤销,我们还是用更广为人知的git reset来撤销。
输入git reset HEAD README.md,表示我们要从 HEAD 只向的分支恢复 README.md 文件。
https://i-blog.csdnimg.cn/blog_migrate/3a2d8a89391823ef358c03c4a7977970.png
6-3. 撤销当地版本库的提交

如果已经把修改后的文件提交到 master 分支上了,想要撤销是撤销不了的,只能通过回退版本(第 3 小节的内容)的方式来举行。如今还只是当地版本库,如果后续学到远程版本库,把修改提交到远程版本库,那可能就无力回天了,因为远程版本库不止一个人在用,可能会影响到其他人的工作。
因此,很多企业在合入远程仓库之前都会有一个环节叫代码检察(review),所谓的 review 就是指开发团队中的成员对其他成员编写的代码举行查抄和评审的过程。代码检察是一种质量包管机制,通过让其他团队成员查抄代码,可以发现潜在的问题、提供反馈和建议,以确保代码质量和项目整体的稳固性。
7. 删除文件

在实际工作中,删除文件也是常见的操作,在 Windows 体系常常使用手动删除,风俗使用命令行的同学会使用rm。例如,我们如今就把其中一个文件删除,并检察当前版本库的状态。
https://i-blog.csdnimg.cn/blog_migrate/3b0ded43b91900ee8a9ac57916ab8b4b.png
Git 已经感知到了工作区的 Hello.exe 被删除,但版本库中的文件还未删除,这时我们有两种选择:

[*] 使用git add/rm <file>命令更新修改到暂存区以备 commit。
https://i-blog.csdnimg.cn/blog_migrate/308d34cb539b27c1d3b77661c8aa8ac0.png
这个操作目的是为了删除文件做准备,如果在执行git rm之前,突然不想删除了,那就是第二种选择了。
[*] 使用git checkout -- <file>丢弃工作区的修改,即还原被删除的文件。
https://i-blog.csdnimg.cn/blog_migrate/ade4cf0dc52b20f1a271e70ae4f8a753.png
8. 检察提交历史

在提交了若干更新,又或是克隆了某个项目之后,通常都会回顾下提交历史,看看项目都做了哪些修改。而检察历史提交记录最简朴而又有效的工具是git log命令了。
我们去嵌入式大神稚晖君的 GitHub 上找一个项目并克隆下来,这是他的 Github 链接:peng-zhihui (稚晖) (github.com)。
https://i-blog.csdnimg.cn/blog_migrate/27f7f7460ae87294bc92e38cf41b7201.png
我这里克隆了他的 HelloWord-Keyboard 项目,使用了git clone命令。
https://i-blog.csdnimg.cn/blog_migrate/01d60494020c89215b9f2adeb356f569.png
我这里换了一个文件夹,并且在这个文件夹下重新打开了 Git 终端,克隆项目完成后,运行 Git 的目次下会多出一个项目为名的文件夹。
https://i-blog.csdnimg.cn/blog_migrate/02197ba0f5811baabc0161504ee87cef.png
用cd命令进入文件夹。
https://i-blog.csdnimg.cn/blog_migrate/649e146d7db188a0cc47543ec7c89a34.png
在此项目中运行git log命令时,可以看到很多历史记录。
https://i-blog.csdnimg.cn/blog_migrate/939eeaa54c49e29e3ad7a732b9a2f590.png
历史记录甚至多到滚动不完,可以按q键退出浏览历史记录。
不传入任何参数的默认情况下,git log会按时间先后次序列出所有的提交,近来的更新排在最上面。会包罗每个提交的 commit ID、作者的名字、电子邮箱、提交时间和提交说明。
https://i-blog.csdnimg.cn/blog_migrate/4fa959701568a3c8c793c94be3009c8e.png
git log有许多选项(或者叫参数)可以有效搜索信息,例如需要表现每次提交所引入的差异,就可以加入参数-p或--patch(patch 就是我们常说的补丁)。
https://i-blog.csdnimg.cn/blog_migrate/696d2896b7d134c9437bb97e3e263078.png
如果要限制表现的日志条目数目,可以输入短杆后加上数目,例如git log -3,就会表现近来三次的提交信息。
https://i-blog.csdnimg.cn/blog_migrate/10a3cb258fc8923c27ec191c6a10533c.png
如果想看到每次提交的大略统计信息,可以使用–stat选项。
https://i-blog.csdnimg.cn/blog_migrate/55d8a848708f4fa8e0fd7f40e87feb74.png
–stat选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。 在每次提交的最后还有一个总结。
关于git log还有很多选项,这里就不一一赘述了,感爱好的直接在这个链接学习:Git - git-log Documentation (git-scm.com)。
四、代码托管平台

1. 常见的代码托管平台


[*] GitHub: GitHub 是最大的开源代码托管平台之一,提供了强大的版本控制功能和协作工具,支持 Git。
https://i-blog.csdnimg.cn/blog_migrate/f8c6a329355251edc43b1aadf22e75c1.png
[*] GitLab: GitLab 是一个开源的代码托管平台,提供了类似于 GitHub 的功能,但还包罗了一些额外的功能,例如持续集成、CI/CD 等。
https://i-blog.csdnimg.cn/blog_migrate/a9e62e029920bbf5571111ab5fb63395.jpeg
[*] Gitee: Gitee(码云)是开源中国(OSCHINA)的一个类似于 GitHub 的代码托管平台,支持 Git 和 SVN,提供 Git 仓库托管、团队协作、代码检察、问题跟踪、持续集成等功能。它是由中国的一家公司开发和运营,旨在为国内开发者提供一个方便、高效的代码托管平台。
https://i-blog.csdnimg.cn/blog_migrate/d3df91f6fdd062112a05349a80b42057.png
[*] Bitbucket: Bitbucket 是由 Atlassian 公司提供的代码托管平台,支持 Git 和 Mercurial,提供了私有仓库、团队协作、持续集成等功能。
https://i-blog.csdnimg.cn/blog_migrate/b8d974d4e02c2007ef34bab6c99b6efe.jpeg
[*] SourceForge: SourceForge 是一个老牌的开源软件托管平台,提供了代码托管、下载、论坛等功能,支持 Git、SVN 和 Mercurial。
https://i-blog.csdnimg.cn/blog_migrate/9742bf16150aaeeb8afb2340b3fefb1d.png
[*] Microsoft Azure DevOps: Azure DevOps(之前称为 Visual Studio Team Services 或 VSTS)是微软提供的一套全面的软件开发工具,包罗代码托管、CI/CD、项目管理等功能。
https://i-blog.csdnimg.cn/blog_migrate/ec8e2de31c13cca80afa82acd7d4896a.png
[*] AWS CodeCommit: AWS CodeCommit 是亚马逊提供的托管 Git 存储库的服务,可以与其他 AWS 服务集成,例如 AWS CodePipeline 和 AWS CodeBuild。
https://i-blog.csdnimg.cn/blog_migrate/284c934ef5d4b46efaffd14c32e0771a.png
[*] Google Cloud Source Repositories: Google Cloud Source Repositories 是 Google Cloud Platform 提供的托管 Git 存储库的服务,可以与其他 Google Cloud 平台的服务集成。
https://i-blog.csdnimg.cn/blog_migrate/9a4f2e3bb4f14561e4f6fbccaa203aae.jpeg
2. 注册代码托管平台账号

代码托管平台较多,这里只介绍其中两个平台的账号申请,而且都是以官方的文档为重要参考教程,分别是 GitHub 和 Gitee。推荐 GitHub 的缘故原由是大部分开源项目都在 GitHub 上(包罗 Linux kernel)。但究竟 GitHub 的服务器在国外,国内访问很不方便(无法访问和超慢的响应时间是家常便饭),要正常访问,还需要翻墙(这事违法哈)。以是这里补充一个类型 GitHub 的国内平台,就是开源中国的 Gitee,同样可以有很多开源项目,也可以在 Git 上设置账号,与 GitHub 的体验差别不大,重要对英语不好同学很友好,基本都是中文的。
2-1. GitHub

注册 GitHub 账号建议先翻墙,然后看官方文档。
官方注册文档链接:《在 GitHub 上创建帐户》
2-2. Gitee

官方注册文档链接:《注册 Gitee 账号》
3. 为 GitHub / Gitee 设置公钥

3-1. GitHub 设置 SSH Key

在开始菜单中打开 Git Bash。
https://i-blog.csdnimg.cn/blog_migrate/cab9eb5b21f023746d164dba29418b5a.png

[*] 设置用户信息:
git config --global user.name "your name"
git config --global user.email "your e-mail"
把双引号内里的内容更换成自己的,如下图:
https://i-blog.csdnimg.cn/blog_migrate/8b70bb7ed390540bbc31d65c3c7661e0.png
[*] 创建SSH密钥:
ssh-keygen -t rsa -b 4096 -C "your e-mail"
同样把双引号的内容更换成自己的邮箱,不外创建密钥时会遇到一个界面静止不动,如下图:
https://i-blog.csdnimg.cn/blog_migrate/2748b5945606fbed3843fad9bc59cd68.png
这是要我们设置一下密码,这个 Key 我们只是个人使用,只要不设计军事项目,不需要密码,直接按三次回车跳过。
https://i-blog.csdnimg.cn/blog_migrate/02af49cfd0057822a4012630e348b18a.png
看到这个画面就是 Key 创建成功了。
[*] 复制公钥,在当前窗口输入命令cd .ssh回车,再输入ls可以看到“.ssh”文件夹下生成了 Key 的密钥对。
https://i-blog.csdnimg.cn/blog_migrate/57a576b6f67bdc701da58ed9f99882f1.png
其中,id_rsa 是私钥,不能泄袒露去, 是公钥,可以放心地告诉任何人。输入cat id_rsa.pub检察公钥,并复制。
https://i-blog.csdnimg.cn/blog_migrate/ba7500673e37fddd13c9d49b63ad6614.png
[*] 登录 GitHub 网站,点击网页右上角的头像,在弹出的菜单中选择Setting。
https://i-blog.csdnimg.cn/blog_migrate/1bb5c15a02caeffc3a760322d8b8e19e.png
在左边的选项卡中,选中SSH and GPG keys,然后点击右边绿色按钮的New SSH key。
https://i-blog.csdnimg.cn/blog_migrate/28b8dd008594e7bb1c7af7ac6d16cf02.png
然后输入 Title,再粘贴密钥,最后点击下面的按钮Add SSH key。
https://i-blog.csdnimg.cn/blog_migrate/08e3ea7274298e01bac04b6db08e7ffc.png
偶然间可能要验证一下是不是本人操作,输入 GitHub 的密码验证就好了。
https://i-blog.csdnimg.cn/blog_migrate/1735bdc683ec863c6127e5b911c27792.png
成功添加 Key 如下图:
https://i-blog.csdnimg.cn/blog_migrate/168b8398bd1147ef8c74c3d37ed6e053.png
[*] 测试连接,输入下面的命令行:
ssh -T git@github.com
如果看到类似于 “Hi username! You’ve successfully authenticated, but GitHub does not provide shell access.” 的消息,则说明 SSH 连接已成功设置。如下图:
https://i-blog.csdnimg.cn/blog_migrate/ed7afb4969dd5d5b6d2743dae8f4fc9f.png
   [!NOTE]
为什么 GitHub 需要 SSH Key 呢?
因为 GitHub 需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而 Git 支持 SSH 协议,以是 GitHub 只要知道了你的公钥,就可以确认只有你自己才气推送。
当然,GitHub 允许你添加多个 Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的 Key 都添加到 GitHub,就可以在每台电脑上往 GitHub 推送了。
3-2. Gitee 设置 SSH Key

Git 设置 Gitee 和设置 GitHub 过程一样,但是不能使用同一个公钥,以是这里需要生成新的 Key 的密钥对。
为了区分之前的 Key,我们用基于ed25519算法的 SSH 密钥。
ssh-keygen -t ed25519 -C "your e-mail"
生成的密钥对如下:
https://i-blog.csdnimg.cn/blog_migrate/890623a1a7c66e36736213d6f359d985.png
用同样的方法复制密钥,然后登录 Gitee 网站和账号,点击右上角头像,弹出菜单,选择“设置”。
https://i-blog.csdnimg.cn/blog_migrate/43b4e9b81f954eced1d05bb5b0d21eef.png
在左边的选项卡中选择 SSH 公钥的选项卡,输入标题和公钥,点击确定。
https://i-blog.csdnimg.cn/blog_migrate/1fe2180b33276e3e342352e657c47f19.png
然后输入密码验证一下。
https://i-blog.csdnimg.cn/blog_migrate/68dcdd66810cacc69135e0fc9fac80ae.png
公钥成功添加。
https://i-blog.csdnimg.cn/blog_migrate/b74c86143f4de8dbb04ca187483895de.png
测试方法和 GitHub 差不多,后面部分改成 gitee.com 就行。中间停顿的时间,输入yes回车即可,看到类似于 “Hi username! You’ve successfully authenticated, but GitHub does not provide shell access.” 的消息,则说明 SSH 连接已成功设置。
https://i-blog.csdnimg.cn/blog_migrate/1a9135945991cbb8894d80f651c8e7f1.png
4. 添加远程仓库

到如今为止,我们已经学会了很多的关于 Git 的基本操作。但是这些功能与之前的 SVN 之类的会合式版本控制体系相比也没有太大的差别,因为这些仅仅只是基本操作,而 Git 真正意义上的杀手锏是远程仓库。
Git 是分布式版本控制体系,同一个 Git 仓库,可以分布到差别的机器上。那么是怎么分布的呢?最早,只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库实在都是一样的,并没有所谓的主次之分。
在实际工作场景往往是如许的,找一台电脑作为“服务器”,其他人都从这个服务器仓库“克隆”一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。服务器在这个过程中充当数据转接的角色,仅仅作为数据共享的中介。
Git 服务器可以自己搭建,也可以使用代码托管平台,对于初学 Git 的小同伴来说,搭建自己的服务器不太现实,以是直接注册 GitHub 或者 Gitee 的账号,使用外部的服务器来托管代码是最实际最高效的选择。前面三小节已经把账号注册完毕,并通过 SSH Key 加密连接了,如今我们就可以直接构建自己的远程仓库。
4-1. 构建 GitHub 的远程仓库

登录 GitHub 账号,先点击右上角的小三角形,在下拉菜单中选择New repository,此时页面会革新,在Repository name下面的输入框中,输入仓库名,前面不停用git_test这个仓库名,这里要使用一样的。最后点击下面的绿色按钮Create repository创建仓库。要提示一点,就是仓库名不能重复,如果你输入了仓库名是自己帐号里已存在的仓库,是无法创建成功的。
https://i-blog.csdnimg.cn/blog_migrate/b7839bdb9624330cdf2e3f116ea16a87.png
创建成功会革新成如下图的界面。
https://i-blog.csdnimg.cn/blog_migrate/77199e0890b96bfaf1f08dcfcfc1463b.png
回到当地,打开当地仓库git_test的文件夹,在这个文件夹下打开 Git Bash,粘贴下面的命令(上图红框复制的)。
git remote add origin https://github.com/zhengxinyu13/git_test.git
远程库的名字就是origin,这是 Git 默认的叫法,也可以改成别的的,不外origin这个名字一看就知道是远程库,以是建议不改。
https://i-blog.csdnimg.cn/blog_migrate/fa537fccc9fe4f56775e75cb00b21243.png
然后执行下面的命令:
git branch -M main
简朴解释一下这个命令,这是用于将当前仓库的默认分支名称从旧名称(如master)更改为main。这在许多情况下是为了避免使用具有历史负担的术语,比如master/slave或master分支的历史寄义。
具体来说,git branch -M main
命令执行以下操作:


[*]-M 选项表示move或rename。它会重命名分支,如果分支已存在,则会强制覆盖。
[*]main 是新的分支名称。
这个命令将当前仓库的默认分支重命名为 main,如果之前存在名为 main 的分支,则会覆盖它。
https://i-blog.csdnimg.cn/blog_migrate/1066c9a63c9bb39915ed8ad7c26e5e7b.png
将当地库同步到远程库可以执行下面的命令:
git push -u origin main
由于远程仓库是空的,第一次推送main分支时,加上了-u参数,Git 不但会把当地的main分支内容推送的远程新的main分支,还会把当地的main分支和远程的main分支关联起来,在以后的推送或者拉取时就可以简化命令。执行命令后,会提示登录 GitHub 的账号,点击Sign in with your browser。
https://i-blog.csdnimg.cn/blog_migrate/4549508d37061f2c5a68ca90428aec05.png
然后会自动跳转到浏览器,点击Authorize git-ecosystem。
https://i-blog.csdnimg.cn/blog_migrate/ec9ebb4f6f2e08db9243202826035307.png
然后输入密码,点击Confirm。
https://i-blog.csdnimg.cn/blog_migrate/a998f05998cf749407ddf6d487956ac4.png
如果看到这个界面,就表示设置成功。
https://i-blog.csdnimg.cn/blog_migrate/40b3c50df43b466a075505831447bd94.png
Git 这边也会提示,表示已经成功把当地仓库推送到远程仓库了。
https://i-blog.csdnimg.cn/blog_migrate/27147ae103cf80805f85f2f1e7aa6af1.png
推送成功后,可以立刻在 GitHub 页面中看到远程库的内容已经和当地一模一样的文件了。
https://i-blog.csdnimg.cn/blog_migrate/81e75055f41f18e7dcae4b6c5067a439.png
一旦有了远程仓库,当地仓库做出修改,需要同步到远程仓库的话,就可以通过命令:
$ git push origin main
如许就可以把当地的main分支的最新修改推送到 GitHub 的远程仓库。
4-2. 构建 Gitee 的远程仓库

Gitee 创建远程仓库会 GitHub 基本上一模一样,而且界面是中文的,对英语不好的小同伴很友好,操作过程我就不赘述了,登录 Gitee 后看图操作。
https://i-blog.csdnimg.cn/blog_migrate/a4f2291578093dda137da2eb9f337a7e.png
创建好后,在当地仓库的 Git Bash 上执行下图红框的命令。
https://i-blog.csdnimg.cn/blog_migrate/0aaf44b161f9c2d016deb97f82f50982.png
如果前面已经把当地仓库和 GitHub 的远程仓库连接的话,再执行git remote add origin是会失败的,如下图:
https://i-blog.csdnimg.cn/blog_migrate/ddab67636e097194a13d42e37f56256a.png
通常情况下,Git 不允许你添加同名的远程仓库,因为每个远程仓库都应该有一个唯一的名称。
如果你确定要将远程仓库更改为新的地点,你可以使用以下命令:
git remote set-url origin https://gitee.com/Grayson_Zheng/git_test.git
这将更新现有远程仓库 origin 的 URL 为指定的新地点。
https://i-blog.csdnimg.cn/blog_migrate/812ad248b292bf97fbdb3d6949da6d56.png
不外这么做会使当地仓库与 GitHub 的远程仓库失去连接,后面推送只能推到 Gitee 上,这就需要后面的克隆仓库来办理了。
执行git push -u origin "master"时会出错,这是因为当地仓库如今的分支名为main,而不是master,以是改成main之后就可以了。
https://i-blog.csdnimg.cn/blog_migrate/55215af22515df8c4e3f7a5b10f346d4.png
同样需要登录 Gitee 的账号,这一步比 GitHub 简朴多了。
https://i-blog.csdnimg.cn/blog_migrate/8140edcaae422e79af65e829acea1911.png
执行成功可以看到下图红框的内容。
https://i-blog.csdnimg.cn/blog_migrate/5a018c5a90e9cb099ca2af39a2171151.png
Gitee 的远程仓库也同步完成。
https://i-blog.csdnimg.cn/blog_migrate/a39301ce48e51f93971d23174503f0b3.png
5. 克隆远程仓库

由于有远程仓库,当地仓库纵然不警惕删除了,也可以通过克隆仓库找回。
https://i-blog.csdnimg.cn/blog_migrate/1f61565f3cb2afa1f8ac999b1aa1f467.png
克隆仓库需要用之条件到的命令git clone,后面跟上远程仓库的地点就可以了。实在,不管是 GitHub 还是 Gitee ,它们给出的地点不止一个,实际上 Git 支持多种协议,比如 SSH、HTTPS 等。
以克隆git_test这个项目为例,GitHub 的操作是先点击绿色按钮Code,然后复制链接。
https://i-blog.csdnimg.cn/blog_migrate/c68e3a32e2ffe52042a14b21fe9f9c5b.png
再git clone后面粘贴链接就可以克隆了,如下所示:
git clone https://github.com/zhengxinyu13/git_test.git
而 Gitee 也是差不多的操作,在项目页面点击橘色按钮克隆/下载。
https://i-blog.csdnimg.cn/blog_migrate/d1e6a24c401950e3eb2d7089493da33c.png
弹窗中,可以直接复制链接,比 GitHub 跟人性化一些的是,git clone已经包罗在内里了,不需要额外再输入。
https://i-blog.csdnimg.cn/blog_migrate/c41dd311d4f4bff24fd73587f8e9b524.png
   [!CAUTION]
需要留意的是,由于这个仓库虽然分别存放在 GitHub 和 Gitee 上,但是仓库的名字是一样,如果两个一起克隆就要留意,不能放在同一个文件夹下面,要分开存放,究竟克隆下来就是一个当地仓库,当地仓库自己就是个文件夹,同一级目次下是不允许有两个同名文件或文件夹的。
五、分支管理

1. 为什么需要分支

分支是版本管理体系中的紧张概念,一个版本库中的差别分支互不干扰、完全独立,直到分支合并那一天。那么实际工作中,分支的作用到底是什么呢?
   [!NOTE]
假设你准备开发一个新功能,但是需要两周的时间才气完成,第一周你写了 50% 的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不醒目活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。但是有了分支,就不需要担心这种事情了。你可以创建一个属于你自己的分支,如许团队其他人是看不到的,而且还继承在原来的分支上正常工作。你在自己的分支上干活,想什么时间提交都可以,直到开发完毕后,再一次性合并到原来的分支上,如许即安全,又不影响别人工作。
Git 分支重要是为了实现并行开发和代码管理的机动性和效率。以下是一些使用分支的重要缘故原由:

[*] 并行开发: 分支允许团队成员在不影响主代码库的情况下独立地开发新功能或修复错误。每个分支都是代码库的一个拷贝,团队成员可以在自己的分支上举行修改,然后在开发完成后将其合并回主分支。
[*] 功能开发: 每个功能可以在自己的分支上举行开发,如许可以保持主分支的稳固性。一旦功能开发完成并通过测试,就可以将其合并到主分支中。
[*] 错误修复: 当发现主分支中的错误时,可以创建一个新分支来修复该错误,而不会停止其他正在举行的工作。修复后,可以将修复的代码合并回主分支中。
[*] 版本管理: 分支可以用来管理差别的版本。例如,可以创建一个用于发布的稳固分支,以及一个用于持续开发的开发分支。如许可以确保发布版本的稳固性,同时继承举行新功能的开发。
[*] 代码检察: 分支可以用于举行代码检察。开发人员可以在自己的分支上举行工作,并在完成后请求代码检察。如许可以确保代码的质量和一致性。
综上所述,分支是 Git 的紧张特性,可以进步团队协作的效率,同时保持代码库的整洁和稳固。但 Git 的分支是与众差别的,无论创建、切换还是删除,Git 都能快速完成,无论你的版本库是 1 个文件还是 1 万个文件。
关于怎么学会使用 Git 的分支,这里推荐一个很不错的学习网站:Learn Git Branching。
这个网站也是 GitHub 上的一个开源项目pcottle/learnGitBranching,有爱好的可以克隆下来看看。
2. 明白分支

在前面提到的回退版本中可以知道,每次提交到版本库, Git 都会把这些提交版本都串成一条时间线,这是比较抽象的概念,以是可以参考下图:
https://i-blog.csdnimg.cn/blog_migrate/def92805200dc4d4a4cf662a873a0d2f.png
在当地仓库中,每一次的修改都会被 Git 记录在这条时间线上,这条时间线也是一个分支,而且是主分支,从前版本的 Git 叫master分支,Gitee 仍然保持这个叫法,如今版本的 Git 已经开始改名叫main分支了,而且 GitHub 也同步了这个叫法。
前面我们还提到有个 HEAD 指针指向最后一个修改,实在这不是一个严谨的说法。严格来讲, HEAD 指向的是当前分支(更专业的说法是对当前所在分支的符号引用),而master(或main)才是指向提交的节点。一开始时,HEAD 只指向master(或main),而master(或main)指向一个初始节点,这个节点是在仓库初始化之后就有了。之后每一次修改提交都会新增一个节点,同时也会使master(或main)指向新的节点。因此,随着版本不停地迭代修改,master(或main)这条分支也会越来越长。
   [!NOTE]
从个人角度来讲,这块内容比较抽象,明白起来会比较困难,因为当时我学习 Git 的时间也是如许的状态。后面我把分支类比成数据布局里的链表,把分支类比成链表的头指针,把修改类比成链表的结点。每次有新的提交,就当作有新的结点插入了链表,并且让头指针(分支)指向新结点(最新的修改)。
3. 分支的创建与合并

前面我们提到了一个场景,就是新功能的开发可能需要很多时间,而在这段开发的时间里,如果功能还没做完就提交,可能会影响别人开发,如果等到功能开发好后在提交,那么中间要是出现电脑宕机等不可抗力的缘故原由导致代码丢失,那也得不偿失。那么,既不影响别人开发,也不影响自己进度的办法就是创建一个自己的分支。
通常我们都会用dev来命名这个分支,在 Git 中,dev指的是“development”(开发)的缩写,它是一个常见的命名约定,用于表示开发阶段的分支,用于举行新功能的开发。
假设如今有个如今新建了版本库,内里写了初始版本的代码,当下如果用 Git 举行版本管理的话,可以用下图表示如今情况。
https://i-blog.csdnimg.cn/blog_migrate/9c5c3b043faffe3c38747d1f223f8b06.png
然后,对初始版本举行修改后,得到了C1版本,提交后如下图:
https://i-blog.csdnimg.cn/blog_migrate/0bf22fe4eb2e7aab803e660444e4825c.png
这时,我需要添加一个新的功能到这个版本内里,但是又害怕破环了原来的代码,于是我就创建了一个新的分支举行开发。创建新分支并命名为dev的命令如下:
git branch dev
https://i-blog.csdnimg.cn/blog_migrate/d15b5c958545bad76414ecd96d79d504.png
此时有个需要留意地方,那就是 HEAD 指针。此时的 HEAD 还是指向主分支,如果我这时间修改代码并提交了,这个提交记录还是在主分支上,那我创建的新分支就没有任何意义了。因此,在创建新分支之后,要及时把 HEAD 指向新的分支,之后的提交记录才会记在新分支上。求换分支的命令如下:
git checkout dev
https://i-blog.csdnimg.cn/blog_migrate/ba7e7bf950f2f6a8a325a81114978822.png
当然如果想在创建新分支后自动切换到新分支,可以用下面这个命令:
git checkout -b dev
如许就不需要用到git branch命令了,可以省一条命令。
这时我写好了一部分的新功能,虽然没有完成全部功能,但是为了保险起见,我提交了这次的修改,于是有了C2版本的代码,并且提交在了dev分支上。
https://i-blog.csdnimg.cn/blog_migrate/4d3612a03f8fe356ccd4e12984907dbd.png
接着我有一连开发C3版本和C4版本,坏消息是,虽然我完成了新功能的开发,但是经过测试都没能达到预期,同时也影响到了原本好的功能。好消息是,主分支的代码还能正常运行。
https://i-blog.csdnimg.cn/blog_migrate/2e01f6fa443b856ef3c6831bc05fd0c6.png
终于,功夫不负有心人,当开发到C5版本时,终于实现了功能,测试也没有发现 Bug,于是我提交了C5版本。
https://i-blog.csdnimg.cn/blog_migrate/245fdfe4bcbd5b140884a0df082fbc56.png
然后再就把这次提交合入到主分支中去,这个过程需要将 HEAD 切回主分支,再举行合并。切换回主分支的命令是git checkout,后面接上主分支名,如下:
git checkout main
https://i-blog.csdnimg.cn/blog_migrate/34f1b202608a7227b7c19a86b3fed2e1.png
切换主分支后,再用git merge命令合并dev分支,具体如下:
git merge dev
https://i-blog.csdnimg.cn/blog_migrate/04d2b7a7fa076e7896a20dbd33b45aab.png
对于dev分支来说,它看到了几个版本的迭代,但是对于主分支来说,只是C1到C5的迭代。合并之后,就可以放心的将dev分支删除了。不外不需要担心曾经在dev分支提交的各种记录会被删除,纵然分支被删除,这个分支上的提交记录会被保留一段时间(直到 Git 触发了垃圾回收并删除了这些无用的提交)。删除分支的命令如下:
git branch -d dev
https://i-blog.csdnimg.cn/blog_migrate/43fca623350089d3b480413bac15696f.png
因为创建、合并和删除分支非常快,以是 Git 鼓励使用分支完成各种使命,合并后再删掉分支,这和直接在主分支上工作效果是一样的,但过程更安全。
4. 冲突办理

只要是团队开发项目,代码上的冲突是在所难免的,究竟团队成员基本都在各自的分支里开发,那么合并分支就不可能一帆风顺,这时就要办理各种冲突了。
在 Git 中,所谓的冲突指的是当合并操作(merge)或重置操作(reset)尝试合并两个差别的修改时发生的情况。这种情况会导致 Git 无法自动办理修改之间的矛盾,需要人工介入办理。
常见的情况是,当你试图合并两个差别的分支,但这两个分支上的相同文件被修改了,且这些修改彼此之间存在冲突。例如,如果两个分支都修改了同一个文件的同一行代码,Git 就无法自动确定应该保留哪个版本的修改,因此会产生冲突。
当Git发现冲突时,会在受影响的文件中插入特殊标志来标识冲突的部分,例如:
<<<<<<< HEAD
这是当前分支(HEAD)的修改
=======
这是另一个分支的修改
>>>>>>> other_branch
冲突标志之间的内容就是冲突的部分。在办理冲突时,你需要手动编辑这些文件,选择要保留哪些修改,然后将冲突标志删除,以及合并两边的修改。一旦办理了所有冲突,你就可以继承完成合并操作。
下面举一个简朴的例子,演示一下如何办理开发过程中遇到的版本库冲突的问题。
起首在现有的 Git 版本库创建一个新的分支feature。
https://i-blog.csdnimg.cn/blog_migrate/df8be30a54f809827bb0eb173835ee30.png
前面没有提到,这里补充一下,检察当地仓库有多少分支可以用git branch命令,Git 会列出所有的当地分支,其中字体为绿色且前面带有星号的分支,就是当前被 HEAD 指向的分支。
此时我修改了 README.md 文件,并保存提交。
https://i-blog.csdnimg.cn/blog_migrate/2b43cb7be6bafc2a010235a066418dc7.png
此时我切换回主分支,同样修改了 README.md 文件,并保存提交。修改的内容和上图一样,只是换了一个符号。
https://i-blog.csdnimg.cn/blog_migrate/7868bcb501daa72371613883d794eddc.png
好了,如今两个分支都有对同一个文件的提交,如果这时间合并分支就会有冲突,Git 也会有提示合并存在冲突,需要手动办理,然后重新提交。
https://i-blog.csdnimg.cn/blog_migrate/bfc9e372a6930c99bdf41488850ddae2.png
可以用git status命令来检察存在冲突的文件。
https://i-blog.csdnimg.cn/blog_migrate/ddd0e740214088557bc8fce9cb5c803c.png
这时我们再打开 README.md 文件,可以看到 Git 标志出差别分支的内容。
https://i-blog.csdnimg.cn/blog_migrate/7f185be7d93dfa55b54cf95fa0e41be7.png
修改成下图所示的内容后保存,这个要修改成哪个分支的内容,全看实际的情况,我这里是恣意选的。
https://i-blog.csdnimg.cn/blog_migrate/3cb81c5ccf09b1d46a58f7a7562c1f97.png
办理冲突后,使用 git add 命令将办理冲突的文件标志为已办理,再用 git merge --continue来继承合并进程。
https://i-blog.csdnimg.cn/blog_migrate/3d0431f49ca1a279d4dfb6cd42c9cf15.png
用带参数的git log也可以看到分支的合并情况(别慌,这些命令我也没记住,从前靠百度,如今靠 ChatGPT)。
git log --graph --pretty=oneline --abbrev-commit
https://i-blog.csdnimg.cn/blog_migrate/dcb80a047a92714ce6c1ed1345422b51.png
5. BUG 分支

软件开发中,bug 就像家常便饭一样。有了 bug 就需要修复,在 Git 中,每个bug都可以通过一个新的临时分支来修复,修复后合并分支,然后将临时分支删除。
假设我如今接到一个修复代号为 101 的 bug 的使命时,而且这个 bug 相对比较紧急,以是我需要放下当前的工作优先去处理这个 bug,那么我就会创建一个名为 issue-101 的分支来修复它。不外,正在dev分支上举行的工作还没有提交,只是添加到了暂存区而已。
https://i-blog.csdnimg.cn/blog_migrate/6ad1987207528979f9fa26a22c10f536.png
此时我还不能提交,究竟当前的进度还未完成,没办法提交。同期间号 101 的 bug 又需要在本日办理,那要怎么办呢?
在前面的 Git 工作流程中,有一个贮藏区(stash)不停没提到,如今就是它发挥作用的时间了。贮藏区可以把当前的工作现场“贮藏”起来,等以后需要恢复工作现场时,再把工作现场还原到“贮藏”前,进而可以继承举行未完成的工作。
如今用git status检察版本库的状态,还存在未提交的内容。
https://i-blog.csdnimg.cn/blog_migrate/13f73009ebd7389bd2e230ba0a3e74e5.png
用git stash命令贮藏当前的工作状态,用git status检察版本库的状态,可以看到工作区已经 clean 了,因此可以放心地创建分支来修复 bug 了。
https://i-blog.csdnimg.cn/blog_migrate/71114fcd1c6522144ccaaccb9aa03548.png
这时就要留意了,先要确定以哪个分支的版本修复 bug,究竟如今的 HEAD 指针还指向dev分支,而且dev分支上可能有很多提交是不完整的,这时就需要切换回主分支,以主分支的最后一个提交的版本为基准,去创建新的 bug 分支。
https://i-blog.csdnimg.cn/blog_migrate/17477cb26b321decd5ff10bb4f008c2d.png
分支创建好后,就可以开始修复 bug 了。修复好后,提交修改,切回主分支,合并 bug 分支,最后删除 bug 分支。
https://i-blog.csdnimg.cn/blog_migrate/5b178f159d60813b4d6b43a6d36be133.png
这时间再回到dev分支干活,但是工作区是干干净净的,需要去贮藏区恢复后才气继承。
https://i-blog.csdnimg.cn/blog_migrate/fa1723210d366318a0c4395ab0f6a9c4.png
用git stash list命令可以检察当前贮藏区的所有贮藏记录,如今看来只有一条记录。
https://i-blog.csdnimg.cn/blog_migrate/dcefde691d1c62e89c61006e52e59c2f.png
想要恢复成贮藏之前的状态,有两种情况:

[*] 恢复贮藏前的工作状态,不删除贮藏区的贮藏记录,命令如下:
git stash apply
后续想要删除要用git stash drop,而且还要指定删除哪条记录,不指定就是删除最新的,指定的话,命令如下,stash@{<index>}内里的<index>是记录编号,如上图的stash@{0}。
git stash drop stash@{<index>}

[*] 恢复贮藏前的工作状态,同时删除贮藏区的贮藏记录,命令如下:
git stash pop

我这里直接用git stash pop
,不需要用git status,恢复的时间会直接表现版本库的状态。
https://i-blog.csdnimg.cn/blog_migrate/74171f87fb495b6eded43d4172268e27.png
6. 分支管理策略

在合并分支时,可以留意到有个“Fast-forward”的字样,这是 Git 中的一种合并模式。在 Fast-forward 模式(快进合并)下,Git 可以通过简朴地将目的分支指向合并的分支的最新提交来完成合并,而无需创建新的合并提交。
https://i-blog.csdnimg.cn/blog_migrate/c11d7851138598ec59cecc0f5f35699c.png
在这种模式下,Git 只需将目的分支指向合并分支的最新提交,而不会创建新的提交来记录合并的过程。快进合并的好处是可以保持提交历史的线性和简便,因为不会创建额外的合并提交。这在处理简朴的合并情况时非常方便和高效。但这种模式有个缺点,那就是删除分支后,会丢掉分支信息。
以是偶然间快进合并可能不太适用,比如当我想要保留合并操作的记录或者在合并过程中需要办理冲突时。在这种情况下,可以使用--no-ff选项来禁用快进合并,强制 Git 创建一个新的合并提交。如许可以更清晰地记录分支的合并历史以及办理合并冲突所做的修改。
例如,我如今在dev分支提交了一笔代码,准备合并dev分支。如果想要保留提交信息,就要强制禁用 Fast forward 模式,Git 就会在 merge 时生成一个新的 commit,那么从分支历史上就可以看出分支信息了。
https://i-blog.csdnimg.cn/blog_migrate/2f1d333859df29d594d58eca5e47c38a.png
在dev分支提交后,切回主分支,然后合并dev分支时,带上--no-ff和合并信息,命令如下(双引号是合并信息):
git merge --no-ff -m "merge with no-ff" dev
https://img-blog.csdnimg.cn/direct/890865e53f914f4ca79e8e93dd065a9d.png#pic_center
合并后看看分支历史,可以显着看到,前面演示的分支合并,和这次的禁用快进合并的分支合并有着显着的信息差别,禁用快进合并的分支合并操作,会记录下这次的提交是从dev分支合并过来的。
https://img-blog.csdnimg.cn/direct/115268d1aaee4606bae9f0a1e42da565.png#pic_center
在实际开发中,分支管理是一个至关紧张的实践,它可以资助团队更好地组织和协作。以下是一些基本原则和最佳实践,可以举行有效的分支管理:

[*]主分支保持稳固性: 主分支(通常是 master 或 main)应该保持稳固,反映了生产环境中的代码状态。在主分支上应该只合并已经经过测试和验证的代码。
[*]使用特性分支: 对于新功能或修复问题,应该创建专门的特性分支。每个特性分支都应该专注于办理一个特定的问题或实现一个特定的功能。如许可以使得代码更容易管理和测试。
[*]及时合并主分支变更: 团队成员应该经常将主分支上的最新变更合并到自己的特性分支中,以避免特性分支与主分支之间的差异过大,导致合并冲突难以办理。
[*]小步快走: 尽可能频繁地提交和合并代码变更,以减小每次合并的规模。这有助于低沉合并冲突的发生率,并使得问题的定位和办理更加容易。
[*]Code Review: 所有代码变更都应该经过代码检察。通过 Code Review 可以发现潜在的问题并进步代码质量。通常,在代码检察通事后才允许将代码合并到主分支。
[*]避免直接推送到主分支: 避免直接推送代码到主分支,除非是紧急修复或小的修改。如许可以确保所有的代码变更都经过了适当的检察和测试。
[*]定期清理不需要的分支: 定期清理已经完成的特性分支或不再需要的分支,以保持仓库的清洁和可管理性。
[*]合并策略选择: 根据团队的需求和项目的特点选择合适的合并策略,比如快进合并、非快进合并、rebase 等。
[*]文档化: 在团队中建立清晰的分支管理规范和流程,并确保所有成员相识和遵守这些规范。文档化可以资助新成员快速上手,并减少误解和混乱。
[*]持续改进: 不停地评估和改进分支管理流程,以适应项目的发展和团队的需求。及时调整流程可以资助团队更加高效地举行开发工作。
有了这些原则,实际的团队合作的分支实在就像下图如许(很多大型项目,上万条分支都是正常的)。
https://img-blog.csdnimg.cn/direct/848da4f366b1426081e8d8fdd0187ded.png#pic_center
7. 特性分支

做软件开发总有无穷无尽的新功能要添加,从上图也可以知道,新功能一般都会在dev分支上的根本上,构建一个feature分支来开发。这也是多数团队默认的风俗,还是那个原则,不能让实验性代码破坏主分支。
假设我如今接到了 Leader 安排的新使命,要我开发一个新功能,使命的代号为 feat-013。
于是我在dev分支的根本上,创建了feat-013分支。
https://img-blog.csdnimg.cn/direct/bb0a17d6417447f1a62605d5b781afb5.png#pic_center
过程很顺利,我提交了新功能,并切回了dev分支,准备把性能合并进来。
https://img-blog.csdnimg.cn/direct/172efc40f33c43d7842bc584e3ea1c1d.png#pic_center
但就在这时,Leader 跟我说,预算不敷,我负责的功能被砍掉了。然白干了,但是这个包罗秘密资料的分支还是必须就地销毁。但是用git branch -d会发现删不掉这个分支,因为这个分支还没有合并。不外 Git 也会提示,可以用git branch -D来删除分支。
https://img-blog.csdnimg.cn/direct/43d8c0e0c3a146b5958a1177724e1725.png#pic_center
8. 多人协作

从远程仓库克隆时,Git 会自动把当地的主分支和远程的主分支对应起来了,并且远程仓库的默认名称是origin。要检察远程库的信息,用git remote命令或者git remote -v命令。
https://img-blog.csdnimg.cn/direct/96810a7679824e31b737af281ec4c5ce.png#pic_center
上图表现了可以抓取和推送的origin地点。如果没有推送权限,就看不到push的地点。
8-1. 推送分支

所谓推送分支,就是把该分支上的所有当地提交推送到远程库,推送时要指定当地分支。在 Git 中,要推送分支到远程仓库,可以使用 git push 命令。如下图:
https://img-blog.csdnimg.cn/direct/e1d6011584e14d6b89532c4341672cb1.png#pic_center
在推送前,要确认推送的分支是哪一个,比如要推送主分支,那就先切换到主分支上,在执行git push命令,后面的origin mian表示远程仓库的main分支,也就是我把本田主分支的提交,合并到远程仓库的主分支上。
同理,推送其他分支也是类似的操作,比如dev分支,先切分支,再推送。
https://img-blog.csdnimg.cn/direct/4b0b61d0eef94f6494f722823a73d0dd.png#pic_center
使用git branch -a可以检察当地和远程仓库的所有分支信息。
https://img-blog.csdnimg.cn/direct/48426ed66164496e9498700354938673.png#pic_center
不外要留意一点,不是当地所有的分支和提交都要往远程仓库推送。起首主分支,基本都是时间与远程同步。其次是dev分支,团队所有成员都想要在上面工作,以是也要与远程同步。最后,类似修复 bug 用的临时分支和用于开发新功能feature分支,就看情况同步了。一般来说,当地用于修复 bug 的分支是不需要推送的(除非 Leader 要看你的进度),而feature分支就取决于是单独开发新功能,还是团队协作开发了。
8-2. 抓取分支

多人协作时,团队成员都会往远程仓库推送各自的修改,以及向远程仓库抓取分支。不外要留意一点,抓取分支和克隆是 Git 中的两个差别的操作。克隆是指从远程仓库复制整个仓库的操作。当使用git clone命令时,Git 会复制远程仓库的所有文件、提交历史、分支等信息到当地,并创建一个与远程仓库相同的当地仓库副本。
假设,我如今所处的团队中,我和另一个小同伴被安排一起开发一个功能,我们一起克隆了同一个远程仓库,默认情况下,都是克隆远程仓库的主分支到当地。
https://i-blog.csdnimg.cn/blog_migrate/ccb22fb14db6355c770c4f1e1830dcd4.png
但偶然间开发需要克隆的是远程仓库的dev分支(如上图,仓库远程仓库有两个分支),那么指定远程dev分支可以用下面的命令:
git clone -b dev https://github.com/zhengxinyu13/git_test.git
如果一开始克隆时,没有加上-b 选项和指定分支,克隆的仓库则是默认克隆主分支,这时也不消发急把当地仓库删掉,可以创建远程 origin 的dev分支到当地,如下命令:
git checkout -b dev
origin/dev 如今我和小同伴都用相同分支克隆下来的版本做开发,期间他把对某个文件的修改推送到origin/dev分支,而可巧我也对同个文件做出了修改,如果我也推送到origin/dev分支,就会推送失败。因为小同伴最新的提交和我试图推送的提交有冲突,办理办法也很简朴,Git 也会提示用git pull命令把最新的提交从origin/dev分支抓下来,然后在当地合并,办理冲突后再推送。具体命令如下:
git pull origin dev
这就是多人协作的工作模式,一旦认识了,就非常简朴。
9. 删除远程分支

要删除远程仓库中的分支,可以使用git push命令来向远程仓库推送一个空的分支,实际上相当于删除远程分支。以下是具体步骤:
git push origin --delete branch_name
其中,origin是远程仓库的名称,branch_name是要删除的分支的名称。
例如,如果你要删除远程仓库origin中的dev分支,可以使用以下命令:
git push origin --delete dev
执行这个命令后,dev分支将会被从远程仓库origin中删除。
六、标签管理

1. 什么是标签

Git 标签(Tag)是用来标志某个特定提交的,通常用于标识版本发布、紧张里程碑等。Git 的标签是版本库的快照,但实在它就是指向某个 commit ID 的指针,跟分支会像,但是分支可以移动,标签不能移动。
   [!TIP]
那么为什么 Git 已经有 commit ID,却还要引入 tag 呢?
同样来假设一个场景,某个软件版本发布日,Leader 跟我说:“请把上周一的那个版本打包发布,commit ID 是 6a5819e…”,我心想:“一串乱七八糟的数字不好找!”
但是同样的场景,Leader 跟我说:“请把上周一的那个版本打包发布,版本号是 v1.2。”,我就会这么想:“按照 tag v1.2 查找 commit ID 就行了。”
可以这么明白,标签就是一个让人容易记住且故意义的名字。
2. 创建标签

在 Git 中打标签非常简朴,先切换到需要打标签的分支上,然后用git tag加上标署名称既可以了。
https://i-blog.csdnimg.cn/blog_migrate/aa0c5d1060bf3abd3e58515e9e98391d.png
git tag可以检察所有的标签,加上标署名则是给最新的提交打上标签。同时用git log检察,也可以看到标签跟提交绑定在一起。
https://i-blog.csdnimg.cn/blog_migrate/68796733685e24f8d8d473e6e06d1bae.png
由于默认是最新的提交打标签,如果给之前的提交打标签,就需要找到对应的 commit ID 了。例如,我要给上图所示的“fix issues-101”打个标签,那我就先复制一下对应的 commit ID,再用git tag打上标签。上图的 commit ID 太长了,可以用下面的命令获得简短 SHA-1 标识符(abbreviated commit):
git log --pretty=oneline --abbrev-commit
https://i-blog.csdnimg.cn/blog_migrate/d624d5950fe782196aea32b1d50b6fde.png
再用git tag可以检察所有的标签,可以看多了个v0.9的标签。留意,标签不是按时间次序列出,而是按字母排序的。
https://i-blog.csdnimg.cn/blog_migrate/b7dead381d4832511fe51290a4f7559e.png
标签还可以表现提交信息,用git show命令加上标署名就可以了。
https://i-blog.csdnimg.cn/blog_migrate/12c9d997996d3f68271d3e7c637b4bf3.png
而且创建标签时,还可以顺带写上一些描述说明,用-a指定标署名,-m指定描述说明。
https://i-blog.csdnimg.cn/blog_migrate/c2bc30a4c619749ee2aef709de48229f.png
3. 管理标签

只要是人做的事都有可能犯错,因此标签也有可能会打错,但是没关系,Git 是可以删除标签的,同样是git tag命令加上-d选项就可以了。
https://i-blog.csdnimg.cn/blog_migrate/08e2c9815001783d780a6aed226b92b2.png
如今所有的标签都只是在当地仓库,不会自动推送到远程仓库。如果要推送某个标签到远程仓库,可以用git push origin <tagname>命令。
https://i-blog.csdnimg.cn/blog_migrate/7747cbe307701ad63cf79d2650417829.png
如果要一次性推送所有的标签,可以只用git push origin --tags。
https://i-blog.csdnimg.cn/blog_migrate/b06ef33c2f20c562c5bc9f87d5854b9b.png
当把所有的标签都推送到远程仓库,发现有一个标签原来要删除,一时疏忽给忘了,那就需要先在当地把标签删了,然后用下面的命令删除远程仓库的标签,其中<tag_name>是标署名。
git push origin :refs/tags/<tag_name>
这个命令的语法是通过将一个空的当地分支推送到远程仓库的标签位置来删除标签。如果要直接删除远程仓库中的标签,可以使用以下命令:
git push origin --delete <tag_name>
七、Git 自定义

1. 文件忽略

日常开发中,工作区可能有些文件是不需要提交的,例如一些测试功能时产生的 log,或者是数据库密码的设置文件等等。这些文件需要放在工作区,但是又不能提交,每次输入git status时,又会表现 Untracked files,着实让逼迫症患者抓狂。
幸亏 Torvalds 也是个逼迫症晚期,在开发 Git 的时间也想到了这一点,可以通过.gitignore文件来指定需要忽略的文件和文件夹。.gitignore文件通常位于项目的根目次中,用于告诉 Git 哪些文件和文件夹不应该被纳入版本控制。
以下是一些常见的 .gitignore 文件的用法:

[*] 忽略特定文件或文件夹:
如果想忽略特定的文件或文件夹,只需在 .gitignore 文件中添加它们的名称即可。例如:
file_to_ignore.txt
folder_to_ignore/

[*] 使用通配符:
可以使用通配符来匹配一类文件。例如,使用*可以匹配恣意字符序列,使用?可以匹配单个字符。例如:
*.log      # 忽略所有 .log 文件
*.tmp      # 忽略所有 .tmp 文件
secret_*   # 忽略以 secret_ 开头的文件

[*] 解释:
可以在.gitignore文件中使用#符号添加解释。例如:
# 这是一个注释

[*] 忽略整个文件夹:
如果想忽略整个文件夹及其所有内容,只需在.gitignore文件中添加文件夹的名称即可。例如:
node_modules/   # 忽略 node_modules 文件夹及其所有内容

   [!CAUTION]
.gitignore文件中的每一行都描述了一个忽略模式。模式可以是文件名、文件路径或者通配符,Git 会根据这些模式来确定哪些文件应该被忽略。
不外,如今也不需要从头写.gitignore文件,这个 GitHub 上的项目《github/gitignore:》(点击跳转),为我们总结了险些适用于所有软件开发的.gitignore文件,可以根据自己开发项目所用的编程语言选择,例如,我常用 C/C++ 开发,我就下载对应的文件夹。
https://i-blog.csdnimg.cn/blog_migrate/cbd14c1bc5d5c95003cb0c14b36cf387.png
那么可能会有如许的问题,那就是偶然间可能需要提交某个文件,刚好是被忽略的,那要怎么添加呢?
如果打开.gitignore文件重新修改就很麻烦,也不高效,以是在把工作区提交到暂存区时,加上-f选项,表示强制提交。具体如下:
git add -f <file_name>
2. 设置别名

在 Git 中,你可以通过设置别名来创建自定义的命令或简化常用的 Git 命令。可以在.gitconfig文件中设置别名,也可以使用git config命令来设置。
以下是一些常见的 Git 别名设置示例:

[*] 使用git config命令设置别名:
git config --global alias.co checkout
这个命令会创建一个名为 co 的别名,用于执行 git checkout 命令。
[*] 在.gitconfig文件中设置别名:
打开 .gitconfig 文件,并添加类似以下内容的设置:

    co = checkout
这个设置会创建一个名为 co 的别名,用于执行 git checkout 命令。
[*] 设置带参数的别名:
git config --global alias.br "branch -a"
这个命令会创建一个名为 br 的别名,用于执行 git branch -a 命令。
[*] 设置自定义命令别名:
git config --global alias.history "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
这个命令会创建一个名为history的别名,用于执行自定义的git log命令,可以表现更简便的提交历史。
设置好别名后,你可以直接使用别名来执行相应的 Git 命令,如许可以进步效率并减少输入量。
https://i-blog.csdnimg.cn/blog_migrate/894395f64a59bc5464d10f1ba82ec808.png
3. 设置文件

设置 Git 的时间,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。每个仓库当地的设置文件的位置都放在本仓库的.git/config文件中。
https://i-blog.csdnimg.cn/blog_migrate/0170a13a615bd19e64874980d0abbfca.png
Git 的设置文件包罗三个级别:体系级别、全局级别和仓库级别。它们分别存储在差别的位置,作用范围也差别。

[*] 体系级别设置文件:
这个设置文件位于 Git 安装目次下的etc/gitconfig文件中。它包罗了对体系上所有效户都适用的设置,通常由体系管理员举行管理。你可以使用git config --system命令来修改体系级别的设置,但可能需要管理员权限。
[*] 全局级别设置文件:
这个设置文件位于用户的主目次下的.gitconfig或者.config/git/config文件中(取决于操作体系和 Git 版本)。它包罗了对当前用户所有仓库都适用的设置。你可以使用git config --global命令来修改全局级别的设置。
[*] 仓库级别设置文件:
这个设置文件位于 Git 仓库的根目次下的.git/config文件中。它包罗了对当前仓库的特定设置。你可以使用git config命令来修改仓库级别的设置,不需要任何特殊权限。
在设置文件中,你可以设置一些 Git 的举动选项、别名、用户信息等。以下是一个简朴的示例:
    name = Your Name    email = your.email@example.com
    co = checkout
    ci = commit    st = status    editor = nano 这个设置文件设置了用户信息、一些常用的别名,以及指定了默认的文本编辑器。你可以根据需要在设置文件中添加、修改或删除设置项。
要检察当前的 Git 设置,可以使用git config --list命令,它会列出当宿世效的所有设置。
附录

1. 关于 commit 提交信息规范

编写规范的 Git commit 信息对于团队协作和项目维护非常紧张。以下是一个适用于嵌入式开发的 Git commit 信息规范示例:
<type>(<scope>): <subject>

<description>

<footer>


[*]<type>:同样是描述 commit 的类型,可能包罗:

[*]feat:新功能
[*]fix:修复问题
[*]docs:文档修改
[*]refactor:重构代码
[*]test:增长或修改测试
[*]chore:构建过程或辅助工具的变动

[*]<scope>:描述 commit 影响的范围,可以是一个模块、驱动、功能名字等。
[*]<subject>:简短描述 commit 的目的,用一句话概括。
[*]<description>:详细描述 commit 的内容。对于嵌入式体系,可能需要说明与硬件相干的修改、驱动的更新、性能优化等。
[*]<footer>:一些附加信息,比如关联的 issue、版本号、特定的硬件平台等。
例如:
feat(sensor): implement driver for temperature sensor

Added driver for XYZ temperature sensor to handle temperature readings.

- Implemented initialization routine
- Added functions to read temperature in Celsius and Fahrenheit
- Tested on hardware version 2.1

Fixes #321
在嵌入式开发中,还可能会有一些特定的标签或者约定,比如硬件版本、特定的编译器或工具链版本等信息,需要根据项目实际情况举行调整和添加。
2. 安装 Git 后,关于 ssh 的环境变量设置

从 Windows 10 版本 1709(2017 年 10 月)开始,微软初次以 beta 版形式在 Windows 10 中引入 OpenSSH 客户端和服务器,用户可以手动启用并使用 OpenSSH。原生的 SSH 功能,使 Windows 用户可以或许使用标准的 SSH 工具举行远程连接和管理。而 Git for Windows 为了确保在 Windows 环境下,可以或许方便地使用 SSH 举行身份验证和连接,Git 也与 OpenSSH 集成,提供一个一致的工具链,使用户可以使用与 Git 版本控制相干的所有功能。
Windows 体系自带的 OpenSSH 和 Git 的 OpenSSH 在环境变量中的位置如下图所示。在环境变量列表中,越靠前的变量优先级越高,因此在终端使用 SSH 工具时,是以体系自带的 OpenSSH 为重要工具的。
https://i-blog.csdnimg.cn/blog_migrate/8c6ed4d6989eddd07ef0c7bb09b7eba7.png
如果平常不使用 SSH 工具,只是用 Git 管理代码,那么使用 Git for Windows 自带的 SSH 工具可能更方便,因为它与 Git 命令行工具集成得更好。这时就需要修改环境变量来调整 SSH 的启动次序了。
起首在搜索框输入 “环境” 找到 “” 选项并进入。
https://i-blog.csdnimg.cn/blog_migrate/18016c87759691dab96c7ae9ca117a60.png
点击 “环境变量”。
https://i-blog.csdnimg.cn/blog_migrate/00c2deec9b79b7dbead92243a3f0c25d.png
双击打开体系变量的 “Path”。
https://i-blog.csdnimg.cn/blog_migrate/a12f6a6be947694d0f7db151016585cc.png
新建一个新的环境变量,填入 Git 的 OpenSSH 路径,一般在 Git 安装路径的 usr\bin 文件夹中,内里包罗了 ssh.exe 及相干工具。
https://i-blog.csdnimg.cn/blog_migrate/cddcb210a107481c5d8a7e3b5f2813da.png
再把两个环境变量上移到 C:\Windows\System32\OpenSSH\ 之前,然后一步步按 “确定” 退出即可。
https://i-blog.csdnimg.cn/blog_migrate/338dafa7e51f3259bf0333fcbd0e897e.png
如果需要举行通例的 SSH 操作(例如远程服务器管理),使用 Windows 自带的 OpenSSH 工具是合适的选择。
参考资料

Git教程 - 廖雪峰的官方网站 (liaoxuefeng.com)
Git - Book (git-scm.com)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Git 新手快速入门教程