Git

介绍

Git 是一种代码托管技术。理解成是一个开源的分布式版本控制系统,可以敏捷高效地处理任何或小或大的项目。

历史

林纳斯。托瓦兹在 1991 年创建了开源的 Linux,随着社区的不断壮大,代码需要人工合并,十分麻烦。

于是他花费两周的时间用 C 语言编写了一个分布式版本控制系统。

版本控制

版本控制(Version Control)是一种用于跟踪和管理文件或代码变化的系统。

它允许多人协同工作,并且可以在不同版本之间进行有效的比较、恢复和合并。

版本控制系统记录文件的修改历史,使得用户可以回溯到先前的版本,并在需要时恢复到特定的状态。

主要优势和功能包括:

  1. 版本追踪: 版本控制系统可以追踪文件的每一次修改,包括添加、删除、修改等操作。这使得用户可以了解文件的变化历史。
  2. 协同工作: 多人协同工作时,版本控制系统可以协调各人对同一文件的修改,防止冲突,并能够合并不同版本的修改。
  3. 回滚和恢复: 如果出现错误或需要回到之前的某个稳定状态,版本控制系统允许用户轻松地回滚到先前的版本。
  4. 分支和合并: 版本控制系统允许创建分支,这是一种并行开发的方式,每个分支都可以独立进行修改。之后,这些分支可以合并回主干。
  5. 追踪贡献者: 版本控制系统可以记录每个修改的作者,追踪贡献者的工作。

工作流程

工作流程

Workspace: 工作区,就是你平时存放项目代码的地方。

Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是 一个文件,保存即将提交到文件列表信息。

Repository: 仓库区 (或版本库),就是安全存放数据的位置,这 里面有你提交到所有版本的数据。其中 HEAD 指向最新放入仓库的 版本。

Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项 目组中的一台电脑用于远程数据交换。

一般工作流程为:

  1. 创建 / 修改文件。
  2. 添加到暂存区。
  3. 提交到版本库。

安装

Git - Downloads 下载对应操作系统的安装包,按照提示安装即可。

安装的 Git 需要配置一下用户的信息。

在终端输入:

plaintext
git config --global user.name "用户名"

git config --global user.email "邮箱"

查看配置信息:

plaintext
git config --list

也可以在 ~/.gitconfig​文件进行查看和修改。

基本命令

初始化

一般的文件夹是不会直接被 Git 托管的,而需要我们进行初始化后才能进行后续的操作。

plaintext
git init [PATH]

不提供 PATH 会初始化当前文件夹。

初始化后的文件夹会创建一个.git​隐藏文件夹,包含了当前项目的所有相关信息。

状态

untracked

未跟踪状态,说明该文件位于此文件夹中,但并没有加入 Git 的监听。可通过 git add​添加为 Staged 状态。

tracked

已跟踪状态,又分为三个状态。

  • Staged:暂存状态,执行 git commit​则将修改同步到版本库中,这时库中的文件和本地文件又变为一致,文件为 Unmodify 状态,执行 git reset HEAD FileName​取消暂存,文件状态为 Modified。
  • Unmodified:文件已经添加,但未修改,即版本库中的文件快照内容与文件夹中完全一致,这种类型的文件有两种去处,如果它被修改,而变为 Modified,如果使用 git rm​移出版本库,则成为 Untracked 文件。
  • Modified:文件已修改,仅仅是修改,并没有进行其他的操作,这个文件也有两个去处,通过 git add​可进入暂存 staged 状态,使用 git checkout​则丢弃修改过,返回 unmodify 状态,即从库中取出文件,覆盖当前修改。
plaintext
git status [-s]

-s:简洁输出,仅展示文件的状态的单词首字母。

文件

删除

plaintext
git rm FileName

只是删除了工作区和暂存区的文件,版本库中可仍然存在。

手动删除的文件,只是删除了工作区的文件,暂存区和版本库可仍然存在。

移动 / 重命名

plaintext
git mv OldFile NewFile

移动或重命名工作区的文件,并记录到暂存区。

日志

查看提交日志

plaintext
git log

–graph:查看分支合并图。

–oneline:将记录压缩为一行展示。

查看引用日志

plaintext
git reflog

通常用于恢复丢失的提交或分支。

比较

plaintext
git diff [--cached]

–cached:比较暂存区和版本库的差异。

比较工作区和暂存区的文件差异。

忽略

在项目目录下.gitignore​文件。

忽略规则(同 Linux 文件匹配):

  • /​开头表示命令。
  • *​通配多个字符。
  • ?​通配单个字符。
  • []​包含单个字符的匹配列表。
  • !​表示不忽略匹配到的文件或目录。

版本控制

添加

将工作区中修改的文件添加到暂存区中。

plaintext
git add FileName

也可使用.​通配符来调配所有修改的文件。

提交

将暂存区中修改的文件提交到版本库中。

plaintext
git commit -m "提交信息"

-m:需要提供本次提交的信息,说清该版本的更新情况即可。

-a:添加修改到暂存区并提交到版本库,不能用于第一次提交的文件。

–amend:覆盖最后一次提交信息,可用于提交信息的修改。

恢复

将工作区、暂存区进行恢复还原。

plaintext
git restore FileName

–staged、-S:取消暂存区未提交的修改。

–worktree、-W(默认):取消工作区未暂存的修改。

回退

将工作区、暂存区、版本库进行版本的回退。

plaintext
git reset HEAD|版本号

–soft:将版本库进行回退,工作区及暂存区不变。

–mixed(默认):将版本库及暂存区进行回退,工作区不变。

–hard:将版本库、暂存区及工作区都进行回退。

其中 HEAD 指代当前版本,HEAD^ 指代上个版本,以此类推,HEAD~N 即指代前 N 个版本。

远程仓库

  • GitHub:是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯的版本库格式进行托管。
  • Gitee:是国内的一个代码托管平台,由于服务器在国内,所以相比于 GitHub,码云速度会更快。
  • GitLab:是一个用于仓库管理系统的开源项目,使用 Git 作为代码管理工具,并在此基础上搭建起来的 web 服务。

SSH 协议

SSH(Secure Shell)是一种网络协议,用于通过不安全的网络安全地访问远程计算机。它为网络中的数据传输提供了加密、认证和数据完整性校验,广泛应用于远程登录、文件传输以及远程命令执行等场景。

工作原理

  • 客户端连接到服务器
    客户端使用 SSH 客户端(如 ssh​命令、PuTTY 等)连接到远程主机。客户端会向服务器发起连接请求,通常包括要连接的主机地址、端口(默认是 22)等信息。
  • 密钥交换和加密设置
    在建立连接后,SSH 会通过密钥交换算法(如 Diffie-Hellman)协商出一个共享的密钥。这个过程确保了即使连接过程中存在第三方窃听者,也无法获取到加密的通信内容。
    同时,协议会确定使用的加密算法(如 AES)和消息认证算法(如 HMAC)来确保数据的保密性和完整性。
  • 服务器认证
    服务器通过向客户端提供自己的公钥进行身份验证,客户端可以验证服务器是否是预期的服务器,从而防止中间人攻击。
  • 用户认证
    客户端会通过用户名和密码、私钥等方式对自己进行身份验证。私钥和公钥的配对是常见的认证方式,私钥存储在客户端,公钥存储在服务器上。客户端用私钥签名并通过服务器的公钥验证。
  • 数据传输
    完成认证和加密设置后,客户端与服务器之间的所有通信都通过加密通道进行。包括远程命令的执行、文件的传输等。
  • 会话终止
    当任务完成后,客户端和服务器会断开连接,结束会话。

主要功能

  • 远程登录
    SSH 最常见的用途之一是远程登录。通过 SSH,用户可以在远程计算机上执行命令,就像在本地计算机上操作一样。
  • 文件传输
    SSH 协议还支持通过 SFTP​(SSH File Transfer Protocol)和 SCP​(Secure Copy Protocol)协议安全地传输文件。SFTP 和 SCP 都建立在 SSH 之上,提供了加密的文件传输功能。
  • 远程命令执行
    SSH 可以用来执行远程命令而不需要登录到服务器。通过传递命令参数,SSH 允许在连接时直接执行远程命令。
  • 端口转发
    SSH 支持端口转发功能,允许将本地端口或远程端口映射到另一台计算机的端口。这通常用于绕过防火墙或建立 VPN 连接。

生成密钥

plaintext
ssh-keygen -t rsa -C "Email"

会在用户目录下生成.ssh​文件夹,包含了公钥和私钥,作为用户的凭据。

然后在远程仓库托管平台配置 ssh 公钥。

测试

plaintext
ssh -T git@github.com

出现 successfully 即成功。

最后可以通过 ssh 克隆。

仓库管理

添加

plaintext
git remote add RemoteName Url

移除

plaintext
git remote rm RemoteName

查看

plaintext
git remote -v

代码管理

克隆

plaintext
git clone Url

推送

plaintext
git push [RemoteName BranchName|TagName]

-f:强制推送

拉取

plaintext
git pull [RemoteName RemoteBranch:LocalBranch]

拉取远程仓库的代码,且合并到本地仓库。

抓取

plaintext
git retch [RemoteName BranchName]

抓取远程仓库的代码,但不会合并到本地仓库。

冲突

产生原因:

  • 不同分支下的 merge。
  • 同一个分支下的 pull 或 push。

解决:

  • push 之前,先 pull。
  • 手动删除冲突内容的代码。

关于 GitHub 访问慢

获取最新 DNS,修改本地 hosts 文件,并刷新 DNS。

  • Windows 刷新 DNS
plaintext
ipconfig/flushdns
  • MacOS 刷新 DNS
plaintext
sudo killall -HUP mDNSResponder

分支管理

git 支持分支管理,可以创建多个分支同时进行,最后合并即可。

查看

plaintext
git branch

-r:列出所有远程分支。

-a:列出所有本地和远程分支。

创建

在当前分支创建一个子分支。

plaintext
git branch BranchName [CommitID|BranchName|TagName]

-m:修改分支名。

切换

plaintext
git checkout BranchName

-b:在当前分支下创建并切换到该分支。

合并

将指定分支合并到当前分支。

plaintext
git merge BranchName

删除

删除本地分支:

plaintext
git branch -d BranchName

-d:删除已合并的分支。

-D:强制删除,不管该分支是否已合并。未合并删除会给出 CommitID,可再次使用该 ID 创建分支。

删除远程分支:

plaintext
git push origin -d BranchName

标签管理

Git 可以给历史中的某一个提交打上标签,以示重要。

比较有代表性的是人们会使用这个功能来标记发布结点 (v1.0、v1.2 等)。

标签指的是某个分支某个特定时间点的状态。通过标签,可以很方便的切换到标记时的状态。

查看

查看所有标签:

plaintext
git tag

查看标签信息

plaintext
git show TagName

创建

plaintext
git tag TagName

会在当前 commit 上创建标签。

删除

删除本地标签

plaintext
git tag -d TagName

删除远程仓库标签

plaintext
git push RemoteName :refs/tags/TagName

git push RemoteName --delete TagName

Gitflow

git-flow 是 Git 进行代码管理的行为规范。

工作流通过为功能开发、发布准备和维护分配独立的分支,让发布迭代过程更流畅。

严格的分支模型也为大型项目提供了一些非常必要的结构。

分支介绍

  • master:主干分支,开发完成的上线的项目版本;最终上线的主分支,不能轻易去改动,每次向该分支 merge 时,都应该打上 tag,且该分支不应该存在 commit。
  • hotfixes:热部署分支,进行主干分支的补丁操作;由 Master 分支创建,用于热修复 Master 分支上 BUG 及问题,开发完后需要 merge 回 Master 分支及 Develop 分支,并在 Master 分支打上 tag。
  • release:预部署分支,测试工程师的调用的分支;由 Develop 分支创建,用于预部署,供测试人员调用,若发现 BUG 或问题则直接进行修复并 merge 回 Develop 分支及 Master 分支。
  • develop:开发分支,开发源代码分支;由 Master 分支创建,用于开发的专用分支,所有开发者的代码汇聚地,当开发完成一个阶段后,需要 merge 回 Release 分支等待上线。
  • feature:功能分支,开发者使用的分支;由 Develop 分支创建,用于某功能模块的开发,该分支开发完成后需要 merge 回 Develop 分支,merge 后的分支可删除可保留。

AVN

gitflow-avh:Git 的一个高效拓展工具。

使用该工具可以更快速的实现 Git Flow 规范。