git阅读笔记

260 阅读8分钟

起步

版本控制:

是记录一个或多个文件内容变化,以遍将来查阅特定版本修订情况的系统。

分布式版本控制,客服端是把代码仓库整个完整的镜像下来,包括完整的历史记录。

  • 直接记录快照,而非差异比较

提交更新或保存项目状态时,就会对当前全部的文件创建一个快照并保存这个快照的索引。
如果文件没有修改,git不在重新存储该文件,只保留一个链接指向之前存储的文件。

  • 几乎所有操作都是本地执行
  • 保证完整性 (git中所有的数据在存储前都计算校验和(hash:由40个16进制字符组成),然后与校验和来引用)
  • 三种状态:已修改、已暂存(git add)、已提交(git commit)
  • 工作区、暂存区域以及git仓库

git配置

$ git config --list --show-origin  查看所有配置及文件所在位置
$ git config --list                查看配置信息

位置

  • ./etc/gitconfig文件:系统配置 git config --system
  • ~/.gitconfig~/.config/git/config文件:当前用户git配置git config --global
  • 当前仓库的git配置.git/config:针对当前仓库

每个级别都会覆盖上一个级别的配置

用户信息

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

帮助

$ git help config   获取config命令手册

基础

获取git仓库

  • 本地目录初始化git目录 git init
  • 克隆现有仓库 git clone git@url

更新到仓库

  • git status 状态详情
  • git status -s 简略状态信息
  • git add <files> 将修改添加到暂存区
  • .gitignore忽略的配置文件
    • 所有空行或者以#开头的行都会被git忽略
    • 可以使用标准的glob的匹配模式,递归的应用在整个工作区中
    • 匹配模式可以以/开头防止递归
    • 匹配模式可以以/结尾指定目录
    • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反
    • 正则*?[]适用
    • 星号(**)匹配任意中间目录
  • git diff尚未存储的文件更新了哪些部分
    • --staged 比对已暂存文件与最后一次提交的文件差异
    • --cached 查看已经暂存起来的变化
  • git commit -m"msg" 提交更新
  • git rm --cached 从暂存区删除文件
  • git mv file_from file_to暂存区重名文件

查看提交历史

git log 提交信息

  • 选项 |选项|说明(提交信息+)| |--|--| |-p|按补丁格式显示每个提交引入的差异| |--stat|每次提交修改的统计信息| |--shortstat|行数修改、添加、移除总数| |--name-only|文件清单| |--name-status|文件状态清单| |--abbrev-commit|仅显示 SHA-1 校验和所有 40 个字符中的前几个字符| |--relative-data|相对现在的时间差| |--pretty|其他格式展示
    oneline、short、full、fuller 和 format(用来定义自己的格式)|

  • 过滤条件 |选项|说明| |--|--| |-n|展示最近n次| |--since, --after|指定时间之后的提交| |--until, --before|指定时间之前的提交| |--author|指定作者| |--committer|指定提交者| |--grep|搜索条件| |-S|匹配的删除添加|

  • --pretty=format 常用选项 |选项|说明| |--|--| |%H|提交的完整哈希值| |%h|提交的简写哈希值| |%T|树的完整哈希值| |%t|树的简写哈希值| |%P|父提交的完整哈希值| |%p|父提交的简写哈希值| |%an|作者名字| |%ae|作者的电子邮件地址| |%ad|作者修订日期(可以用 --date=选项 来定制格式)| |%ar|作者修订日期,按多久以前的方式显示| |%cn|提交者的名字| |%ce|提交者的电子邮件地址| |%cd|提交日期| |%cr|提交日期(距今多长时间)| |%s|提交说明|

  • 查看其它分支log git log develop,git log origin/develop

  • git log commtId 输出提交记录

  • git reflog 日志引用

  • git show HEAD@{n} 输出提交记录

  • git show master@{yesterday} 历史提交记录

  • 祖先引用^~

    • git log head@{2}^ 第前三次提交记录
    • git log 12132~3 第前三次提交记录
  • 提交区间

    • .. 这种语法可以让 Git 选出在一个分支中而不在另一个分支中的提交 git log origin/develop..develop
    • ... 这个语法可以选择出被两个引用之一包含但又不被两者同时包含的提交

撤消操作

  • 从暂存区取消git restore --staged <files>
  • 还原修改
    • git restore <files>
    • git checkout <files>

集体看git status提示

远程仓库的使用

  • 查看远程仓库
    • 仓库列表 git remote
    • 仓库地址 git remote -v
    • 仓库详情 git remote -v show shortname
  • 添加远程仓库 git remote add shortname url
  • 从远程仓库中抓取与拉取 git fetch shortnamegit pull = git fetch + git merge
  • 推送到远程仓库 git push shortname branch
  • 远程仓库的重命名 git remote rename oldname newname
  • 远程仓库移除 git remote remove shortname

打标签

  • 查看
    • 列表 git tag -l
    • 标签详情 git show tagname
  • 创建标签
    • 附注标签 git tag -a tagname -m "msg"
    • 轻量标签 git tag tagname
    • 历史标签 git tag -a tagname 9fceb02
  • 删除标签 git tag -d tagname
  • 标签推送到远程仓库
    • 单个 git push origin <tagname>
    • 批量 git push origin --tags
    • 删除 git push origin --delete <tagname>

分支

  • 当使用 git commit 进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和, 然后在 Git 仓库中这些校验和保存为树对象。
  • Git 便会创建一个提交对象, 它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。
  • 如此一来,Git 就可以在需要的时候重现此次保存的快照。
    实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件

本地分支

  • 新建分支 git branch <name>
  • 切换分支 git checkout <name>
  • 新建并切换分支 git checkout -b <name>
  • 删除分支 git branch -d <name>
  • 强制删除分支 git branch -D <name>
  • 合并分支 git merge <name>
  • 合并工具 git mergetool
  • 列表 git branch
    • -v 查看每个分支的最后一次提交信息
    • --merged 查看已经合并到当前分支的分支
    • --no-merged 未合并到当前分支的分支
    • --merged name, --no-merged name某分支排除过滤

远程分支

  • 跟踪远程分分支 git branch -u origin/branchName
  • 新建不跟踪远程分支
    • git branch --track origin/branchName
    • git checkout origin_branchName
    • git checkout -b sf origin/master 新建分支与远程分支命名不同
  • 删除远程分支 git push origin --delete develop
  • git ls-remote <remote> 来显式地获得远程引用的完整列表

变基

git rebase develop: 如develop分支有新的变更会被合并过来

将提交到某一分支上的所有修改都移至另一分支上,相当于改变checkout -b 的基础

贮藏

  • git stash,git stash push
  • git stash list
  • git stash apply,git stash apply stash@{n}
    • git stash pop 对应stash存取变更会被取出
    • git stash drop stash@{n} 直接删除
  • 从贮藏创建一个分支git stash branch <new branchname>

可在任意分支取出

清理目录

git clean 移除没有忽略的未跟踪文件

重写历史

修改最后一次提交

  • 修改messagegit commit --amend -m"msg"
  • 不修改messagegit commit --amend --no-edit

修改多个提交

  • git rebase -i commitId~n
    git commit --amend
    git rebase --contiune

重置HEAD

HEAD指向当前分支的最后一次提交
三棵树(head、索引、工作目录),git status主要是比对这三者是否相同

  • 移动指针(一维) git reset

    工作目录 ---- git add ----> 索引 ------- git commit ------> head
       |-----------------------------|<---git reset --soft commitId--|
       |<------------------- git reset commitId ----------------------|
       |<-------------git reset --hard(不保留更改) ---------------|

  • 检出(移动指针 二维)
    • git checkout branch head移动到去其他分支
    • git checkout path 从缓存区检出
    • git checkout commitId 检出到临时分支

合并

  • git merge branch
  • 中断合并 git merge --abort
  • 还原合并 git revert -m 1 HEAD

子模块

  • 新增
    • git submodule add url
    • 到指定目录 git submodule add url path
  • 查看记录 git diff --cached --submodule
  • 克隆含子模块的项目
    • git clone url
      git submodule init
      git submodule update
    • git submodule update --init
    • 递归克隆子模块 git submodule--recurse-submodules
    • git submodule update --init --recursive
  • 设置跟踪的分支git config -f .gitmodules submoduleName.DbConnector.branch branchName
  • 删除子模块
    • rm -rf 子模块目录
    • vi .gitmodules 删除项目目录下.gitmodules文件中子模块相关条目
    • vi .git/config 删除配置项中子模块相关条目
    • rm .git/module/* 删除模块下的子模块目录
    • git rm --cached 子模块名称

git钩子

在重要动作发生时触发自定义脚本
位置:.git/hooks ,带.sample未示例脚本,使用需去除后缀。

客户端钩子

提交工作流钩子

  • pre-commit检查将要提交的快照,可以使用git commit --no-verify绕过
  • prepare-commit-msg 钩子在启动提交信息编辑器之前,默认信息被创建之后运行
  • commit-msg接收一参数,存有当前提交信息的临时文件的路径
  • post-commit 钩子在整个提交过程完成后运行
其他客户端钩子
  • pre-rebase变基之前。禁止对已推送的提交变基
  • git-push在push期间运行

原理

git是内容寻址文件系统,并在此之上提供一个版本控制系统的界面。核心部分是简单的键值对数据库

.git 目录下内容

  • description 文件仅供 GitWeb 程序使用
  • config 文件包含项目特有的配置项
  • info目录包含exclude放置那些不希望被记录在 .gitignore 文件中的忽略模式
  • hooks目录包含钩子脚本
  • HEAD指向当前分支
  • index文件保存当前暂存区信息
  • objects 目录存储数据内容
  • refs 目录存储指向数据(分支、远程仓库和标签等)的提交对象的指针