前端工具 | Git (版本管理)

Git 基础

Git 是一个免费开源的版本控制系统,用来快速高效地管理项目开发的源码。

  • 通过 git 可以跟踪代码的状态,也可以在修改代码后对代码状态进行更新,还可以在需要时将已经修改过的代码恢复到之前存储的状态。
  • 更强大的是,使用 git 管理代码时,可以创建代码分支(branch),代码分支相当于一段独立的代码记录,我们可以在分支上对代码进行任意的修改,而这个修改只会影响当前分支,不会对其他分支产生影响。同时,可以对分支进行合并,合并后,一个分支的修改便可在另一分支上生效。
  • Git 代码库是分布式的,每一个程序员的计算机上都有一个完整的代码仓库(去中心化),当然也有一个远程服务器。
  • 安装:直接官网下载安装即可, git -v 查看是否安装成功。

1 配置用户身份信息

Git 复制代码
git config --global user.name "用户名"
git config --global user.email "邮箱地址"

设置好用户信息,当进行项目修改的时候就会记录用户名。

该设置在 github 仓库主页显示谁提交了该文件。

2 初始化仓库

进入某文件夹执行git init即可完成项目的初始化,目录中多出一个.git目录(可能隐藏),用来存储代码的版本信息。

  • 建议使用空目录学习 Git,以免产生不必要的错误。目录名尽量使用英文名。
  • 有了.git 就意味着项目现在已经开始被 git 管理了,不希望项目被 git 管理时,只需删除 .git 即可。

git 文件状态

未跟踪:没有被git所管理(刚刚添加到目录中的文件)

已跟踪:被 git 管理

  • 暂存,表示文件的修改已经保存,但是尚未提交到 git 仓库
  • 未修改,已入库,磁盘中的文件和 git 仓库中文件相同,没有修改
  • 已修改,表示磁盘中文件已被修改,和 git 仓库中文件不同

可以通过git status来查看目录及里面的文件的的状态,还会给你下一步的操作提示。

4 版本管理流程

新增文件(未跟踪) ---> add ---> 已跟踪(暂存) --- commit---> 未修改 ---> 修改代码 ---> 已修改 ---> add ---> 暂存---> commit --->.....

① 未跟踪--->已跟踪(暂存)

git add <filename> 将文件切换到暂存状态

git add * 将所有已修改或者未跟踪的文件转为暂存

② 暂存--->未修改

git commit -m "提交日志" 将暂存文件提交到仓库中

git commit -a -m "提交日志" 提交所有已修改的文件(相当于跳过了 add 步骤,但是未跟踪的不会直接提交)

③ 未修改--->已修改: 代码被修改

④ 已修改--->未修改: 重复 add 和 commit

常用命令

git restore <filename>``git restore *

放弃 untracked 的修改,将文件重置到上一个已经暂存的状态

git rm <filename>删除文件(和 add 是同一层级的反向操作)

执行 git rm,使得文件变为一种执行了删除操作的暂存状态(commit 之后才能真正把文件从本地 GIT 仓库和磁盘里删除。)

该命令仅能删除未修改的文件,对于已修改(还未暂存和提交)的文件,git 存在保护机制防止误删。------> 强制删除git rm <filename> -f

git restore --staged <filename>把文件从暂存的状态取消,也就是把删除这个操作变成"未跟踪"。 然后我再git restore,就能把文件重置到上一个暂存状态,也就是还没执行删除操作的时候,这样就能找回删除的文件。

git mv <oldfilename> <newfilename> 重命名文件

在 VSCODE 中使用

推荐 Gitlen 插件。

初始化项目

创建一个文件并写入内容

暂存+提交本地仓库

Branch 分支

什么是分支

每一次代码提交(commit)都会创建一个与之对应的节点,git 通过一个一个节点来记录代码的状态。

  • 所有节点会构成一个树状结构(代码状态平行宇宙)
  • 树的分支与分支之间相互独立,在 B 分支上的所有 commit 操作不会影响 A 分支
  • 默认仓库只有一个主分支 master(main)

分支操作

  • git branch 查看当前分支
  • git branch <branch name>创建分支
  • git branch -d <branch name>删除分支
  • git switch <branch name> 切换分支
  • git switch -c <branch name>创建+切换分支

合并分支 merge

在开发中,我们都需要给自己搞一个分支然后在其上编写代码,代码写完后,把自己的分支合并到团队的主分支中。

  • 切回主分支:git switch master
  • 合并 bug1 分支:git merge bug1
  • 删除已合并的分支:git branch -d bug1

无冲突时会快速合并;

分支之间存在冲突时,需要手动处理冲突:保留当前 / 保留要合并的分支 / 都保留

【应用场景】为啥需要分支

网站已经是上线使用的稳定版(master分支),现在接到了新需求需要添加新功能,但同时不能影响稳定版的正常使用。此时我需要创建一个新的分支 update,并在其上做更新。确保完成后我才将 update 分支合并到 master,作为下一个稳定版本发布。

在做 update 的过程中,客户反映 master 上有 bug,那我切回 master 分支,去改 master 这个平行宇宙的 bug。当然也不能直接在 master 上改,还是创建新分支 bug,切到 bug 再去改。改完后我再合并到主分支。

去公司的第一件事就是把源码从远程仓库上拽下来,然后创建 一个自己的分支再开发(这样你写的代码再恶心也不会影响公司的主分支)。

Rebase 变基

每一次 merge 都会在树状图上产生记录,当项目非常复杂,创建、删除、合并操作非常频繁时,会使得 git 的提交历史记录变得非常混乱。

rebase 和 merge

merge 合并两个分支,默认会提交合并后的内容,关注点在真实的提交历史上面。

rebase 并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面。

rebase 操作会丢弃当前分支已提交的 commit,会篡改历史!故不要在已经 push 到远程,和其他人正在协作开发的分支上执行 rebase 操作。

rebase 原理

如图, test 分支是基于 master 分支在B处的提交节点创建的,其后 master 分支又经过迭代提交了两次(C到D),test 分支也基于 B 往前继续更新了两次(到F节点)。所以说,两者从B开始就走向了分叉。

(1)git merge test 生成了一个新的提交点 G,merge 命令把两个分支的最新快照(F、E 和 D、C)以及二者最近的共同祖先(B)进行三方合并,合并的结果是生成一个新的快照 G(并提交)。

(2)当我们在master (待变基分支) 上执行git rebase test(基分支) 时:

  1. git 就会从两者的共同祖先B开始,提取 master 分支上的修改,也就是 C, D 两个 commit ,并保存起来;
  2. 然后将 master 分支指向 test 分支最新提交的节点,也就是 F 节点;
  3. 然后把提取到的 C, D 接到 F 后面,在这个过程当中,会删除原来的 C, D commit 记录,生成新的 C', D',虽然C', D'和原来的C, D commit的内容是一样的,但是 commit id 是不同的。 【总结】 rebase 操作简单解释就是改变基底:master 分支原来的基底是A,现在变成了以 test 分支最新的提交 F 做为新的基底了。

远程仓库 github

git remote

git remote 显示当前关联的所有远程库,追加 -v 能看到更详细的信息

git remote add origin <url> 关联一个远程库

git remote remove origin 取消关联

origin:远程仓库的本地备注名,自定义即可,用于在推送时指定推送到哪个远程库,和远程库本身没有任何关联。

git branch -M main 将本地分支名修改成 main

git push -u origin main 本地 main 分支推送到名为 origin 的远程库,追加 -u 则推送后和当前分支关联,下次推就直接 git push,就不用写那么详细了。

git push <远程库名> <本地分支>:<远程分支> 推送到其他还没关联的库

git clone <url> xxx拉取代码+关联远程+ 重命名为 xxx

远程协作相关

① 从远程库拽取代码 git clone url

② 推送我的代码 git push ,如果本地库版本低于远程库,要先 git fetch 使得二者保持一致才能推得上去;

fetch 会从远程仓库下载所有代码,但是不会将代码和我们当前分支自动合并,我们能看到的还是我们本地的版本,所以必须得手动合并一下, git pull 拉取代码并自动合并,就是fetch + merge

git merge origin/master 将远程库 origin 的 master 分支合并到本地。打开源代码文件处理好冲突,git add+commit 提交一下处理好的文件;

④ 此时再推送 git push

所以,在推送代码前,一定要从远程库中拉取最新的代码。

【实际场景】

你提交成功下班后,同事也向该远程仓库提交了新的内容。第二天上班时,你需要拉取线上仓库的最新版本。

因此每天工作的第一件事就是git pull拉取线上的最新版本,下班要做的就是 git push,将本地代码里自己今天的工作成果提交到线上仓库。

VSCODE 快捷方式

关联远程库:如图点击+号,按照提示给远程库 取名+键入 url

推送 branch: 第一次推送需要手动绑一下远程库的账号密码

Tag 标签

tag 干什么用

git log查看所有 commit 记录,每个记录为一个节点,都有一个 commit id。

git switch <commit id> 使头指针指向 id 节点所在的位置。

头指针默认指向当前分支的最新节点处。当头指针被切到其他地方,就是头指针分离。分离头指针的状态下也可以操作代码,但是这些操作不会出现在任何分支上,所以没啥意义,so 尽量不要在分离头指针的情况下操作,如果非得操作,那就开一个新的分支。

git switch -c <分支名> <commit id>从 id 所在的节点处开辟一条新的分支,commit id 在指定时只要键入前几个字符即可。

给提交 log 打标签,方便我们快速定位并切换到某个节点。

git tag

git tag #查看所有 tag

git tag <tag name> #给当前所在节点打标

git tag <tag name> <commit id> #给 id 所在的节点打标

先前切换头指针的操作git switch <commit id>就可以变成git switch <tag name>

先前 git switch -c <分支名> <commit id>就可以写成 git switch <分支名> <tag name>

推送被打标的节点 git push <远程仓库名> <tag name>

git push <远程仓库名> --tags

git tag -d <tag name>#删除标签

git push <远程仓库名> --delete <tag name> #删除远程标签

gitignore

有些文件,比如 node_modules 不需要被 git 管理,.gitignore 设置那些需要被 git 忽略的文件。

bash 复制代码
# 排除/node_modules目录下的所有内容
/node_modules/

# 排除/dist目录下的所有内容
/dist/

参考

[1] 全网最通俗易懂的讲解: git rebase和git merge的原理和区别 [ ⭐️建议收藏] - 掘金 (juejin.cn)

[2] www.bilibili.com/video/BV112...

相关推荐
_.Switch31 分钟前
Python Web 架构设计与性能优化
开发语言·前端·数据库·后端·python·架构·log4j
libai34 分钟前
STM32 USB HOST CDC 驱动CH340
java·前端·stm32
Java搬砖组长1 小时前
html外部链接css怎么引用
前端
GoppViper1 小时前
uniapp js修改数组某个下标以外的所有值
开发语言·前端·javascript·前端框架·uni-app·前端开发
丶白泽1 小时前
重修设计模式-结构型-适配器模式
前端·设计模式·适配器模式
程序员小羊!1 小时前
UI自动化测试(python)Web端4.0
前端·python·ui
破z晓1 小时前
OpenLayers 开源的Web GIS引擎 - 地图初始化
前端·开源
维生素C++2 小时前
【可变模板参数】
linux·服务器·c语言·前端·数据结构·c++·算法
vah1012 小时前
python队列操作
开发语言·前端·python
项目題供诗2 小时前
尚品汇-H5移动端整合系统(五十五)
java·服务器·前端