banner
banner
banner
NEWS LETTER

Git知识

Scroll down

版本控制

  • 集中式(svn)

    • svn 因为每次存的都是差异,需要的硬盘空间会相对的小一点,但回滚的速度会很慢
    • 优点: 代码存放在单一的服务器上 便于项目的管理
    • 缺点: 服务器宕机,数据就存在丢失的风险
  • 分布式(git)

    • git 每次存的都是项目的完整快照,需要的硬盘空间会相对大一点
      (Git 团队对代码做了极致的压缩,最终需要的实际空间比 svn 多一点,但回滚速度极快)
    • 优点: 完全的分布式
    • 缺点: 学习起来比 SVN 陡峭

底层命令

  • git 对象

    • 生成一个 hash 值:压缩后的文件内容的键值对存到.git/objects:git hash-object -w fileUrl
  • tree 对象

    • 往暂存区添加一条记录(让 git 对象对应上文件名)存到.git/index:git update-index –add –cacheinfo 100644 hash test.txt
    • 生成树对象存到.git/objects: git write-tree
  • commit 对象

    • 生成一个提交对象存到.git/objects: echo ‘first commit’ | git commit-tree treehash

初始化配置和文件的 UDR 命令

  • 初始化配置

    • 配置用户名:git config –global user.name “name”
    • 配置邮箱:git config –global user.email name@example.com
    • 获取设置配置列表:git config –list
    • 初始化仓库: git init
  • U(修改提交操作)

    • 将单个文件从工作区添加到暂存区: git add <file>
    • 将所有文件添加到暂存区: git add .
    • 将暂存区的文件提交到本地仓库: git commit -m "msg"
  • D(删除 & 重命名)

    • 删除:git rm 要删除的文件
    • 重命名:git mv 老文件名 新文件民
  • R(查询操作)

    • 查看工作目录中文件的状态: git status(已跟踪(已提交 已暂存 已修改) 未跟踪)
    • 查看未暂存的修改,比较文件不同,即暂存区和工作区的差异: git diff
    • 查看未提交的暂存: git diff --cache
    • 查看提交记录: git log --oneline

分支

分支的本质其实就是一个提交对象!!!

  • HEAD:

    • 一个指针,它默认指向 master 分支,切换分支时其实就是让 HEAD 指向不同的分支
    • 每次有新的提交时 HEAD 都会带着当前指向的分支,一起往前移动
  • git 分支命令

    • 查看整个项目的分支图: git log [--oneline | --decorate | --graph | --all]
  • 查看分支

    • 查看分支列表: git branch
    • 查看所有分支: git branch -a
    • 查看分支指向的最新的提交: git branch -v
    • 查看合并到当前分支的分支列表: git branch --merged(一旦出现在这个列表中就应该考虑删除已合并的分支)
    • 查看没有合并到当前分支的分支列表: git branch --no-merged(一旦出现在这个列表中就应该观察一下是否需要合并)
  • 创建分支

    • ⭐ 创建分支: git branch <name>
    • 在指定的提交对象上创建新的分支: git branch <name> commithash — 版本穿梭(时光机)
  • 删除分支

    • ⭐ 删除本地分支: git branch -d <name>
    • 强制删除分支: git branch -D <name>
    • ⭐ 删除远程分支: git push origin -d <name>
  • 切换分支

    • ⭐ 切换分支: git checkout <name>
    • 创建并切换到新分支: git checkout -b <name>
  • 合并分支

    • 合并某个分支到当前分支,默认 fast forward: git merge <name>
      • 快进合并 –> 不会产生冲突
      • 典型合并 –> 有机会产生冲突
      • 解决冲突 –> 打开冲突的文件 进行修改 add commit
  • git 分支的注意点

    • 在切换的时候 一定要保证当前分支是干净的!!!
    • 允许切换分支:
      • 分支上所有的内容处于已提交状态
      • (避免)分支上的内容是初始化创建 处于未跟踪状态
      • (避免)分支上的内容是初始化创建 第一次处于已暂存状态
    • 不允许切分支:
      • 分支上所有的内容处于已修改状态或第二次以后的已暂存状态
    • 在分支上的工作做到一半时 如果有切换分支的需求, 我们应该将现有的工作贮藏起来
  • 贮藏

    • ⭐ 将当前工作区改过的文件贮藏到栈中,贮藏后当前库是上一个已提交的状态: git stash
    • ⭐ 查看当前贮藏列表的文件:git stash list
    • 将栈顶的工作内容恢复,但不让任何内容出栈:git stash apply <name>
    • 取出栈顶的工作内容后就应该将其删除(出栈): git stash drop
    • ⭐ 恢复贮藏起来的文件并把列表中对应文件删除,是 apply+drop 操作:git stash pop <name>

撤销与回退操作(后悔药)

撤销:当修改了工作区/暂存区的文件,想要撤销之前的操作

  • 场景 1:(撤销工作目录的修改)当改乱了工作区某个文件的内容,但还未 add 到暂存区

    • 撤销指定文件的修改:git checkout -- 文件名(-- 表示是文件名不是分支名,不混淆可不用)
    • 撤销所有工作区的修改:git checkout .
    • 撤销工作区和暂存区的所有修改:git checkout -f
  • 场景 2:(撤销暂存区的修改)当乱改了工作区某个文件的内容,并且 git add 到了暂存区

    • 第 1 步,将暂存区的文件修改撤销掉:git reset HEAD <file>
    • 第 2 步,将工作区的文件修改撤销掉:git checkout <file>
  • 场景 3:乱改了很多文件,想回到最新一次提交时的状态

    • 撤销工作区中所有未提交文件的修改内容:git reset --hard HEAD
  • 场景 4:(撤销提交)在当前最后一次提交的 commit 信息,还没有 push 到远程

    • git commit --amend

回退:当已经进行了 commit 操作,需要回退到之前的版本:

  • 查看每一步操作的记录: git reflog (谨慎!!!每次改变都会记录)
  • 设置为某一 id 的记录: git reset id
  • 设置为对应 id 记录: git reset --hard id
  • 回退到上次提交的状态: git reset --hard HEAD^
  • 回退到 n 个版本前的状态: git reset --hard HEAD~n
  • 回退到某一个 commitid 的状态及内容,只改变 HEAD:git reset --soft HEAD commitid
  • 回退到某一个 commitid 的状态,并保留工作区的内容:git reset --mixed(默认) HEAD commitid
  • 回退到某一个 commitid 的状态及内容,并重置暂存区和工作目录:git reset --hard HEAD commitid

checkout 深入

  • git checkout brancname 跟 git reset –hard commithash 特别像

共同点

  • 都需要重置 HEAD 暂存区 工作目录

区别

  • checkout 对工作目录是安全的 reset –hard 是强制覆盖
  • checkout 动 HEAD 时不会带着分支走而是切换分支
  • reset –hard 时是带着分支走

checkout + 路径

  • git checkout commithash filename
    • 重置暂存区
    • 重置工作目录
  • git checkout – filename
    • 重置工作目录

远程协作

基本流程

  1. 项目经理初始化远程仓库

    • 一定要初始化一个空的仓库; 在 github 上操作
  2. 项目经理创建本地仓库

    • git remote 别名 仓库地址(https)
    • git init 将源码复制进来
    • 修改用户名 修改邮箱
    • git add
    • git commit
  3. 项目经理推送本地仓库到远程仓库

    • 清理 windows 凭据
    • git push 别名 分支 (输入用户名密码;推完之后会附带生成远程跟踪分支)
  4. 项目邀请成员 & 成员接受邀请

    • 在 github 上操作
  5. 成员克隆远程仓库

    • git clone 仓库地址 (在本地生成.git 文件 默认为远程仓库配了别名 orgin)
    • 只有在克隆的时候 本地分支 master 和 远程跟踪分支别名/master 是有同步关系的
  6. 成员做出贡献

    • 修改源码文件
    • git add .
    • git commit
    • git push 别名 分支 (输入用户名 密码;推完之后会附带生成远程跟踪分支)
  7. 项目经理更新修改

    • git fetch 别名 (将修改同步到远程跟踪分支上)
    • git merge 远程跟踪分支

做远程跟踪

  • 克隆仓库时会自动为 master 做跟踪
  • 本地没有分支: git checkout --track remote/分支名
  • 本地已经创建了分支: git branch -u remote/分支名

远程操作

  • 刷新远程分支信息: git fetch
  • 将本地 master 分支推送到远程对应分支: git push origin master
  • 下载远程代码并合并: git pull
  • 拉取远程最新代码并合并,不会产生 Merge: git pull --rebase
  • 推送本地代码到远程分支上: git push
  • 将远程仓库和本地仓库关联起来: git remote add origin <url>
  • 查看远程库信息: git remote -v

rebase 和 merge

  • rebase: 把分叉的提交历史“整理”成一条直线,看上去更直观

    • 变基:git rebase
    • 将当前分支移植到指定分支或者 commit 之上:git rebase -i <commit>
    • 从远程回退到未提交状态:git reset HEAD^
  • merge: 每次操作都会产生一条 merge 记录,从日志上看的,会产生分叉,日志看起来杂乱

git 修改默认 pull 的参数

  • git pull = git fetch + git merge
  • 全局修改 pull 的命令: git config --global --add pull.rebase true
  • 查看命令是否修改成功:git config --global -l
  • 如果之前向全局配置文件修改过 pull 的配置项,但修改错了,使用--unset
  • 使用–unset 后,发现提示有多个值,则使用--replace-all
    • 示例: git config –global –replace-all pull.rebase true

修改全局配置项

  • 新增一个配置项:--add

    • 格式:git config --local/--global/--system --add section.key value
    • 示例: git config –global –add pull.rebase true
  • 获取一个配置项:--get

    • 格式:git config --local/--global/--system --get section.key
  • 删除一个配置项:--unset

    • 格式:git config --local/--global/--system --unset section.key
    • 示例:git config –global –unset pull.rebase
  • 查看配置文件:--list/-l

    • 查看仓库级的 config:git config --local -l
    • 查看全局级的 config:git config --global -l
    • 查看系统级的 config:git config --system -l
    • 查看当前生效的配置:git config -l
  • 编辑配置文件:--edit/-e

    • 编辑仓库级的 config: git config --local -e
    • 编辑全局级的 config:git config --global -e
    • 编辑系统级的 config:git config --system -e

基本概念

  • 本地仓库:本地仓库上存放所有相关的文件,具体可分为工作区、暂存区和仓库区,工作区即项目文件夹下不包含.git 文件夹的所有文件,暂存区和仓库区则在.git文件夹下
  • 工作区:即我们工作的文件夹,在里面进行文件的增删改操作
  • 暂存区:临时保存工作区上的改动,通过git add操作将工作区的修改同步到暂存区
  • 仓库区:当执行git commit操作时,将暂存区上的所有变动同步到本地仓库
  • 远程仓库:GitHub/GitLab 上保存的仓库,通过 git push 将本地仓库同步到远程仓库,也可以通过 git fetch/pull 将远程仓库同步到本地仓库
  • 快照:git 将顶级目录中的文件和文件夹称作集合,并通过一系列快照来管理历史记录。在 git 的术语中,文件被称为blob对象(数据对象),也就是一组数据。目录则被称为tree(树)>,目录可以包含文件和子目录。快照统称“commit”>,每个快照都有一系列的父辈。每次commit都是创建一个全新的记录
  • master 引用通常会指向主分支最新一次 commit.在 Git 中,当前的位置有一个特殊的索引,它就是“HEAD”

checkout 可以用于切换分支,可以从历史提交或暂存区中拷贝文件到工作目录

  • 当给定某个文件名时,git 会从指定的提交中拷贝文件到暂存区域和工作目录。

HEAD 标识处于分离状态的提交操作

  • 可以正常提交,但不会更新任何命名分支,一旦切换到别的分支,这个提交节点再也不会被引用就会被丢弃
  • 如果想保存这个状态,可以用 git checkout -b name 来创建一个新的分支

Reset

  • 也用来从仓库中复制文件到索引,而不动工作目录
  • 如果不给选项,那么当前分支指向到那个提交。如果用–hard 选项,那么工作目录也更新,如果用–soft 选项,都不变
  • 如果没有给出提交点的版本号,那么默认用 HEAD。分支执行不变,但是索引会回滚到最后一次提交。如果用–hard 选项,工作目录也同样

Merge

  • merge 命令把不同分支合并起来。合并前,索引必须和当前提交相同。
  • cherry-pick 复制一个提交节点并在当前分支做一次完全一样的新提交

Rebase

  • 合并分支。本质上,是线性化的自动的 cherry-pick

工作原理

git工作原理图

1
2
3
4
5
6
7
graph TB
工作区==git add files==>暂存区/索引
暂存区/索引==git checkout -- files==>工作区
暂存区/索引==git commit==>仓库区
仓库区==git reset -- files==>暂存区/索引
仓库区==git checkout HEAD -- files==>工作区
工作区==git commit files==>仓库区
  • 工作区 –> 暂存区 –> 仓库区 –> 就走完本地仓库 –> 推送到远程仓库

  • .git

.git目录结构

  • 查看每个 SHA-1 的类型: git cat-file -t
  • 查看每个对象的内容和简单的数据结构: git cat-file -p
  • 把当前文件放入暂存区: git add files
  • 把暂存区生成快照并提交本地仓库: git commit
  • ⭐ 用来撤销暂存区的某一文件, git reset 撤销所有暂存区的文件: git reset -- files
  • 把文件从暂存区复制到仓库区,用来丢弃本地修改: git checkout -- files
  • 回滚到复制最后一次提交: git checkout HEAD -- files
  • 相当于运行 git add 把工作区的所有文件加入暂存区再提交到仓库区: git commit -a
  • 进行最后一次提交+工作目录中文件快照的提交,并且文件被添加到暂存区:git commit files
  • 比较两次提交记录的差异:git diff commitId commitId
  • 比较跟远程分支的差异: git diff HEAD
  • 比较跟暂存区的记录的差异: git diff
  • 比较跟某一分支记录的差异: git diff 分支名
  • 使用与当前提交相同的父节点进行一次新提交,旧的提交会被取消: git commit --amend

点击跳转,去了解更多 git 底层原理

其他文章
cover
Git在项目中遇到的问题(实战)
  • 24/10/30
  • 14:28
  • 前端工程化工具
目录导航 置顶
  1. 1. 版本控制
    1. 1.1. 集中式(svn)
    2. 1.2. 分布式(git)
  2. 2. 底层命令
    1. 2.1. git 对象
    2. 2.2. tree 对象
    3. 2.3. commit 对象
  3. 3. 初始化配置和文件的 UDR 命令
    1. 3.1. 初始化配置
    2. 3.2. U(修改提交操作)
    3. 3.3. D(删除 & 重命名)
    4. 3.4. R(查询操作)
  4. 4. 分支
    1. 4.1. git 分支命令
    2. 4.2. 查看分支
    3. 4.3. 创建分支
    4. 4.4. 删除分支
    5. 4.5. 切换分支
    6. 4.6. 合并分支
    7. 4.7. git 分支的注意点
    8. 4.8. 贮藏
  5. 5. 撤销与回退操作(后悔药)
    1. 5.1. 撤销:当修改了工作区/暂存区的文件,想要撤销之前的操作
    2. 5.2. 回退:当已经进行了 commit 操作,需要回退到之前的版本:
  6. 6. checkout 深入
    1. 6.1. 共同点
    2. 6.2. 区别
    3. 6.3. checkout + 路径
  7. 7. 远程协作
    1. 7.1. 基本流程
    2. 7.2. 做远程跟踪
    3. 7.3. 远程操作
  8. 8. rebase 和 merge
    1. 8.1. rebase: 把分叉的提交历史“整理”成一条直线,看上去更直观
    2. 8.2. merge: 每次操作都会产生一条 merge 记录,从日志上看的,会产生分叉,日志看起来杂乱
  9. 9. git 修改默认 pull 的参数
  10. 10. 修改全局配置项
    1. 10.1. 新增一个配置项:--add
    2. 10.2. 获取一个配置项:--get
    3. 10.3. 删除一个配置项:--unset
    4. 10.4. 查看配置文件:--list/-l
    5. 10.5. 编辑配置文件:--edit/-e
  11. 11. 基本概念
    1. 11.1. checkout 可以用于切换分支,可以从历史提交或暂存区中拷贝文件到工作目录
    2. 11.2. HEAD 标识处于分离状态的提交操作
    3. 11.3. Reset
    4. 11.4. Merge
    5. 11.5. Rebase
  12. 12. 工作原理
    1. 12.1. 工作区 –> 暂存区 –> 仓库区 –> 就走完本地仓库 –> 推送到远程仓库
请输入关键词进行搜索