Git

介绍

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

历史

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

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

版本控制

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

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

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

主要优势和功能包括:

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

工作流程

工作流程

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

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

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

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

一般工作流程为:

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

安装

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

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

在终端输入:

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

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

查看配置信息:

git config --list

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

基本命令

初始化

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

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状态,即从库中取出文件,覆盖当前修改。
git status [-s]

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

文件

删除

git rm FileName

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

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

移动/重命名

git mv OldFile NewFile

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

日志

查看提交日志

git log

–graph:查看分支合并图。

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

查看引用日志

git reflog

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

比较

git diff [--cached]

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

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

忽略

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

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

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

版本控制

添加

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

git add FileName

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

提交

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

git commit -m "提交信息"

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

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

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

恢复

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

git restore FileName

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

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

回退

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

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连接。

生成密钥

ssh-keygen -t rsa -C "Email"

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

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

测试

ssh -T git@github.com

出现successfully即成功。

最后可以通过ssh克隆。

仓库管理

添加

git remote add RemoteName Url

移除

git remote rm RemoteName

查看

git remote -v

代码管理

克隆

git clone Url

推送

git push [RemoteName BranchName|TagName]

-f:强制推送

拉取

git pull [RemoteName RemoteBranch:LocalBranch]

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

抓取

git retch [RemoteName BranchName]

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

冲突

产生原因:

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

解决:

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

关于GitHub访问慢

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

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

分支管理

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

查看

git branch

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

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

创建

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

git branch BranchName [CommitID|BranchName|TagName]

-m:修改分支名。

切换

git checkout BranchName

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

合并

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

git merge BranchName

删除

删除本地分支:

git branch -d BranchName

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

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

删除远程分支:

git push origin -d BranchName

标签管理

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

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

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

查看

查看所有标签:

git tag

查看标签信息

git show TagName

创建

git tag TagName

会在当前commit上创建标签。

删除

删除本地标签

git tag -d TagName

删除远程仓库标签

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规范。