Git的使用
Git的使用
以下为学习过程中的极简提炼笔记,以供重温巩固学习
学习准备
准备工作
无
学习目的
学会通过Git 版本控制系统,协同工作
摘要
详细介绍了Git的基本操作,如仓库管理、暂存区使用、版本回退、分支创建与合并、远程仓库操作、多人协同开发以及VSCode中的Git集成。通过实例演示了登录页面、bug修复和黑马头条数据管理平台的发布流程。
可能看了会觉得我啰嗦,但这正正是我彻底弄懂后所提炼出来的、最精简的原理阐述记录,连在这方面0认知的人,能在无图情况下,看了文字都能懂
复述提炼的能力,以及他人能0门槛读懂你所复述提炼的输出标的,恰好证明了理解的到位情况
Git 版本控制系统
- 背景:根据开发的项目进度、产品经理定义等多个因素影响,开发的代码会有不同的版本迭代
认识Git
概念:一个免费开源,分布式的代码版本控制系统,帮助开发团队维护代码
作用:
- 以版本形式,记录每一个状态下/每一次编辑更新的代码内容
- 可以切换到此前的/不同的代码版本
- 多人协同开发同一个项目时,高效合并代码内容
学习包括:
- 个人本机使用:通过 Git 基础命令来管理编写的源码,掌握概念
- 多人共享使用:团队开发时,同一个项目的代码版本管理,通过远程仓库,共享管理的代码版本
Git安装:
- Windows系统:通过 exe 程序安装,默认下一步即可 Git for Windows
- Mac系统:dmg 程序,默认下一步即可
Git for Windows包括:
Git BASH (包括bash cmd)
- Git for Windows 提供用于从命令行运行 Git 的 BASH 仿真。*NIX 用户应该感到宾至如归,因为 BASH 仿真的行为就像 LINUX 和 UNIX 环境中的 “git” 命令一样。
Git 图形用户界面 (在路径Git\cmd\git-gui.exe)
- 正如 Windows 用户通常期望的图形用户界面一样,Git for Windows 还提供了 Git GUI,这是 Git BASH 的强大替代方案,提供几乎所有 Git 命令行函数的图形版本,以及全面的可视化差异工具。
Shell 集成
- 只需右键单击 Windows 资源管理器中的文件夹即可访问 BASH 或 GUI。
Git 凭证管理器
- Git 凭据管理器提供安全的凭据存储,并对 GitHub、Azure Repos 和其他流行的 Git 托管服务进行身份验证。
检验安装成功状态:
- 打开 bash 终端(git 专用终端)
- 可以到安装目录下打开Git Bash
- 也能到编译器,如vscode,在终端右上角下拉中,选择Git Bash
- 通过git专用终端,能在运行用户名称后,看到分支名
- 在完成git安装后,cmd终端下虽然能运行git命令,但是看不到分支名,看不到文件状态
- 命令 git -v (git命令,查看版本号)
- 打开 bash 终端(git 专用终端)
某某windows MINGW64 ~
$ git -v
git version 2.45.2.windows.1
Git 配置用户信息
配置:正式使用前,需要全局配置用户名和邮箱
目的:Git会在你每次提交代码产生版本时,记录下你的用户名和邮箱信息,在多人项目中,表明自己的身份
命令:
git config --global user.name "itheima" git config --global user.email "itheima@itcast.cn" git config --list //显示本地 repo 配置设置
总结:
- 学习 Git 目的:管理代码版本,记录,切换,合并代码
- 学习 Git 包含哪些协同使用场景:现在本机自己使用,再学习多人共享使用
- 如何安装使用?
- win下程序双击安装;
- 在Git Bash独立终端下使用
- 在 VSCode 中使用 bash 终端以及 git 命令
- 备注:VSCode 中可以同时开两个终端,可以切换使用
- 使用git命令的时候要用Git bash终端,好处:能显示分支名,能显示文件状态,保存文件时输入目录可以按tab补充文件路径
掌握git仓库
Git仓库(repository)
- 本质:是一个以.开头的、名称为git的,隐藏文件夹.git
- 概念:该文件夹记录了所在项目下,所有提交过的文件的状态内容,存储着修改的历史记录状态
创建Git仓库的两种方式:
- 把本地文件夹转换成 Git 仓库:到项目目录文件夹下,终端运行命令 git init 运行后项目下就会自动生成.git文件夹
- 从其他服务器上克隆 Git 仓库:git clone git_url 终端命令执行完毕后,会在终端所在目录,从远程服务器,克隆一份项目仓库到本地
需求:创建一个空白的 Git 仓库
- 在终端中运行,注意终端的目录
# 终端运行命令 git init 以新建仓库
git init
#======================#
# 返回提示:已新建空白仓库
Initialized empty Git repository in I:/路径/.git/
# 返回提示:已有仓库
Reinitialized existing Git repository in I:/路径/.git/
- 总结:
- 什么是 Git 仓库 ?
- 记录项目下所有文件状态内容和历史记录的地方
- 以.git 隐藏文件夹形式存在,目的是为了不被误删,误删后所有的版本历史记录就没了
- 如何创建 Git 仓库?
- 把本地文件夹转换成 Git 仓库:命令 git init
- 从其他服务器上克隆 Git 仓库
- 什么是 Git 仓库 ?
Git 的三个区域
- Git使用时:不同的区域/仓,有不同的作用
- 工作区:实际开发时操作的项目代码的文件夹
- 即git_study概念,项目编辑的地方,例如在此目录下编辑html、js等
- 通过 git ls-files 命令,查看当前暂存区有哪些文件
- 通过 git add 命令,将你认为编写完/开发完的项目文件,保存到暂存区
- 暂存区:保存之前的准备区域(暂存改动过的文件)
- 在 .git/index中,暂时存储即将被我们保存变更的文件内容(提交保存前的记录)
- 因为还没提交版本库,版本库中无记录,如暂存区的文件被删除,则无法找回
- 暂存区相当于中间状态
- 版本库:提交并保存暂存区当中的内容,且在每次提交保存时,产生一个版本快照
- 在 .git/object中
- 工作区:实际开发时操作的项目代码的文件夹
- 命令使用注意:
- git add
git add 加需要暂存的文件名字
,如果文件在文件夹下,需要写相对路径git add 加需要暂存的相对路径
,可以将整个目录加到暂存区git add .
暂存所有改动过的文件内容,可以多次运行,项目代码改动后,可以运行git add . 覆盖- 如在项目目录下首次运行
git add .
,则是将整个项目目录,连带node_module依赖,都全部加到暂存区 - 因为还没提交版本库,版本库中无记录,如暂存区的文件被删除,则无法找回
- 可以理解为,git add是将 电脑现状 与 工作区 与 暂存区 3个同步的命令
- git commit
- 当觉得当前设计的代码没有问题,较为稳定,想提交一次,产生一次历史记录时,运行
git commit -参数 "本次产生的版本对应代码注释说明"
git commit -m 说明
命令为:将所有暂存的文件提交到版本化历史记录git commit -am 说明
命令为:将所有跟踪的文件提交到版本化历史记录- 每执行一次
git commit
命令,都会将暂存区当前的状态内容,在版本库中产生一个版本快照 - 每执行一次
git commit
命令所产生的版本记录快照不会覆盖 - 每个版本记录,都有一个对内容使用sh哈希算法产生的一个40位的哈希字符串,以标识当前版本名字
- 在运行
git commit -参数 说明
提交版本前,建议都先git ls-files
一下,以确认当前暂存区的文件列表/待将变化同步到工作区的文件列表 - 备注:个人实践经验,在
git commit -参数 "注释说明"
命令的"注释说明"中,如果没有使用引号包裹时,不能写&符号,此符号会被认为在执行git commit命令结束时,同时执行另一个命令,可加上引号包裹,如git commit -参数 "完成vue3&gpt"
则能成功提交git
- 当觉得当前设计的代码没有问题,较为稳定,想提交一次,产生一次历史记录时,运行
- 使用git命令的时候要用Git bash终端,
- 好处:能显示分支名,保存文件时输入目录可以按tab补充文件路径
- git status
- 通过
git status
查看主分支状态 - 通过加参数
git status -s
查看文件状态 git status -s
只显示状态不明的目录,以及有过修改的文件的已修改状态(M)
- 通过
- git reset
git reset 文件名/目录
以--mixed参数的方式,将暂存区中的文件名/目录撤销,不影响工作区git reset HEAD
,HEAD为当前版本的意思,清空性撤销在暂存区中的,尚未曾提交过版本库部分的新内容,恢复当前版本的暂存区
- git add
将所有跟踪的文件提交到版本化历史记录
命令 | 作用 |
---|---|
git ls-files | 查看当前暂存区有哪些文件 |
git add 文件名/整个相对路径 | 暂存指定文件/整个相对路径的文件 |
git add . | 暂存所有改动的文件 |
git commit -m "注释说明" | 提交暂存的文件并保存,产生版本快照 |
git commit -am "注释说明" | 提交跟踪的文件并保存,产生版本快照 |
git status -s | 只显示状态不明的目录, 以及有过修改的文件的已修改状态(M) |
git reset HEAD | HEAD为当前版本的意思,清空性撤销在暂存区中的、 尚未曾提交过版本库部分的新内容,恢复当前版本的暂存区 |
- 需求:把登录页面新增后,暂存并提交
$ git add src/login/index.js #通过相对路径,加文件到暂存区
warning: in the working copy of 'src/login/index.js', LF will be replaced by CRLF the next time Git touches it
$ git ls-files #确认当前暂存区的文件列表/待将变化同步到工作区的文件列表
src/login/index.js
$ git commit -m "1登录页-逻辑" #从暂存区提交到版本库,命名为:第一次提交,登录页的逻辑js文件
[master (root-commit) e80482a] 1登录页-逻辑
1 file changed, 126 insertions(+)
create mode 100644 src/login/index.js
备注:
- win下开发,CRLF的警告提示可忽略,上述提示是指在git建立版本记录时,会将文档里面的代码,将LF换行的地方转为CRLF,即回车CR+换行LF
总结:
- Git 使用时有哪些区域 ?
- 工作区,暂存区,版本库
- 工作区的内容,最终要如何保存在版本库中?
- git add 将工作区的变化内容,添加到暂存区
- 等待时机后 git commit 将暂存区的当前状态记录,提交保存到版本库,产生一次版本快照记录
- Git 使用时有哪些区域 ?
Git 的文件状态
状态显示:
- 在使用Git bash终端时,通过git ls-files命令列出,发现路径或文件名前面,会有两列,分别列出目录/文件的git状态
- 在VScode中,在左侧资源管理器,树状图文件名后面,文件会有状态显示
Git 管理文件时的状态:
未跟踪(U):在工作区新建的文件,从未被 Git 管理过
- 如,新放入项目目录的文件,处于未跟踪状态(U),git ls-files 下找不到
- 未跟踪文件,在VScode左侧资源管理器中以(U)显示,在Git bash路径或文件名前面以(??)显示
已跟踪:Git 已经知道和管理的文件
- 如,已使用git add暂存过的文件,在git ls-files会有显示,里面的文件处于已跟踪状态
- 新加入项目目录的文件,在经过git add后,变为新添加状态(A),在VScode中,在左侧资源管理器,树状图文件名后面,文件状态显示为A
- 新添加状态下的文件,因为还没提交版本库,版本库中无记录,如此时暂存区的文件被删除,则无法找回
- 可以将新添加状态(A)的文件,简单理解为:已跟踪但待修改状态
- 通过git status -s查看时,已跟踪的文件可能会不显示
未修改(''):提交保存后的状态/刚读取项目状态/下一次提交前尚未发生变动的状态
- 工作区、暂存区、版本库三个区域下的文件都一致的状态,为未修改状态('')
- 可以将前一次版本的状态,简单理解为未修改状态
- 已提交版本库的所有已跟踪的文件,都会恢复为未修改状态
- 提交保存后的状态/刚读取项目状态/下一次提交前尚未发生变动的状态,都是未修改状态,git status -s运行后目录不显示,VScode中也不显示状态
已修改(M):执行git commit提交版本前,文件有过改动的状态
- 显示为已修改(M)的文件,必然与刚打开/刚加载/前一个版本的文件不一样
- 显示为已修改(M)的文件,都尚未执行git commit提交版本,尚未产生版本
- 执行git commit提交版本,并不会清空暂存区
- 执行git commit提交版本,文件状态由已修改(M)变为未修改(''),在VScode中左侧的资源管理器,树状图文件名后面状态消失
- 本地电脑上修改了文件,但未加到暂存区,此时Git bash中,M显示为红色
- 本地修改了文件,已加到暂存区,此时Git bash中,此时M显示为绿色
备注:
- 新添加状态(A)的文件,如在git中丢失,无法通过git找回
- 终端下,在路径或文件名前面列出的状态,以两列显示,第一列是暂存区状态,第二列是工作区状态
- 未跟踪(U)和新添加(A)状态,在VScode左侧资源管理器,树状图文件名后面显示
- 新添加(A)、未修改(")、已修改(M)状态,在Git bash路径或文件名前面显示
- 未跟踪(U)在Git bash路径或文件名前面以(??)显示
文件状态 | 概念 | 场景 |
---|---|---|
未跟踪(U) | 从未被 Git 管理过 | 新文件、 git ls-files下找不到 |
新添加(A) | 第一次被 Git 暂存 | 之前版本记录无此文件 git ls-files能看到 但未被保存到工作区 版本库尚未有此文件记录 |
未修改(") | 三个区域统一 | 提交保存后的状态 刚读取项目状态 下一次提交前尚未发生变动的状态 |
已修改(M) | 工作区内容变化 | 修改了内容后产生的状态 绿色M为工作区与暂存区一致 红色M为工作区改动尚未add到暂存区 |
修改状态 | 对应场景与概念 |
---|---|
_ | 电脑当前文件状态=工作区=暂存区,还没有版本 |
_ | 概念:新文件还没发版本 |
电脑当前文件状态≠工作区=暂存区,还没有版本 | |
概念:新文件曾经加过暂存区,还在改,还没发最终第一版 | |
_ | 电脑当前文件状态≠前一次工作区=前一次暂存区=前一次版本库 |
_ | 概念1:发过版本,开发改动后,本地保存了,还没进行过git提交 概念2:发过版本,开发改动后,还不确定,先在本地保存,先不提交git |
_ | 电脑当前文件状态=工作区=暂存区≠前一次版本库 |
_ | 概念:发过版本,开发改动后,本地保存了,进行过git提交,等待最后发版 发版前都应该处于这种状态 |
电脑当前文件状态≠前一次工作区=前一次暂存区≠前一次版本库 (注意:这里三者都不相等) | |
概念1:电脑当前文件状态已与暂存区不一样,可将暂存区文件先发一版提交,然后再 git add 一次当前电脑的状态到暂存区,变为 _ 状态,再发一个版本 概念2:电脑当前文件状态已与暂存区不一样,可将电脑当前状态文件,本地另存一份,再 git reset 从版本库回退一版文件到暂存区,回到 _ 状态,然后继续开发 |
实践案例-暂存区的添加与撤销
# 将终端目录下的所有文件加到暂存区
$ git add .
# 逐个文件显示CRLF替换,CRLF的警告后续我这里就不展示了
warning: in the working copy of 'xxxxxxxx', LF will be replaced by CRLF the next time Git touches it
# 确认当前暂存区的文件列表/待将变化同步到工作区的文件列表
$ git ls-files
#当前暂存区文件列表逐个文件显示
node_modules/ws/lib/subprotocol.js #...等等在暂存区的文件
# ....
# 撤销/清空在暂存区中的,尚未曾提交过版本库部分的内容
$ git reset HEAD
# 再次确认当前暂存区的文件列表/待将变化同步到工作区的文件列表
$ git ls-files
# 此时只显示前面一次加到版本库中的,尚在暂存区的文件
src/login/index.js
# ------------------------------------
实践案例-暂存区的状态查看
# 查看暂存区和工作区文件状态
$ git status -s
# -s 只显示状态不明的目录,以及有过修改的文件的已修改状态(M)
?? .vscode/ # ...等等未被跟踪的目录
# 提交保存后的状态/刚读取项目状态/下一次提交前尚未发生变动的状态,都是未修改状态,git status -s运行后目录不显示
# 查看主分支状态
$ git status
# 显示主分支未被追踪
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# .vscode/
# dist/
# node_modules/
# ....
# ------------------------------------
实践案例-已加到暂存区,但尚未修改到版本库的状态查看
# 单独加另一个文件到暂存区
$ git add src/login/index.css
# 再次确认当前暂存区的文件列表/待将变化同步到工作区的文件列表
$ git ls-files
#当前暂存区文件列表逐个文件显示
src/login/index.css
src/login/index.js
# 再次查看暂存区和工作区文件状态
$ git status -s
# 左边绿色A显示已放入暂存区
A src/login/index.css
# ------------------------------------
# 到index.css文件中,随意修改,保存
# 再次查看暂存区和工作区文件状态
$ git status -s
# 左边绿色A显示已放入暂存区,右边红色M显示在工作区中有过文件更改,但未将更改加到暂存区
AM src/publish/index.js
# 再次将最新从工作区文件加入暂存区
$ git add src/login/index.css
# 此时工作区与暂存区一致,只剩下左边绿色A
A src/login/index.css
# 将新样式文件提交版本
$ git commit -m "1登录页样式"
# 再次查看暂存区和工作区文件状态
$ git status -s
# 发现已经没有文件处于暂存状态,所有文件处于未修改状态
实践案例-已加到暂存区,也将修改状态同步到版本库后,改变文件状态查看
# 加一个目录到暂存区
$ git add src/login
# 从暂存区提交到版本库,命名为:第一次提交,登录页目录
$ git commit -m "1登录页目录"
# 再次查看暂存区文件列表
$ git ls-files
src/login/assets/login-bg.png # ...等等显示加到暂存区的目录下的所有文件
# ...
# 再次查看暂存区和工作区文件状态
$ git status -s
# 此时只显示未被跟踪的目录
?? .vscode/ # ...等等未被跟踪的目录
# 其他目录都是未修改状态,不显示
# ------------------------------------
# 到项目中任意修改一下文件,如src/login/index.js,在电脑上ctrl+s保存后,再查看文件状态
$ git status -s
M src/login/index.js
# 此时右边的M为红色,表示电脑当前文件状态,与前一次的工作区文件不一致
# 电脑当前文件状态=/=前一次工作区=前一次暂存区=前一次版本库
# ------------------------------------
# 接着电脑上的文件,修改并本地保存
# 再将修改过的文件加到暂存区
$ git add src/login/index.js
# 再次查看暂存区和工作区文件状态
$ git status -s
M src/login/index.js
# 此时左边的M为绿色,工作区的修改已同步到暂存区
# 电脑当前文件状态=工作区=暂存区=/=前一次版本库
# ------------------------------------
# 接着将电脑上的文件,修改并本地保存
# 但不加到暂存区
# 再次查看文件状态
$ git status -s
MM src/login/index.js
# 此时左边的M为绿色,前一次工作区的修改已同步到暂存区
# 右侧的M为红色,电脑当前文件状态,与前一次的工作区文件不一致
# 电脑文件状态=/=前一次工作区=前一次暂存区=/=前一次版本库
# 注意,此时电脑当前文件状态与工作区/暂存区与版本库三者都不一样
# ------------------------------------
# 将暂存区的文件撤销,不影响工作区
git reset src/login/index.js
# 再次查看暂存区和工作区文件状态
$ git status -s
M src/login/index.js
# 此时的右边的M为红色,已将暂存区中的修改记录撤销
# 工作区当前有新修改未被同步到暂存区,暂存区还是前一次版本的状态
# 电脑当前文件状态或当前工作区=/=前一次暂存区=前一次版本库
Git 暂存区使用
暂存区:
- 意义:
- 暂时存储
- 可以临时恢复代码内容
- 令工作区与版本库解耦
- 概念:在正式发版/提交前,都应该先放到暂存区
- 意义:
暂存区回退 -> 覆盖工作区:
- 命令:git restore 目标文件(注意:使用前必须先确认,是完全覆盖时,才使用)
从暂存区移除文件(叠加取消文件跟踪状态,恢复未跟踪):
- 命令:git rm --cached 目标文件
- 移除文件后,可以通过git ls-files来确认,文件已取消跟踪
从暂存区撤销文件的修改
概念:当你在工作区修改了文件,并且已经使用git add命令将其添加到暂存区,但现在想要撤销暂存区的内容,恢复暂存区之前的文件状态
恢复之前的暂存区/清空性撤销在暂存区中的修改,尚未曾提交过版本库部分的新内容:
- 命令:git reset
- 注意1:暂存区的修改撤销,但工作区的修改会保留
- 注意2:可以撤销跟踪移除
- 注意3:使用时在后面加路径
- 注意4:git reset 参数缺省时,默认为 git reset --mixed
- 注意5:git reset HEAD为恢复当前版本暂存区;git reset HEAD^为恢复上一个版本的暂存区;git reset HEAD^^为恢复上两个个版本的暂存区;git reset HEAD~100为恢复倒数100个版本
实践案例-已加到暂存区,也将修改状态同步到版本库后,改变文件状态查看
# 查看暂存区文件列表
$ git ls-files
src/login/index.js # ...等等显示加到暂存区的目录下的所有文件
# ...
# 本地电脑上删除/修改src/login/index.js文件
# 通过暂存区回退,覆盖工作区
$ git restore src/login/index.js
# 命令执行后,被删掉的文件再次回到目录下,被修改的部分,覆盖性回到之前内容
# 取消src/login/index.js的跟踪状态
$ git rm --cached src/login/index.js
# 再次查看暂存区文件列表
$ git ls-files
# 此时暂存区列表已没有src/login/index.js,且vscode资源管理器中,文件的状态变为未跟踪状态
# 恢复src/login路径下的文件跟踪,或恢复src/login/index.js文件跟踪,撤销跟踪移除
$ git reset src/login
# 再次查看暂存区文件列表,此时已恢复跟踪src/login/index.js
- 总结:
- 使用git restore 命令,通过暂存区回退,覆盖工作区,实现恢复
- 使用git rm --cached 目标文件文件/路径 命令,从暂存区移除已暂存文件/路径
练习-登录页面
需求:新增 js 代码并暂存提交产生新的版本快照
步骤:
- 资源管理器中,新增 js 文件和内容,文件放入
- 临时存放在暂存区,通过git add加到暂存区
- 提交保存到版本库,通过git commit提交到版本库
注意:
- 先有暂存区,再有版本库,版本库里面的文件,必定是来源于暂存区的提交
- 产生版本提交前,都应该先确认,在暂存区下的文件的效果
- 文件修改后,再次运行一下git add,覆盖到暂存区
- 确认提交,git commit要写清楚版本名称注释
- 查看提交历史:git log --oneline
- 版本库名称前的id,就是版本号
实践案例-查看提交历史
$ git log --oneline
3f0966e (HEAD -> master) 1登录页目录
ed50810 1登录页目录
5693723 1登录页-逻辑
64b4c77 1登录页目录
179ab84 1登录页-css
e80482a 1登录页-逻辑
Git 版本回退/切换
回退版本概念:把版本库某个版本对应的内容快照,恢复到工作区/暂存区
- 首先是,电脑当前文件状态,包括编辑状态、跟踪状态都会有变化
- 工作区和暂存区,根据模式差异,相应回到标的版本下的工作区和暂存区状态
查看提交历史:
- git log --oneline,找到需要回退到的版本号
- git reflog --oneline ,查看完整的日志,一般用于看另一个分支下版本
回退命令的不同指令及概念:
git reset --soft 版本号
- 使用soft命令回退时,会将 回退标的版本 ,与 当前状态 作对比,将 回退标的版本 之后产生/修改的文件保留,并改为未跟踪状态,留在工作区
- 命令执行后,文件回到标的版本状态,后续加入版本的文件,在git ls-files暂存区列表中有显示,在vscode/bash中的状态显示为A新添加跟踪
- 工作区与暂存区版本状态一样,但可能出现当前电脑文件状态与他们不一样,由于是版本回退,标的工作区与标的暂存区,肯定和保留的文件不一样
- 此时如果有需要,可以将带一红一绿两个的文件,另存一份
git reset --hard 版本号
- 使用hard命令回退时,清空暂存区,并且撤销工作区的所有修改,两个区都回到标的版本号下的状态
- 注意:回到版本号commit的状态,会丢弃所有未提交的修改,使用这个命令需要小心,不加版本号则为回到最近一个版本的状态
git reset --mixed 版本号(与 git reset 等价)
- 使用缺省命令/mixed命令回退时,清空暂存区,暂存区的文件修改状态被撤销,跟踪状态会保留,在此之后产生/修改的文件,会保留在工作区
- 命令执行后,暂存区的文件回到标的版本状态,文件的跟踪情况视乎保留下来的跟踪列表,后续加入版本的文件在vscode/bash中的状态显示为U未跟踪
- 当前已跟踪的文件,在执行 git ls-files 后会显示为_,因为当前的文件和暂存区中的文件不一样
注意1:
- 只有记录在版本库的提交记录才能恢复,不同回退命令的差异,仅在针对变动部分的处理是彻底舍弃,还是另放回工作区,供重新编写
注意2:
- 回退到标的版本后,在标的版本的基础上继续修改 -> 暂存 -> 提交版本仓库操作,即可产生新的提交记录,本质上是产生了新的分支
- 项目在标的版本后至今的原有修改,仍然存在,本质上是一个未正式命名的分支
- 两个分支会以标的版本为共有节点
- 当分支头HEAD回退到了节点时,可通过 git reflog --oneline 查看完整的日志
注意3:git reset 的代码执行顺序是:
- 先从版本库,按照版本号的状态,恢复到暂存区,然后工作区再对比暂存区的内容,从暂存区去恢复/删除
- 如果先执行git reset --mixed 版本号,再执行git reset --hard 版本号,那么--mixed 命令已把标的暂存区恢复,且将此之后产生/修改的文件,保留在工作区,再执行--hard时,工作区下的文件已丢失跟踪关系,不会再执行恢复/删除
注意4:如果在提交到暂存区之后,工作区的同一文件又有了新的修改
- 这时候如果使用git reset HEAD,Git会自动处理冲突,保留工作区的修改,而撤销暂存区的修改
- 如果使用git reset --hard HEAD,则会丢弃暂存区和工作区的所有修改,回到最初的状态
命令 | 概念 | 场景 |
---|---|---|
git reset --soft 版本号 | 回退标的版本 | 将标的版本至当前状态的区别,都放到工作区和暂存区 |
git reset --hard 版本号 | 丢弃当前状态 | 推倒标的版本至今的开发,全部舍弃 |
git reset --mixed 版本号 (与 git reset 等价) | 重新构建暂存区 | 将暂存区恢复标的版本,重新从工作区构建暂存区 |
实践案例-将当前状态回退到某个版本
# 查看当前版本库状态
$ git log --oneline
3f0966e (HEAD -> master) 1登录页目录
ed50810 1登录页目录
5693723 1登录页-逻辑
64b4c77 1登录页目录
179ab84 1登录页-css
e80482a 1登录页-逻辑
# 查看暂存区文件列表
$ git ls-files
src/login/assets/login-bg.png
src/login/assets/logo-4kb.png
src/login/assets/logo.png
src/login/index.css
src/login/index.js
src/login/index.less
# 通过--soft 版本号回退
$ git reset --soft e80482a
# 命令执行后,文件回到标的版本状态,后续加入版本的文件,在git ls-files暂存区列表中有显示,在vscode/bash中的状态显示为A新添加跟踪,并且已有暂存
# 工作区与暂存区版本状态一样,但可能出现当前电脑文件状态与他们不一样,由于是版本回退,工作区与暂存区版本肯定和回退标的版本不一样
# 此时如果有需要,保守起见,可以将带一红一绿两个MM的文件,另存一份
# 基于上一个回退的情况下,叠加操作,看效果区别
# 通过--mixed 版本号回退
$ git reset --mixed e80482a
# 命令执行后,暂存区的文件回到标的版本状态,文件的跟踪情况视乎保留下来的跟踪列表,后续加入版本的文件在vscode/bash中的状态显示为U未跟踪
# 当前已跟踪的文件,在执行 git ls-files 后会显示为_M红,因为当前的文件和暂存区中的文件不一样
# 工作区与暂存区版本状态一样,但可能出现当前电脑文件状态与他们不一样,由于是版本回退,工作区与暂存区版本肯定和回退标的版本不一样
# 基于上两个回退的情况下,叠加操作,看效果区别
$ git reset --hard e80482a
HEAD is now at e80482a 1登录页-逻辑
# 命令执行后,暂存区跟踪列表还在,但跟踪状态已清空,后续加入版本的文件在vscode/bash中的状态显示为U未跟踪,标的版本已跟踪的文件会显示为_M红
# 叠加命令执行后,此前丢失跟踪关系的文件,仍然存在
# 先从版本库,按照版本号的状态,恢复到暂存区,然后工作区再对比暂存区的内容,从暂存区去恢复/删除
# 如果先执行git reset --mixed 版本号,再执行git reset --hard 版本号,那么--mixed 命令已把标的暂存区恢复,且将此之后产生/修改的文件,保留在工作区,再执行--hard时,工作区下的文件已丢失跟踪关系,不会再执行恢复/删除
# 查看完整的日志
$ git reflog --oneline
e80482a (HEAD -> master) HEAD@{0}: reset: moving to e80482a
e80482a (HEAD -> master) HEAD@{1}: reset: moving to e80482a
e80482a (HEAD -> master) HEAD@{2}: reset: moving to e80482a
e80482a (HEAD -> master) HEAD@{3}: reset: moving to e80482a
3f0966e HEAD@{4}: commit: 1登录页目录
ed50810 HEAD@{5}: commit: 1登录页目录
5693723 HEAD@{6}: reset: moving to HEAD
5693723 HEAD@{7}: reset: moving to HEAD
5693723 HEAD@{8}: commit: 1登录页-逻辑
64b4c77 HEAD@{9}: reset: moving to HEAD
64b4c77 HEAD@{10}: commit: 1登录页目录
179ab84 HEAD@{11}: commit: 1登录页-css
e80482a (HEAD -> master) HEAD@{12}: reset: moving to HEAD
e80482a (HEAD -> master) HEAD@{13}: commit (initial): 1登录页-逻辑
- 总结:
什么是 Git 回退/切换版本?
- 把版本库某个版本对应的内容快照,恢复到工作区/暂存区
强制覆盖暂存区和工作区的命令?
- git reset --hard 版本号
如何查看提交历史?
- git log --oneline
- git reflog --oneline
通过 Git 删除某个文件并产生新记录版本
需求:删除 editor.js 文件,并产生一次版本记录
目的:通过产生新记录版本的方式,使得删除的状态被版本库保留记录
步骤:
- 手动删除电脑上的文件,影响工作区
- 状态同步
- 通过git add 覆盖性地将电脑上的文件状态,同步到工作区和暂存区
- 通过git rm --cached 目标文件文件/路径 命令,手动从暂存区移除已暂存文件/路径
- 暂存区状态已与版本库产生差异,通过git commit -m 提交版本库,保存为新版本
个人总结技巧:
- 如需从某个版本中,删掉包含的某个文件,最好的方法是
- 在电脑上将要删掉的文件重命名,让其本地存档一份,重命名时,会丢失跟踪情况
- 通过git rm --cached 被删目标文件文件/路径 命令,手动从暂存区移除已暂存文件/路径
- 重新git commit -m 备注写清楚删掉了某文件的名字,提交,作为新版本
- 通过本地文件重命名导致自动丢失跟踪的方法,去区分开哪些是因为git reset模式差异导致的跟踪丢失,还是人为的删文件的需求导致的跟踪丢失
- 通过本地文件重命名,只要不再次 git add . 暂存区中还是有这个文件,可以改为 git add 目录/文件,然后提交,还是会被记录
- 清空Git bash终端控制台命令:clear ;有别于cmd的:cls
- 如需从某个版本中,删掉包含的某个文件,最好的方法是
实践案例-删除某个文件并产生新记录版本
$ git ls-files
src/login/index.js
git add src/login/
warning: in the working copy of 'src/login/index.css', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'src/login/index.less', LF will be replaced by CRLF the next time Git touches it
$ git ls-files
src/login/assets/login-bg.png
src/login/assets/logo-4kb.png
src/login/assets/logo.png
src/login/index.css
src/login/index.js
src/login/index.less
$ git status -s
A src/login/assets/login-bg.png
A src/login/assets/logo-4kb.png
A src/login/assets/logo.png
A src/login/index.css
A src/login/index.less
git log --oneline
e80482a (HEAD -> master) 1登录页-逻辑
$ git log
commit e804xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxb (HEAD -> master)
Author: xxxxxxx <xxxxxxx+xxxxxxx@users.noreply.github.com>
Date: xxx xxx 13 22:30:53 2024 +0800
$ git reflog --oneline
e80482a (HEAD -> master) HEAD@{0}: reset: moving to e80482a
e80482a (HEAD -> master) HEAD@{1}: reset: moving to e80482a
e80482a (HEAD -> master) HEAD@{2}: reset: moving to e80482a
e80482a (HEAD -> master) HEAD@{3}: reset: moving to e80482a
# ...等等
$ git commit -m 1登录页目录1
5 files changed, 52 insertions(+)
create mode 100644 src/login/assets/login-bg.png
create mode 100644 src/login/assets/logo-4kb.png
create mode 100644 src/login/assets/logo.png
create mode 100644 src/login/index.css
create mode 100644 src/login/index.less
$ git reflog --oneline
1bc0a97 (HEAD -> master) HEAD@{0}: commit: 1登录页目录1
e80482a HEAD@{1}: reset: moving to e80482a
e80482a HEAD@{2}: reset: moving to e80482a
e80482a HEAD@{3}: reset: moving to e80482a
# ...等等
$ git log --oneline
1bc0a97 (HEAD -> master) 1登录页目录1
e80482a 1登录页-逻辑
$ git ls-files
src/login/assets/login-bg.png
src/login/assets/logo-4kb.png
src/login/assets/logo.png
src/login/index.css
src/login/index.js
src/login/index.less
# 本地电脑上重命名src/login/index.js为indexindex.js
# indexindex.js的状态变为U未跟踪
# 并删掉暂存区文件
$ git rm --cached src/login/index.js
rm 'src/login/index.js'
# 将暂存区删掉后的情况保存为新版本
$ git commit -m 1登录页目录-删除逻辑
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
[master afd5eab] 1登录页目录-删除逻辑
1 file changed, 126 deletions(-)
delete mode 100644 src/login/index.js
#再次确认版本
$ git log --oneline
afd5eab (HEAD -> master) 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
- 个人总结技巧:如需从某个版本中,删掉包含的某个文件,最好的方法是
- 在电脑上将要删掉的文件重命名,让其本地存档一份,重命名时,会丢失跟踪情况
- 通过git rm --cached 被删目标文件文件/路径 命令,手动从暂存区移除已暂存文件/路径
- 重新git commit -m 备注写清楚删掉了某文件的名字,提交,作为新版本
- 通过本地文件重命名导致自动丢失跟踪的方法,去区分开哪些是因为git reset模式差异导致的跟踪丢失,还是人为的删文件的需求导致的跟踪丢失
- 通过本地文件重命名,只要不再次 git add . 暂存区中还是有这个文件,可以改为 git add 目录/文件,然后提交,还是会被记录
- 清空Git bash终端控制台命令:clear ;有别于cmd的:cls
定义忽略文件
概念:通过 .gitignore 隐藏配置文件,可以让所在的 git 本地版本仓库,彻底忽略跟踪指定文件
目的:让 git 仓库更小更快,避免重复无意义的文件管理
例如:
- 系统或软件自动生成的文件
- 如npm包管理器下载的第三方包依赖文件夹 node_modules
- 编译产生的结果文件
- 如分发文件夹/打包构建目录 /dist
- 如果是离线项目,如果需要别人开箱即用的话,则需要打包;通常不打包
- 运行时生成的日志文件,缓存文件,临时文件等
- 例如vscode运行时产生的配置目录文件 .vscode、*.log等
- 涉密文件,密码,秘钥等文件
- 密钥文件,证书 .pem、.cer、.crt、.key、*.csr 格式
- 系统或软件自动生成的文件
注意:
- 创建多人协同开发项目/将项目代码开源前,必须建立忽略规则,让git忽略跟踪
创建:
- 项目根目录新建 .gitignore 文件
- 填入相应配置来忽略指定文件
- 反推:有 .gitignore 文件的目录,必定是一个仓库所在的根目录
注意:
- 被忽略文件,在vscode资源管理器中,呈现为灰色
- 如果文件已经被暂存区跟踪过,可以从暂存区移除即可(如在开源项目中的某些文件发现不合适)
- 可以通过 git rm --cached 移除,也可以通过修改 .gitignore 文件后,使用 git add . 来更新配置实现移除
- 如需忽略特定名字文件夹,就写文件夹名字,如果是忽略某特定文件,需要写全文件名和后缀
- .gitignore 文件作用在整个目录下的所有文件层级,不限路径
- *星号为匹配任意字符的通配符,如*.*为所有类型所有名称的文件,*.加后缀为某种类型的所有文件,名称加.*为所有某个名称的文件
实践案例- .gitignore 配置案例
# 忽略npm下载的第三方包
node_modules
# 忽略分发文件夹/构建目录
dist
# 忽略VScode配置文件
.vscode
# 忽略密钥文件,证书
*.pem
*.cer
*.crt
*.key
*.csr
# 其他类型
*.log
# 特定文件
xxx.txt
实践案例- 增加忽略文件配置
$ git add .gitignore
warning: in the working copy of '.gitignore', LF will be replaced by CRLF the next time Git touches it
$ git commit -m 2登录页目录-增加忽略文件配置
[master 50ab3b8] 2登录页目录-增加忽略文件配置
1 file changed, 21 insertions(+)
create mode 100644 .gitignore
$ git log --oneline
50ab3b8 (HEAD -> master) 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
$ git ls-files
.gitignore
src/login/assets/login-bg.png
src/login/assets/logo-4kb.png
src/login/assets/logo.png
src/login/index.css
src/login/index.less
分支
分支包含的概念:
master 主分支印记:
- 本质上是指向某个提交记录/提交节点的印记
- 用于标记项目下的有效版本/稳定版本/用于发布正式版本,即经过测试和验证的可靠代码
- master 主分支是可变的,但主分支只有一个
- 一般情况下,不应该直接在master分支上进行开发,而是通过其他分支进行开发,并在开发完成后将代码合并到master分支
- 在确认下一个开发分支有效前,不要轻易改变主分支
- 在接收其他分支合并前,其他分支的变化不会影响主分支
- 我这里理解为印记,有的人将master也理解为是一个类型的指针
HEAD 编辑指针:
- 本质上是起到 指明当前编辑/使用所在版本库 的作用
- HEAD 指针影响工作区/暂存区的代码状态
- 我这里理解为 编辑指针/光标 ,像鼠标输入光标一样,指明/标出当前键盘所在编辑地方
- 在编辑的一定是工作区/暂存区
- git reflog --oneline 或 git log --oneline 会用 -> 箭头 HEAD 标出当前编辑的工作区/暂存区,将会合并到哪个分支/版本
- git reflog --oneline 能够看到当前分支及其所继承的主分支,但如果HEAD 编辑指针切换到了其他分支,就看不到当前分支的继承情况,需要通过 git log --oneline 来查看HEAD指针的移动情况
dev/develop 次分支印记:
- develop 次分支是用于集成和测试新功能的分支
- 用于标记项目下的 旁分支/复制/副版本
- dev 次分支是在master分支的基础上创建的,一般有多个,通常主分支拥有最多次分支
- 在develop分支上进行的开发工作可能包括添加新功能、修复错误和进行一些实验性的工作
- 当开发完成并通过测试后,develop分支的代码将会合并到master分支,形成一个新的稳定版本
- 从开源代码平台项目创建项目分支时,会标记为dev
- 在master上新创建的dev分支会继承master分支的所有提交,通过 git log 可以看出来
feature分支:
- feature分支是用于开发单个功能或解决某个问题的分支
- 当需要开发新功能时,可以从develop分支上创建一个新的feature分支,并在该分支上进行开发工作
- 在feature分支上进行的开发工作是相对独立的,不会影响其他分支的代码
- 一旦功能开发完成并通过测试,可以将feature分支合并回develop分支
git branch 创建分支:
- 在当前 HEAD 编辑指针下,执行 git branch 分支名,会在当前 HEAD 编辑指针所指向的版本记录基础上,创建也指向这个版本记录的新分支
- 新的分支,也指向当前指针所指向的这个分支记录
git checkout 指定 HEAD 编辑指针所作用版本:
- 执行 git checkout 分支名 ,以更改当前 HEAD 编辑指针所作用的版本
- 需要改变 HEAD 编辑指针所作用版本,才能更改 git commit 版本提交的标的版本
- 不更改master 主分支印记,主分支仍旧指向稳定版
注意:
- 从次分支印记通过 git checkout 命令切换回到主分支/后退回主分支,那些期间加入的文件不是恢复未被跟踪,而是会被删除!
- 可以通过版本回退,恢复期间被删掉的文件/记录
分支的使用场景:
- 开发新需求过程中,保证主线代码master随时可用,隔离未确定的代码和效用影响
- 在现有代码基础上,新开 dev/develop 次分支来开发新需求,确保多人协同开发时,各自分支开发,互不干扰影响,提高效率(git log --oneline看不到没有继承的其他分支)
- 在 修复 Bug 过程中,单独创建feature分支解决 Bug
- 执行git add前,必须先确认当前 HEAD 编辑指针是指向哪个版本
- 在master上新创建的dev分支会继承master分支的所有提交,通过 git log 可以看出来
需求:创建内容列表 content 分支,并产生3次提交记录
- 步骤:
- 创建分支命令:git branch 分支名
- 切换分支命令:git checkout 分支名
- 步骤:
实践案例- 创建新分支,补充新分支,产生3次提交记录
$ git log --oneline
50ab3b8 (HEAD -> master) 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
MINGW64 /i/xxxxx (master)
$ git ls-files
.gitignore
src/login/assets/login-bg.png
src/login/assets/logo-4kb.png
src/login/assets/logo.png
src/login/index.css
src/login/index.less
# 创建新分支content(括号内显示当前编辑指针在master分支下)
MINGW64 /i/xxxxx (master)
$ git branch content
MINGW64 /i/xxxxx (master)
# 查看本地仓版本记录
$ git log --oneline
50ab3b8 (HEAD -> master, content) 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
# 切换 HEAD 编辑指针到content版本下
MINGW64 /i/xxxxx (master)
$ git checkout content
Switched to branch 'content'
# 再次列出本地仓版本记录,发现content在前,HEAD 编辑指针指向content
MINGW64 /i/xxxxx (content)
$ git log --oneline
50ab3b8 (HEAD -> content, master) 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
# 查看当前Git仓库中,有哪些分支名字,当前操作命令行括号内已经是(content),编辑指针已在content下,此时才能继续开发
MINGW64 /i/xxxxx (content)
$ git branch
* content
master
# 进行开发,变动文件,补充新分支,产生3次提交记录
MINGW64 /i/xxxxx (content)
# 开发并同步暂存区
$ git add src/content/index.css
# 提交版本
$ git commit -m 3内容管理页-样式
[content 86f4a9b] 3内容管理页-样式
1 file changed, 119 insertions(+)
create mode 100644 src/content/index.css
# 开发并同步暂存区
$ git add src/content/index.js
# 提交版本
$ git commit -m 4内容管理页-逻辑
[content 5fc69ec] 4内容管理页-逻辑
1 file changed, 170 insertions(+)
create mode 100644 src/content/index.js
# 再次列出本地仓版本记录,发现 HEAD 编辑指针指向 content分支所在 4内容管理页-逻辑这个版本 ,master印记标记的主分支仍然停留在‘2登录页目录-增加忽略文件配置这个’版本
# 能够看到当前分支及其所继承的主分支,但如果HEAD 编辑指针切换到了其他分支,就看不到当前分支的继承情况
# 在master上新创建的dev分支会继承master分支的所有提交,通过 git log 可以看出来
$ git log --oneline
5fc69ec (HEAD -> content) 4内容管理页-逻辑
86f4a9b 3内容管理页-样式
50ab3b8 (master) 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
# 切换分支回到主分支master
$ git checkout master
Switched to branch 'master'
# 发现此前通过git add 加到版本记录的文件,不是恢复未被记录的情况,而是会被删除
# 切换回到最新编辑的content分支
$ git checkout content
Switched to branch 'content'
# 文件被git所恢复
- 提示:
- 常/多多创建版本,以防突如其来的需求变更,或者修复bug需求
- 以一个小功能/小模块为节点来创建版本
练习-登录 bug 修复
需求:新建 login-bug 分支,做2次提交记录(对手机号长度,验证码长度做判断)
步骤:
- 切回到主分支:
- master 是主分支的默认名字
- git checkout master 让HEAD编辑指针回到默认主分支
- 创建新分支:
- git branch 新名字
- 如:git branch login-bug
- 切换到新分支:
- git checkout 新分支名字
- 如:git checkout login-bug
- 修改代码,暂存,并产生提交记录,保存新分支版本
实践案例- 切回主分支,创建feature分支解决 Bug,切换到新分支,修改代码,并产生提交记录,保存新分支版本
# 切换分支回到主分支master
$ git checkout master
Switched to branch 'master'
# 发现此前通过git add 加到版本记录的文件,不是恢复未被记录的情况,而是会被删除
# 基于master主分支,创建新分支login-bug(括号内显示当前编辑指针在master分支下)
MINGW64 /i/xxxxx (master)
$ git branch login-bug
# 切换 HEAD 编辑指针到 新分支login-bug 版本下
MINGW64 /i/xxxxx (master)
$ git checkout login-bug
Switched to branch 'login-bug'
# 已切换到login-bug分支下,修改文件,产生提交记录,保存新分支版本
MINGW64 /i/xxxxx (login-bug)
$ git add src/login/index.js
# 提交版本
$ git commit -m 5修复login-index
[login-bug 7c36880] 5修复login-index
1 file changed, 126 insertions(+)
create mode 100644 src/login/index.js
# 基于新的login-bug分支,通过 git log --oneline查看提交的版本记录
$ git log --oneline
7c36880 (HEAD -> login-bug) 5修复login-index
50ab3b8 (master) 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
# 此时看不到另一个分支的记录
# 基于新的login-bug分支,通过 git reflog --oneline 查看提交的版本记录
$ git reflog --oneline
7c36880 (HEAD -> login-bug) HEAD@{0}: commit: 5修复login-index
50ab3b8 (master) HEAD@{1}: checkout: moving from master to login-bug
50ab3b8 (master) HEAD@{2}: checkout: moving from content to master
5fc69ec (content) HEAD@{3}: checkout: moving from master to content
50ab3b8 (master) HEAD@{4}: checkout: moving from content to master
5fc69ec (content) HEAD@{5}: commit: 4内容管理页-逻辑
86f4a9b HEAD@{6}: commit: 3内容管理页-样式
50ab3b8 (master) HEAD@{7}: checkout: moving from master to content
50ab3b8 (master) HEAD@{8}: commit: 2登录页目录-增加忽略文件配置
afd5eab HEAD@{9}: commit: 1登录页目录-删除逻辑
# 此时能看到 HEAD编辑指针 的版本移动记录,通过键盘上下箭头,能看到更多版本
# 此时退出的操作,与vim编辑器一样,按q退出,光标前已显示:冒号
- 注意重点:
- 每次修改bug/基于主分支做任何操作前,先从master创建一个dev次分支出来,再把HEAD编辑指针移到次分支,再去操作
分支-吸收与删除
需求:把已经修复bug的分支 login-bug ,吸收回到 master 分支,并删除login-bug 分支
步骤:
- 切回到要吸收的分支上:
- git checkout 要吸收的分支印记名
- 如回到主分支,以吸收其他分支 git checkout master
- 吸收其他分支过来:
- git merge 将要吸收的分支印记名
- git merge 命令会将 原主分支 与 标的吸收分支最新版本 之间的版本提交记录,拼接吸收到原主分支
- 形成新的主分支后,master主分支印记,会移到所吸收部分的、最新的版本,即Fast-forward
- 被吸收的分支,在被吸收后,其分支名下的版本印记,也会被一同移动到最新的版本
- 如吸收为了解决BUG写的临时分支 git merge login-bug
- 删除吸收后的分支印记:
- git branch -d 被吸收后的分支印记名
- 只删除分支印记,不删除分支版本,后续仍可通过分支版本名切换到该分支
- 如删除为了解决BUG写的临时分支印记名 git branch -d login-bug
- 切回到要吸收的分支上:
分支吸收:
分支吸收的简单定义:即将主分支与新编写部分的分支 通过merge吸收
个人理解将其理解为分支吸收,是从原主分支节点出来的新编写分支,被主分支完全吸收继承(有的人称为合并,但我不认同)
个人经验建议:
- 吸收了解决完bug的分支后,将bug分支版本名称改掉即可,留用下一次fix bug使用,让fix bug分支与master处于同一节点侯命待用
- 频繁反复的删除/创建分支,更容易造成混淆,风险更大
- 后续有需要,可通过id,回到该历史版本
实践案例- 切回主分支,将login-bug吸收merge到主分支,删除吸收后的分支印记,不删除分支
# 将HEAD编辑指针,切回主分支
MINGW64 /i/xxxxx (login-bug)
$ git checkout master
Switched to branch 'master'
# 将login-bug吸收merge到主分支
MINGW64 /i/xxxxx (master)
$ git merge login-bug
Updating 50ab3b8..7c36880
Fast-forward
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Nothing new to pack.
Checking connectivity: 13777, done.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
src/login/index.js | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
create mode 100644 src/login/index.js
# 删除被吸收后的分支印记
MINGW64 /i/xxxxx (master)
$ git branch -d login-bug
Deleted branch login-bug (was 7c36880).
# 删除后,查看当前的分支
$ git branch
content
* master
分支-合并与提交
合并提交:
背景:
- 在原主分支完成吸收,产生了新的提交记录后,再将从原主分支旧节点分出的其他分支,通过merge合并回去新的主分支时,触发合并提交
定义:
- 合并提交,会自动将标的被合并分支下,从旧节点往后所使用的多个快照记录,按顺序吸收合并,并产生一次新的提交版本
- 合并提交所产生的新版本,按提交次序,依次排列地包含了各分支的历史版本(从历史节点分出来至今的主分支及被合并分支,期间的历史版本)
- 产生一次新的提交版本,以作两个分支的共同继承
合并提交:
- 合并提交的简单定义:即将两个由同一个历史节点分出来的分支(主旁分支)通过merge合并,并产生一次新的提交版本,以作两个分支的共同继承
合并提交与吸收的区别:
- 吸收是:从原主分支节点出来的新编写分支,被主分支完全吸收继承,并将主分支印记,移到所吸收部分的、最新的版本
- 合并提交是:两个拥有共同历史节点的分支(一个主一个旁),在合并后按提交时间线次序,包含了各分支的历史版本,并产生一个新的版本,以作两个分支的共同继承
git merge 语法:
- 无论是采取吸收策略还是合并策略,都是使用 git merge 语法
- git merge 会比较两个分支的历史版本情况,决定是吸收性继承操作,还是合并性继承操作
- 吸收性继承:仅移动master标记到最新版本
- 合并性继承:产生一次新的提交版本,以作主旁两个分支的共同继承,并移动master标记到新的提交版本
- 注意:合并后是按各版本的历史提交时间线次序排列,而非合并的先后顺序
步骤:
- 切回到要合入的分支上:
- 通常是切回到主分支,以合入拥有共同历史版本的分支
- git checkout 分支印记名(主)
- 如这里回到修复bug后的主分支,以准备合入新功能分支: git checkout master
- 合并其他分支过来:
- git merge 旁系分支印记名(被合并)
- 如这里吸收一个功能分支:git merge content
- 删除合并后的分支:
git branch -d 分支印记名(历史旁系)
如这里删掉旁系分支印记名:content
个人经验建议:
- 完成合并提交后,可删除旁系分支名,以理清,该旁系功能已被合入主分支
- 但不要删除,后续有需要,可通过id,回到该旁系分支
- 先吸收bug fix分支,再去合并旁系功能分支
实践案例- 切回主分支,将content功能旁系分支,合并到修复bug后的主分支
# 将HEAD编辑指针,切回主分支,提示当前已在主分支
$ git checkout master
Already on 'master'
# 合入旁系分支content
$ git merge content
# 提示写入合并旁系的原因
Merge branch 'content'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
~
~
合并分支 'content'
# 请输入提交消息以解释为什么需要此合并,
# 特别是如果它将更新的上游合并到主题分支中。
#
# 以 '#' 开头的行将被忽略,空消息中止
# 提交。
~
~
.git/MERGE_MSG [unix] (16:52 16/11/2024)
# 写入“功能合并”,操作同vim编辑器
'function merge'
# 已有:,可直接输入,然后 wq + 回车,保存退出并继续运行合并策略
# 提示 Merge made by the 'ort' strategy 通过 ort 策略模式合并
$ git merge content
Merge made by the 'ort' strategy.
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Checking connectivity: 13780, done.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
src/content/index.css | 119 +++++++++++++++++++++++++++++++++++
src/content/index.js | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 289 insertions(+)
create mode 100644 src/content/index.css
create mode 100644 src/content/index.js
# 最终合并后产生的新的主分支,其历史版本,按提交次序排列
$ git log --oneline
95d62b3 (HEAD -> master) Merge branch 'content' 'function merge'
7c36880 5修复login-index
5fc69ec (content) 4内容管理页-逻辑
86f4a9b 3内容管理页-样式
50ab3b8 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
# 删除历史旁系分支印记
$ git branch -d content
Deleted branch content (was 5fc69ec).
# 主分支历史版本已不包含其他旁系分支印记
$ git log --oneline
95d62b3 (HEAD -> master) Merge branch 'content' 'function merge'
7c36880 5修复login-index
5fc69ec 4内容管理页-逻辑
86f4a9b 3内容管理页-样式
50ab3b8 2登录页目录-增加忽略文件配置
afd5eab 1登录页目录-删除逻辑
1bc0a97 1登录页目录1
e80482a 1登录页-逻辑
分支-合并冲突
- 合并冲突:
本质:
- 主旁分支/不同分支,均对某共有文件,作出了冲突性修改(如修改标的相同,同一个文件的同一部分),导致各自分支的继承状态不一样,产生逻辑冲突,导致合并冲突
- Git 无法干净的合并具有逻辑冲突的地方,不知道该采用哪个版本的逻辑,产生合并冲突
产生的背景:
- 需求1:基于 master 新建 publish 分支,完成发布文章业务,然后修改内容页面的 html 文件的 title 标签,并提交一次
- 需求2:切换到 master,也在修改内容页面的 html文件的 title 标签,并提交一次
- 冲突:把把需求1和需求2两个分支合并,触发冲突
解决:
- 打开 VSCode ,找到冲突文件中冲突的内容,并手动排查、解决
- 解决后需要提交一次记录
教程原带的建议:避免合并冲突要
- 项目团队开发协作上:与团队多交流
- 自己开发纪律上:
- 按页面划分不同分支开发
- 公共代码在统一文件夹维护
- 万一需要动到公共代码,需要积极沟通,手动合并;或者是组长/专人,在公共分支下,专程管理,各人反向同步公共分支的代码进行合并
- Node等软件版本统一,npm 包统一下载;要点就是保持package.json和package-lock.json两个文件的一致性
- 因此可以让组长/专人,在主分支下,预先下载公共使用的包,避免冲突,然后再让组员各自从主分支同步package.json和package-lock.json到各自的开发分支下,再去下载公共包
个人经验建议:
- 演示冲突之前应该先备份冲突标的
- 同理,发现出现冲突,不要着急切版本,先复制保存文件最重要
- 因为从次分支印记下的版本/继承自主分支之后的版本,通过 git checkout 命令切换回到主分支/后退回主分支,那些期间加入的文件不是恢复未被跟踪,而是会被删除!
- 显示合并过程中时,要到项目中仔细检查冲突的地方
- 在项目中解决完冲突后,要运行一下,确认没问题
- 然后再将处理完冲突后的文件,加到暂存区,提交版本库
实践案例- 分别编辑主旁分支,产生冲突触发,再排查解决
# 新建publish分支
MINGW64 /i/xxxxx (master)
$ git branch publish
# HEAD指针切换到publish分支
MINGW64 /i/xxxxx (master)
$ git checkout publish
Switched to branch 'publish'
# 放入src/publish/目录,并git add加到暂存区
MINGW64 /i/xxxxx (publish)
$ git add src/publish/
warning: in the working copy of 'src/publish/index.css', LF will be replaced by CRLF the next time Git touches it
warning: in the working copy of 'src/publish/index.js', LF will be replaced by CRLF the next time Git touches it
# 暂存区有新文件,但是还没通过提交版本清空暂存区,因此,在切换HEAD指针所在分支时,会提示暂存区有文件
# 如下方切换回主分支,提示有两个新加入暂存区跟踪A文件
MINGW64 /i/xxxxx (publish)
$ git checkout master
A src/publish/index.css
A src/publish/index.js
Switched to branch 'master'
# 再次切换回到发布publish分支
MINGW64 /i/xxxxx (master)
$ git checkout publish
A src/publish/index.css
A src/publish/index.js
Switched to branch 'publish'
# 将暂存区的文件提交版本,记录在发布publish分支,此在发布分支下的版本,版本名称命名为:6发布页分支提交
MINGW64 /i/xxxxx (publish)
$ git commit -m 6发布页分支提交
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
[publish dbbe94f] 6发布页分支提交
2 files changed, 314 insertions(+)
create mode 100644 src/publish/index.css
create mode 100644 src/publish/index.js
# 再次切换回到主分支,src/publish/目录被删除
# 因为从次分支印记下的版本/继承自主分支之后的版本,通过 git checkout 命令切换回到主分支/后退回主分支,那些期间加入的文件不是恢复未被跟踪,而是会被删除!
MINGW64 /i/xxxxx (publish)
$ git checkout master
Switched to branch 'master'
# 拷贝一份src/publish/,放入文件目录,修改文件内容,如修改src/publish/index.css内容,例如改个颜色,再加到暂存区
MINGW64 /i/xxxxx (master)
$ git add src/publish/
# 将修改后的目录,加到版本,7主分支冲突版本
MINGW64 /i/xxxxx (master)
$ git commit -m 7主分支冲突版本
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Checking connectivity: 13791, done.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
[master 49e52a0] 7主分支冲突版本
2 files changed, 315 insertions(+)
create mode 100644 src/publish/index.css
create mode 100644 src/publish/index.js
# 将与主分支带有冲突关系的旁系分支publish合并过来
$ git merge publish
Auto-merging src/publish/index.css
CONFLICT (add/add): Merge conflict in src/publish/index.css
Auto-merging src/publish/index.js
CONFLICT (add/add): Merge conflict in src/publish/index.js
Automatic merge failed; fix conflicts and then commit the result.
# 此时vscode会提示出冲突的地方,并标出冲突的地方所属,并提供选择
MINGW64 /i/xxxxx (master)
$ git merge publish
Auto-merging src/publish/index.css
CONFLICT (add/add): Merge conflict in src/publish/index.css
Auto-merging src/publish/index.js
CONFLICT (add/add): Merge conflict in src/publish/index.js
Automatic merge failed; fix conflicts and then commit the result.
采用当前更改|采用传入的更改|保留双方更改|比较变更
<<<<<<< HEAD
/* color: #409eff !important; */
color: red !important;
=======
color: #409eff !important;
>>>>>>> publish
# 此时指针显示为合并过程中,确认在项目中解决完冲突后,运行一下,确认没问题,加到暂存区
MINGW64 /i/xxxxx (master|MERGING)
$ git add src/publish/
# 提交版本库
MINGW64 /i/xxxxx (master|MERGING)
$ git commit -m 8主分支解决完冲突版本
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
[master 2feea5d] 8主分支解决完冲突版本,保留了publish
# 打印分支记录,确认合并后新建了版本,以继承了冲突修复后的状态
$ git log --oneline
2feea5d (HEAD -> master) 8主分支解决完冲突版本
49e52a0 7主分支冲突版本
dbbe94f (publish) 6发布页分支提交
95d62b3 Merge branch 'content' 'function merge'
7c36880 5修复login-index
# 完成具冲突的分支修复和合并后,可以删掉冲突分支印记
- 备注:
- 如选择保留双方更改,这种情况下,需要手动到发生冲突的地方编辑,写上注释,如果是2选1的,可以注释掉一种
- 如选择比较变更,vscode会拆分两个窗口,展示冲突的地方
- 选择“采用当前的更改”和“采用传入的更改”,会执行保留其中一份记录的策略
Git 常用命令
命令 | 作用 | 注意 |
---|---|---|
git -v | 查看 git 版本 | |
git init | 初始化 git 仓 | |
git add 文件标识 | 暂存某个文件 | 文件标识:以终端为起始的相对路径 |
git add . | 暂存所有文件 | |
git commit -m “说明注释” | 提交产生版本记录 | 每次提交,把暂存区内容快照一份 |
git status | 查看文件状态-详细信息 | |
git status -s | 查看文件状态-简略信息 | 第一列是暂存区状态,第二列是工作区状态 |
git ls-files | 查看暂存区文件列表 | |
git restore 文件标识 | 从暂存区恢复到工作区 | 如果文件标识为.则恢复所有文件 |
git rm --cached 文件标识 | 从暂存区移除文件 | 不让 git 跟踪文件变化 |
git log | 查看提交记录-详细信息 | |
git log --oneline | 查看提交记录-简略信息 | 版本号 分支指针 提交时说明注释 |
git reflog --oneline | 查看完整历史-简略消息 | 包括提交,切换,回退等所有记录 |
git reset 版本号 | 切换版本代码到暂存区和工作区 | --soft 模式保留暂存区和工作区原本内容 --hard 模式不保留暂存区和工作区原本内容 --mixed 模式不保留暂存区,工作区保留(默认) 先覆盖到暂存区,再用暂存区对比覆盖工作区 |
git branch 分支名 | 创建分支 | |
git branch | 查看本地分支 | |
git branch -d 分支名 | 删除分支 | 请确保记录已经合并到别的分支下,再删除分支 |
git checkout 分支名 | 切换分支 | 本质是改变HEAD编辑指针所在的分支 |
git checkout -b 分支名 | 创建并立刻切换分支 | 等同git branch和checkout |
git merge 分支名 | 把分支提交历史记录合并到当前所在分支 |
附:git stash 对当前现场进行存储
使用场景:当在某个分支上正在工作,突然有一个紧急的bug需要修复,此时可以使用 stash功能,将当前正在工作的现场存储起来,等bug修复之后,在返回继续工作。
操作顺序:
- 将当前的工作现场临时存储:
- git stash
- 切换到bug出现的分支上,比如bug出现在 master分支。如果bug就是在当前分支,可以操作此步骤
- git checkout master
- 新添加一个bug临时分支
- git checkout -b bug001
- 对代码进行修复。
- 切换回master分支
- git checkout master
- 合并bug分支到主master上
- git merge --no-ff -m '合并bug分支到master' bug001
- 删除bug001分支
- git branch -d bug001
- 回到之前的工作现场所在的分支
- git checkout dev
- 查看当前分支保存那些工作现场(之前封冻存储的工作现场)
- git stash list
- 恢复存储的现场
- git stash pop
小结: 修复bug时,通过创建新的bug分支进行修复,然后合并,最后删除。
当手头工作没有做完时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,恢复工作现场
Git 远程仓库
概念:把本地的项目版本库,托管/复制一份到因特网或其他网络中
作用:
- 在线保存一份本地的版本库的历史记录,如误删、异地编辑需要等,可以从网络托管的版本库中恢复
- 多人协作需要,把项目分发给多人
创建:
- 通过公司自己服务器,配合开源git项目/其他闭源git项目,创建在公司服务器的版本库
- 通过第三方托管平台
- Gitee(国内),
- GitHub(由微软运营),
- Gitea(开源的自建 Git 服务,包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD)
- GitLab(乌克兰程序员DmitriyZaporozhets和ValerySizov开发,它使用Ruby语言写成。后来,一些部分用Go语言重写)
- 等等...
- 远程仓库地址格式:一般为:协议+平台+你在平台上的注册账户名+具体项目名称.git
需求:创建远程版本库,并把本地 Git 仓库推送上去保存
步骤:
- 注册第三方托管平台网站账号
- 在托管平台上,新建仓库,得到远程仓库 Git 地址(以.git结尾的网址)
- 在本地 Git 仓库中,添加远程仓库原点地址,即绑定远程仓库名字和地址,后续通过远程仓库别名来建立推送关系
- 命令:git remote add 远程仓库别名 远程仓库地址
- 例如:git remote add origin https://gitee.com/lidongxu/work.git
- 远程仓库地址格式:一般为:协议+平台+你在平台上的注册账户名+具体项目名称.git
- 本地 Git 仓库推送版本记录到远程仓库
- 命令:git push -u 远程仓库别名origin 本地和远程分支名master
- 例如:git push -u origin master
- 完整写法:git push --set-upstream origin master:master
- 简写:如果已经通过 -u 推送过,建立过连接,可以简写为 git push
- 命令意思:
- -u 相当于--set-upstream,意为本地的某个分支与远程分支建立通道,后续在master分支下可以直接输入git push
- master是两边名字一致时简写成一个,实际上是 本地分支名:远程分支名,如master:master
- 显示远程仓库的名称和URL
- 命令:git remote -v
- 显示 (fetch) 的是:正在编辑的本地的项目,从远程仓库对应的拉取地址
- 显示 (push) 的是:正在编辑的本地的项目,提交到远程仓库对应的推送地址
- 修改远程仓库地址
- 命令:git remote set-url origin URL
- 如项目在本地 Git 仓库,曾添加过远程仓库原点地址,不能再次添加,会报错,此时可通过此命令实现修改
- 删除现有远程仓库
- 命令:git remote rm origin
- 删除完以后,添加新远程仓库:git remote add origin url
实践案例- 把本地的项目版本库,推送一份到远程仓库平台
# 检查当前本地电脑的Git的全局配置,同vim编辑器操作
MINGW64 /i/xxxxx (master)
$ git config --global --edit
# 更改本地电脑的Git用户名配置,以与远程仓库一致
MINGW64 /i/xxxxx (master)
$ git config --global user.name "你在远程仓库平台注册的用户名"
# 更改本地电脑的Git用户邮箱配置,以与远程仓库一致
MINGW64 /i/xxxxx (master)
$ git config --global user.email "你在远程仓库平台注册的邮箱名称"
# 再次检查当前本地电脑的Git的全局配置,同vim编辑器操作
MINGW64 /i/xxxxx (master)
$ git config --global --edit
# 在本地 Git 仓库添加远程仓库原点地址,绑定远程仓库名字和地址,后续通过远程仓库别名来建立推送关系
MINGW64 /i/xxxxx (master)
$ git remote add '你在远程仓库平台上建立的仓库名字origin' 'https://gitee.com/你在远程仓库平台上建立的仓库地址.git'
# 首次推送版本记录到远程仓库/切换推送平台推送,会提示远程仓库登录框授权
MINGW64 /i/xxxxx (master)
$ git push -u '你在远程仓库平台上建立的仓库名字' '本地和远程分支名,如:master'
Enumerating objects: 55, done.
Counting objects: 100% (55/55), done.
Delta compression using up to 12 threads
Compressing objects: 100% (47/47), done.
Writing objects: 100% (55/55), 99.36 KiB | 16.56 MiB/s, done.
Total 55 (delta 11), reused 44 (delta 0), pack-reused 0 (from 0)
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag 6d4e42b7
To https://gitee.com/你在远程仓库平台上建立的仓库地址.git
* [new branch] master -> master
branch 'master' set up to track '你在远程仓库平台上建立的仓库名字/本地和远程分支名master'.
# 切换远程仓库平台
$ git config --global user.name "你在远程仓库平台注册的用户名2"
$ git config --global user.email "你在远程仓库平台注册的邮箱名称2"
# 如项目在本地 Git 仓库,曾添加过远程仓库原点地址,不能再次添加,会显示报错
MINGW64 /i/xxxxx (master)
$ git remote add '你在远程仓库平台上建立的仓库名字origin' 'https://gitee.com/你在远程仓库平台上建立的仓库地址.git'
error: remote origin already exists.
# 如项目在本地 Git 仓库,曾添加过远程仓库原点地址,则需要修改,修改远程仓库地址格式 git remote set-url origin URL
MINGW64 /i/xxxxx (master)
$ git remote set-url '你在远程仓库平台上建立的仓库名字origin' 'https://gitee.com/你在远程仓库平台上建立的仓库地址.git'
# 推送版本记录到远程仓库2
MINGW64 /i/xxxxx (master)
$ git push -u '你在远程仓库平台上建立的仓库名字' '本地和远程分支名,如:master'
# 查看远程仓库的名称和URL
$ git remote -v
StudyAjax https://github.com/xxxxx.git (fetch)
StudyAjax https://github.com/xxxxx.git (push)
origin https://github.com/xxxxx.git (fetch)
origin https://github.com/xxxxx.git (push)
# 删除现有远程仓库
$ git remote rm '要删除的远程仓库名字,如origin'
# 再次查看远程仓库的名称和URL
$ git remote -v
StudyAjax https://github.com/xxxxx.git (fetch)
StudyAjax https://github.com/xxxxx.git (push)
Quick setup — if you’ve done this kind of thing before
http https://github.com/xxxxxx/xxxxxx.git
ssh git@github.com:xxxxxx/xxxxxx.git
使用方式:
- 如使用不同的方式,改为相应的协议+地址
- 使用https协议,需要有对应平台的账密实现登录后,才能推送,.git结尾无法直接访问,可以用git clone命令拉取
- 使用ssh协议,免帐号密码连接,但是建立连接时需要配置对应公钥才能使用
git hub 官方推荐的推送新建仓库步骤create a new repository on the command line
echo "# StudyAjax" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/xxxxxx/xxxxxx.git
git push -u origin main
git hub 官方推荐的推送已存在仓库步骤push an existing repository from the command line
git remote add origin https://github.com/xxxxxx/xxxxxx.git
git branch -M main
git push -u origin main
远程版本库的注意:
- 第一次使用/切换平台帐号,需要输入gitee/github的账号密码,会自动弹出Git平台账密输入框
- 选择开源的话,大家都可以下载
- 如果当前电脑,需要访问同一个平台下但是是不同账号的仓库,可以到 控制面板\用户帐户\凭据管理器 中,在Windows凭据中,编辑修改/删除旧的凭据
- 上传完了以后,可以选择许可证,补充readme.md文档
切换远程仓库平台:
- 需要先更改本地电脑的Git配置,以与远程仓库一致
- 因为是通过远程仓库别名和url来建立推送关系,因此需要先修改远程仓库名字所绑定的地址
- 如项目在本地 Git 仓库,曾添加过远程仓库原点地址,则需要修改,修改远程仓库地址格式 git remote set-url origin URL,即 git remote set-url 远程仓库项目名 远程仓库地址
- 推送时,更改远程仓库的名称、地址
- 远程版本库的作用?
- 保存提交历史记录,多人共享
- 远程版本库使用步骤?
- 创建远程版本库(自己服务器/第三方托管平台)
- 本地版本库设置远程地址
- 推送本地版本库到远程
- 推送的命令?
- git push -u origin master
- 已经通过 -u 推送过,建立过连接,可以简写为:git push
Git 远程仓库-克隆
克隆:拷贝一个远程的 Git 仓库,到当前电脑本地,进行使用
- 命令:git clone 远程仓库地址
- 例如:git clone https://gitee.com/lidongxu/work.git
效果:在运行命令所在文件夹,生成 work项目文件夹(包含版本库,并映射到暂存区和工作区)
- 克隆下来的版本,包括最后一次提交的版本记录,并映射代码到工作区和暂存区
- 通过 git clone 克隆到本地的仓库,已经建立好和远程仓库的链接,后续推送到平台,不需要git remote add origin url,只需要git pull
- 仓库公开随意克隆git clone,推送需要身为仓库团队成员git push
流程:使用终端操作,打开准备好的文件夹,作为存放项目的目录(项目文件夹的上一层),运行克隆命令,再通过cd,进入项目目录
- 步骤:
- 终端操作方式1:可以在路径地址栏,输入cmd,回车,在当前目录下打开window自带终端cmd,
- 终端操作方式2:也可以类似poweshell,在当前目录下,右键选择使用git bash;注:poweshell则需要shift + 右键
- 运行克隆命令:git clone 远程仓库地址,回车,没有报错则完成克隆
- 进入项目目录:cd 目录名字,进入文件夹(仓库文件夹,文件夹下含.git文件),进入文件夹后可以 git log --oneline查看历史提交记录
- 备注:cd 它是 change directory 单词的一个缩写,意为改变文件夹,这个命令可以切换工作目录
- 开发新需求步骤逻辑:先将项目clone下来到本地,创建新分支来开发需求,开发完成后,工作区同步到暂存区再合并到master主分支本地版本库,再git push推送到远程
- 步骤:
多人协同开发
需求:小传新代码共享给小智
步骤:
- 小传 开发代码 ->工作区 ->暂存区 ->提交 ->拉取(可选)->推送
- 小智 ->拉取(后续也可以开发代码 ->...(流程同上) ->推送)
注意:
- 如果git push提交的时候,遇到他人提交在前,当前推送标的版本,并非提交到之前继承/拉到本地的版本的话,那么需要先拉取新版本,进行合并同步,否则直接提交可能会导致他人的代码被冲掉
- git发现当前推送标的版本有更新的话,会自动做拦截,告知远程仓库有最新代码
- 先拉取远程仓库的最新代码到本地合并同步,然后再提交
从版本仓库平台上,将项目的最新版本内容,同步到电脑本地:
- 命令:
- git pull origin master
- 此复合写法,相当于执行了两条等价于以下的命令
- 也等价于命令:
- git fetch origin master:master(fetch获取远程仓库origin中的远程分支记录master,到本地:的master分支下,未合并)
- git merge origin/master(merge把远程分支记录合并到所在本地master分支下)
- 区别:
- 新拉取,从无到有:
- 使用 git clone 仓库url地址
- 已拉取,同步仓库平台上的新版本到本地:
- 使用 git pull 远程仓库别名origin 本地和远程分支名master
- 新拉取,从无到有:
- 命令:
实践案例- 多人协同开发
# A电脑,推送最新版本到远程仓库
$ git push
Everything up-to-date
# B电脑,之前已经git clone克隆过,现在拉取最新的版本到本地
$ git pull '你在远程仓库平台上建立的仓库名字' '本地和远程分支名,如:master'
From https://github.com/xxxxx
* branch master -> FETCH_HEAD
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Nothing new to pack.
Checking connectivity: 13797, done.
warning: There are too many unreachable loose objects; run 'git prune' to remove them.
Already up to date.
VScode 中使用 Git 功能
- 在VScode 中使用 Git 功能来管理源代码版本:
- 优点:图形化工具管理,逻辑清晰
- 入口:VScode左侧栏源代码管理图标
- 包括:源代码管理,可以实现暂存,撤销,对比差异,提交等操作
- 源代码管理:
- 每次更改代码时,工具栏的源代码管理图标,右下角出现数字记录,显示多少个文件发生了变化
- 对比差异:
- 点到源代码管理,会列出变化的文件,点进去变化的文件,会分栏展示修改处的对比
- 暂存与撤销更改:
- 可以选择点击文件列表后面的 回退图标,放弃更改(使用暂存区内容覆盖工作区)
- 放弃后,工作区内容被暂存区内容所覆盖,数字记录消失
- 如果是执行修改,那么就ctrl+s保存文件,再git add .加到暂存区
- 也可以通过点击文件列表后面的 + 图标,放到暂存区,取代敲 git add 命令,文件状态显示为M已修改/有变更
- 提交记录:
- 再通过 git commit -m '本次版本注释说明',完成提交历史记录后,右下角的数字记录才会消失
- 也可以通过输入框,输入本次版本注释说明,然后点击 提交 图标来提交,取代 git commit -m 命令
- 可以通过敲命令git log --oneline,来查看本地版本记录确认
- 同步到远程:
- 可以点击 同步更改 按钮,同步提交到远程仓库,代替git push命令
- 点击源代码管理的右上角,更多操作:
- 实际上是git命令对应的图形化操作,与敲命令等价作用
- 图形化操作会弹出提示框,提示框中描述了操作逻辑,与对应的敲命令操作逻辑一致
- 例如:点击 推送 按钮,本质上是在项目中,先执行的pull拉取同步,再执行push推送远程仓库
- 源代码管理:
案例-发布黑马头条数据管理平台
需求:把 Webpack 压缩好的 dist 分发文件夹网页,部署到码云上,开启 Page 服务在互联网中浏览(不含后端后台,单纯部署前端网页)
步骤:
- 初始化本地 Git 仓库(这次是非空文件夹-配套素材 dist 文件夹)
- 初始化远程 Git 仓库(这一次也是非空的)
- 本地配置远程仓库链接
- 本地拉取合并一下(确认本地要包含远程内容时才使用)
- 本地推送到远程 Git 仓库
- 开启 page 网页服务得到地址浏览
将打包后的分发文件夹目录(静态页面),上传到支持 Page 服务的平台,注意点包括:
- 本地push上传前需要pull
- 拒绝合并“不想关”的历史记录(当前,本地仓库和远程仓库的分支没有任何关系)
- 两个没有关联文件/没有共有文件的项目,可通过 git pull --rebase '远程仓库名字' '本地分支名字master',拉取远程的仓库到本地项目上,强制进行合并
- git log --oneline 查看合并效果
- 再push到远程仓库,git push '远程仓库名字' '本地分支名字master'
- 开启page服务,在服务中下拉,选择需要的服务,类似部署SaaS(因为仅支持公开仓库开通,管理->基本信息->开源->勾选)
- 部署的目录:使用'/'根路径(可以访问整个仓库的内容)
- 实际上是平台方给个人开通的二级域名地址,访问的资源路径是仓库名字
Git 远程仓库常用命令
命令 | 作用 | 注意 |
---|---|---|
git remote add 远程仓库别名 远程仓库地址 | 添加远程仓库地址 | 别名唯一,地址是.git 结尾的网址 |
git remote -v | 查看远程仓库的名字及地址 | |
git remote remove 远程仓库别名 | 删除远程仓库地址 | |
git pull 远程仓库别名 分支名 | 拉取 | 完整写法:qit pull 远程仓库别名 远程分支名:本地分支名 等价于本地的:git fetch 和 git merge |
git push 远程仓库别名 分支名 | 推送 | 完整写法:git push 远程仓库别名 本地分支名:远程分支名 -u:建立通道后以后可以简写 git push |
git pull --rebase 远程仓库别名 分支名 | 拉取合并 | 合并没有关系的记录 |
git clone 远程仓库地址 | 克隆 | 从0得到一个远程的Git仓库到本地使用 |
Git 的其他操作(来自GPT)
要在 Git 中重命名默认分支并将默认推送分支更改为重命名的分支,请执行以下步骤:
重命名 default 分支:git branch -m master main 此命令会将分支'master'重命名为'main'
设置默认推送分支:git config --global push.default main 此命令会将默认推送分支设置为 'main'
将更改推送到远程仓库:git push origin main 此命令会将更改推送到远程存储库上的分支'main'
就是这样!现在,您已在 Git 中重命名了默认分支,并将默认推送分支更改为重命名的分支。
注意:如果你有任何现有的远程仍然指向旧的默认分支名称,你需要更新它们的默认指向,将默认指向改为新的默认分支名
您可以使用以下命令执行此操作: git remote set-url origin https://github.com/username/repo.git main
将 origin 替换为要更新的远程仓库的名称,将 https://github.com/username/repo.git 替换为远程仓库的 URL。