读书笔记之【Git权威指南】

目录资源

  1. .git文件夹

    • .git/refs
      保存引用的命名空间列表

    • .git/refs/heads
      该目录下的引用称为分支,heads下的文件名就对应分支名,分支名里面存放着最新的commit-id
      refs/heads/master - master分支

    • .git/index
      包含文件索引的目录树,记录文件名和状态信息(时间戳和文件长度等)
      文件索引建立了文件和对象库中对象实体之间的对应
      通过比较时间戳,文件长度等信息判断文件是否更改

    • .git/objects
      git对象库, 保存文件的内容

概念

  1. 分区

    • 工作区
      代码编辑的地方

    • 版本库
      包含引用命名空间,暂存区,对象库

      • 暂存区(indexstage
        介于工作区和版本库的中间状态
      • 对象库
        保存文件的内容
  2. ID

    • commit-id 提交id
      生成算法: ( printf "commit 提交信息的字符数\000"; git cat-file commit HEAD ) | sha1sum

    • parent-id 父提交id

    • tree-id 目录树id
      提交对应的目录树id

    • 查看id对应的对象
      git cat-file -p hash-id

    • 查看引用对应的提交id
      git rev-prase HEAD
      git rev-prase master
      git rev-prase refs/heads/master
      指向的都已同一个commit-id

    • 父提交id
      HEAD^
      HEAD~5 = HEAD^^^^^
      commit-id^{tree} 父提交的树对象
      commit-id:path/to/file 某次提交对应的文件对象

  3. 引用
    git cat-file -t <ref-name> 查看引用的类型

  4. 目录树
    git ls-tree -l HEAD
    显示HEAD的目录树
    git ls-files -s
    显示暂存区目录树

  5. 命令 git

    • add
      1. git add -A : 对删除的文件执行git rm, 对新增和修改的文件执行git add
      2. git add -u : 对删除的文件执行git rm, 对修改的文件执行git add
    • branch
      1. 查看
        • -v/-vv: 显示当前分支名 远程分支名(2个v), 最新的一条提交记录
      2. 创建
        • <br-name>: 创建本地分支
        • <br-name> <commit-id>: 以commit-idHEAD,创建本地分支
        • git push <远程库> <本地分支名>: 创建远程分支
      3. 删除
        • git branch -d <br-name>: 检查分支是否已经合并到其他分支,否则拒绝删除
        • git branch -D <br-name>: 强制删除
      4. 重命名
        • git branch -m <old-br> <new-br>: 检查名为new-br的分支是否已经存在,存在就拒绝重命名
        • git branch -M <old-br> <new-br>: 强制重命名
    • checkout
      1. 无参数
        汇总显示工作区,暂存区与HEAD的差异
      2. <file-path>
        用暂存区文件覆盖工作区文件
      3. <commit-id>
        用指定提交覆盖工作区和暂存区, 会进入头指针分离状态
      4. <commit-id> <file-path>
        用指定提交中的文件覆盖暂存区和工作区中对应的文件
      5. <ref-name> -- <file-path>
        同上,eg. git checkout HEAD^1 -- path/to/file
      6. <br-name>
        切换分支
      7. <br-name> -- <file-path>
        用指定分支中的文件替换暂存区和工作区对应的文件
      8. .
        用暂存区所有文覆盖工作区本地文件,本地新增的文件不会丢失
    • cherry-pick
      从众多提交中挑选一个提交应用在当前分支, 应用后源提交的SHA1会发生变化
    • commit
      1. 提交本地文件到暂存区,进入信息编辑界面
      2. -C <commid-id>/<tag-name>
        沿用指定commit-id/tag的提交信息
        通常和git reset --soft HEAD^^合用,用于提交日志合并
    • diff
      1. 没有参数
        工作区和暂存区比较
      2. <commit-id1> <commit-id2>
        比较两个commit之间的差异
      3. <commit1-id/tag1-name> <commit2-id/tag2-name> -- <path>
        比较两个commit/tag之间指定路径的差异
      4. --cached <commit-id>/<tag-name>
        比较暂存区和指定commit-id或者tag
      5. --cached
        暂存区和HEAD比较
      6. --HEAD
        工作区和HEAD比较
    • fsck
      查看没有被任何引用关联的松散对象
    • log
      1. --stat
        显示修改摘要
      2. -p
        显示修改详情
      3. --oneline
        一行显示提交信息
    • mv
      <src-file> <dst-file>
      移动文件
    • prune
      清除为关联的松散对象
    • rebase
      1. --onto <newbase> <since> <till>
        • 步骤
          1. 执行git checkout切换到till
          2. <since>..<till>所标识的提交范围写到一个临时文件中 (since, till]
          3. 将分支强制重置 git reset --hardnewbase
          4. 从保存在临时文件的提交列表中,将按顺序逐一提交到重置后的分支上
          5. 若遇到的提交在分支中已经包含则跳过
          6. 若遇到冲突,变基过程暂定。解决冲突后(需要git add,不需要git commit),git rebase --continue继续变基操作,git rebase --skip跳过此提交,git rebase --abort终止变基操作,并切换到变基前的分支上
      2. 删除旧提交历史
        • 步骤
          1. 创建新的根目录树
            echo "new commit msg" | git commit-tree C^{tree}
          2. 变基
            git rebase --onto 69bca1a7(上一条命令的执行结果) C^ HEAD
    • reflog
      1. 无参数
        显示对当前仓库所有分支的操作记录
      2. show <br-name>
        显示对当前分支的操作记录 - cat .git/logs/refs/heads/master
      3. 若想恢复到某条操作记录的状态
        执行git reset --hard <commit-id>/<ref>
    • reset
      1. –hard commit-id
        • 步骤
          1. 替换master引用的指向,指向新的提交id
          2. 替换暂存区,替换后暂存区和引用指向的目录树一致
          3. 替换工作区,替换后工作区内容和暂存区一致,也和HEAD指向的目录树内容一致
        • 注意点
          破坏工作区未提交的改动
      2. –mixed或不使用参数 commit-id
        • 步骤
          1. 替换master引用的指向,指向新的提交id
          2. 替换暂存区,替换后暂存区和引用指向的目录树一致
          3. 不改变工作区
      3. –soft commit-id
        • 步骤
          1. 替换master引用的指向,指向新的提交id
          2. 不改变暂存区和工作区 – 测试发现貌似改变了暂存区 HEAD^^
      4. HEAD
        用指定提交状态下的文件替换暂存区中的文件,应该是目录树替换
    • rev-list -HEAD
      显示所有提交commit-id
      1. 显示当前分支总的提交次数
        rev-list -HEAD | wc -l:
    • revert
      反转提交
      git revert HEAED, 将最新的一次提交还原到提交之前的状态
    • show-ref
      查看所有引用,包括tag和分支
    • stash
      1. 无参数
        保存当前工作区和暂存区进度
        注意:工作区新增的文件不会保存
      2. pop
        从最近保存的进度恢复当前工作区
        • –index:恢复工作区和尝试恢复暂存区文件
        • :恢复指定的进度
        • 注意:工作区新增的文件不会保存
      3. list
        显示保存的进度
      4. drop <stash-id>
        丢弃指定保存的进度,默认删除最新的进度
      5. clear
        删除所有存储的进度
      6. branch <br-name> <stash-id>
        基于进度创建分支
      7. save -k
        在保存进度后不会重置工作区和暂存区,默认会重置暂存区和工作区
    • status
      1. -s
        精简显示差异信息
      2. -b
        显示信息中带分支名
      3. --ignore
        显示被忽略的文件
    • tag
      1. 创建
        • <tag-name> <commit-id>
          不带说明
        • -a <tag-name> <commit-id>
          带说明
        • -m <tag-desc> <tag-name> <commit-id>
          带说明
      2. 删除
        • 本地
          git tag -d
          注意:tag一经删除不易恢复,删除的命令输出中会显示tag对象的提交ID,一旦发现错误删除,赶紧补救
        • 远程
          1. git tag -d <tag-name>
          2. git push origin:<tag-name>
      3. 推送
        • 推送一条
          git push origin
        • 推送所有
          git push origin refs/tags/*
      4. 拉取
        git pull origin refs/tags/<tag1-name>:refs/tags/<tag2-name>
        tag-name 可以是tag名或者通配符
      5. 查看 - 支持通配符
        • 查看本地
          1. git tag
          2. git show-ref
        • 查看远程
          git ls-remote <remote-url> *
          remote-url: origin或者是完整的git地址