git 日常使用小结

Git 简介

  • 分布式控制系统
    1. 版本库本地化, 支持离线提交, 相对独立不影响协同开发.
    2. 更少的 “仓库污染”.
    3. 把内容按元数据方式存储, 完整克隆版本库.
    4. 支持快速切换分支方便合并, 比较合并性能好.
    5. 分布式版本库, 无单点故障, 内容完整性好.

开发模式

开发模式

快速入门

快速入门

Git 基础命令

  • git 配置

     git config -l    # 查看当前配置
     git config --global user.name "YQqiang"    # 设置用户名
     git config --global user.email xxxx@gmail.com    # 设置邮箱
     git config --golbal alias.ci commit    # 设置git 命令的别名
     git config --golbal alias.co checkout    # 设置git 命令的别名
    
     ~/.gitconfig     # 全局配置文件
     .git    # 在库的顶级目录当中, 包含项目的所有对象, 提交记录, 配置
     .gitignore    # 记录要忽略的文件
    
  • 获得 git 仓库

    1. git init

      初始化后, 在当前目录会出现一个名为.git的目录. 所有git需要的数据和资源都存放在这个目录中.

    2. git clone
      • git clone git@github.com:YQqiang/MoyaDemo.git 获取社区代码, 但是需要有相关权限才能访问 (使用 ssh-keygen 生成 id_rsaid_rsa.pub, 将id_rsa.pub 添加到authorized_keys)
  • git clone https://github.com/YQqiang/MoyaDemo.git 获取github中提供的第三方资源

  • 提交文件

    提交文件

    • git status 查看文件状态
    • 文件所处三种状态
      • working tree 对应.git/之外的项目文件或目录
      • index tree (add 后) 对应.git/index
      • HEAD (commit 后)
    • HEAD 相关意义
      • HEAD 代表最后一次提交
      • HEAD^ 代表最后一次提交的父提交 等价于HEAD~1>
      • HEAD~2 倒数第二次提交 —
    • git diff 显示working treeindex tree 之间的差异
    • git diff --staged 用户来查看index tree 中的内容 和 HEAD中的区别
    • git diff HEAD 显示working treeindex tree 两者之和与HEAD中的区别, 用来看总共的修改内容
    • git diff file_name 或者 git diff dir_name/ 查看指定文件或目录的修改
    • git diff one_commit_hash another_commit_hash 查看两次commit 之间的差异
    • git diff one_branch_name another_branch_name 对比两个分支之间的差异 —
    • 跟踪新文件
    • git add file_name 将本地指定文件名或目录(新增 和 修改, 没有删除) 的文件添加到暂缓区
    • git add . 将本地所有的(新增 和 修改, 没有删除) 的文件添加到暂缓区. 同样可以使用*来匹配
    • git add -u 将本地的(修改 和 删除, 没有新增) 的文件添加到暂缓区
    • git add -A 将本地所有改动添加到暂缓区 (git add -A = git add . + git add -u) —
    • git commit -m "comment" 提交暂缓区中的内容(已经add) 并添加注释
    • git commit -a 把修改的文件添加到暂缓区(不包括新建(untracked)的文件), 然后提交
    • git commit -i 通常在文件冲突解决以后, 提交解决的冲突时使用. —
    • git fetch 从远程获取最新版本到本地, 不会自动merge
    • git pull 从远程获取最新版本到本地并merge到本地, 相当于git fetchgit merge
    • 在实际使用中, git fetch 更安全一些, 因为在merge前我们可以查看更新情况, 然后再决定是否合并 —
    • 解决冲突
      • 根据冲突提示, 逐个查找冲突文件中有冲突的地方进行手动解决
      • 使用git冲突解决工具, 如: P4merge, kdiff3 —
    • git push
    • git push origin branch_name 将本地分支推送到origin主机的某分支, 如果该分支不存在, 就新建该远程分支
    • git push -u origin master -u (upstream) 指定origin 为默认主机, 后面就可以不加任何参数使用git push
    • git push --all origin 将所有本地分支都推送到origin主机
    • git push origin :branch_name 删除远程分支(即推送一个空分支到主机)
    • git push origin local:remote 完整格式
  • 查看提交历史

    • git log 查看提交记录
    • git log -n n是一个正整数, 查看前n次修改
    • git log file1 file2 查看file1文件, file2文件的提交记录
    • git log file/ 查看file文件夹下所有文件的提交记录
    • git log v1 此时的v1 代表的是分支的名字
    • git log -- v1 此时的v1 代表的是名为v1的文件
    • git log --oneline 一行显示一条log
    • git log -p 查看详细修改内容
    • git log --stat 查看提交统计信息
    • git log -graph 显示何时出现了分支和合并等信息
    • git log commit_id 查询commit_id之前的记录, 包括commit_id
    • git log commit_id_1 commit_id_2 查询commit_id_1commit_id_2 之间的记录, 包括commit_id_1commit_id_2
    • git log commit_id_1..commit_id_2 同上, 但是不包括commit_id_1
    • git log v1.0.. 查询从v1.0 之后的提交历史记录(不包含v1.0)
    • git log test..master 查询master分支中的提交记录但不包含test分支记录
    • git log master..test 查询test分支中的提交记录但不包含master分支记录
    • git log master...test 查询mastertest分支中的提交记录
    • git log test --not master 屏蔽master分支
    • git log --author='yuqiangsun' 查询指定作者的提交记录
    • git log --grep='日期' 列出所有包含日期字样的提交信息说明的提交记录
    • git log --name-only 仅在提交信息后显示已修改的文件清单
    • git log --pretty=oneline 单行显示每次的提交(commit_id 和 注释)
    • git log --pretty=format:"%H %an %ae %ad %s" 格式化输出log

      选项 说明
      %H 提交对象(commit)的完整哈希字串
      %T 树对象(tree)的完整哈希字串
      %t 树对象的简短哈希字串
      %P 父对象(parent)的完整哈希字串
      %p 父对象的简短哈希字串
      %an 作者(author)的名字
      %ae 作者的电子邮件地址
      %ad 作者修订日期(可以用 -date= 选项定制格式)
      %ar 作者修订日期,按多久以前的方式显示
      %cn 提交者(committer)的名字
      %ce 提交者的电子邮件地址
      %cd 提交日期
      %cr 提交日期,按多久以前的方式显示
      %s 提交说明
  • 撤销操作

    Rebase

    rebase 详解 rebase 命令执行后, 实际上是将分支点从C移动了G, 这样分支也就具有了C到G的功能

    reset

    • 作用
      • reset 将当前的工作目录完全回滚到指定的版本号
      • revert 还原一个版本的修改, 必须提供一个具体git版本号
    • 区别
      • reset 是指将当前head的内容重置, 不会留下任何痕迹
      • revert 是撤销某次提交, 但是这次撤销也会作为一次提交进行保存
  • 打标签

    • 查看tag
      • git tag -l 查看所有tag, -l 可以省略
    • 创建tag
      • git tag v1.2.4 基于最新提交创建标签
      • git tag -a v1.2.4 -m "tag message"
      • git tag -a v1.2.4 31dd771 补打tag, 前提是记得commit
    • 分享tag
      • git push origin tag v1.2.4
      • git push origin --tags 提交所有tag到服务器
    • 删除tag
      • git tag -d v1.2.4 删除本地tag
      • git push origin :refs/tags/v1.2.4 删除远程tag

分支管理

  • 新建分支 (本地)

    • git branch new_branch 新建分支
    • git checkout branch_name 切换分支
    • git checkout -b new_branch 从当前分支新建分支(等同上面两条命令)
    • git checkout -b new_branch commit_id 从某次提交点上新建分支
  • 新建分支 (远程)

    • git push origin branch_name 将本地分支推送到origin主机的某分支, 如果该分支不存在, 就新建该远程分支
    • git push -u origin master -u (upstream) 指定origin 为默认主机, 后面就可以不加任何参数使用git push
    • git push origin local:remote 完整格式
  • 查看分支

    • git branch -l 查看本地分支, -l 可以省略
    • git branch -r 查看远程分支
    • git branch -a 查看所有分支
    • git branch -v 查看各分支最后一次提交对象信息
    • git branch -vv
  • 修改分支

    • git branch -m old_branch new_branch 本地分支重命名
    • git branch --set-upstream-to=origin/<远程分支> <本地分支> 设置本地分支对应的远程分支, 或者需要更改, 在项目根目录下.git/config, 直接修改merge = refs/heads/<分支名称>
  • 合并分支

    • git merge branch_name 将branch合并到当前分支
  • 删除分支

    • git branch -d branch_name 删除分支, 分支中所有文件已提交, 是个干净的工作目录, 不能再该分支下执行该命令
    • git branch -D branch_name 强制删除分支, 不能在该分支下执行该命令
    • git push origin :branch_name 删除远程分支(即推送一个空分支到主机)

贮藏工作进度

  • git cherry-pick commit_id 用于把另一个本地分支的commit修改应用到当前分支
  • git stash 保存当前的工作进度. 会分别对working treeindex 的状态进行保存
  • git stash save "message" 指定保存信息
  • git stash list 显示暂存列表
  • git stash pop 恢复最新保存的工作进度, 并从贮藏表中删除
  • git stash apply 回复最新保存的工作进度, 从贮藏表中删除
  • git stash ( pop | apply ) stash@{1} 恢复指定的贮藏
  • git stash clear 清空贮藏表

使用技巧

  • 用另一分支”source_branch”的指定文件直接覆盖当前分支的相应文件

    git checkout B_branch
    cd path/to/f.txt
    git checkout A_bracn  f.txt
    
  • 把当前修改的内容保存到暂缓区

    git add .
    git stash save "添加一些注释在这里
    git stash list # 查看暂缓区中的内容列表     git stash pop stash@{1}  # 出栈
    git stash apply stash@{1} # 应用
    
  • 放弃对某一个文件的修改内容

    git checkout file_name
    
  • 放弃当前所有内容的修改

    git add .
    git stash 
    git stash drop
    
  • 使用某个分支的文件替换某个分支的文件

    git 使用branch_A分支的file1文件替换branch_B的file1文件
    (branch_B) $ git checkout branch_A file1
    
  • 移除git

    rm -rf .git
    
  • 清空working tree

    git clean -df
    
  • 查看 hosts 文件

    cat /etc/hosts
    
  • commit 后的代码还原(未提交到服务器)

    git reset commit_id (回退到上一个 提交的节点 代码还是原来你修改的) 
    git reset –hard commit_id (回退到上一个commit节点, 代码也发生了改变,变成上一次的)
    
  • 按提交信息过滤

    按提交信息来过滤提交,你可以使用 --grep 标记。 比如说,你的团队规范要求在提交信息中包括相关的issue编号,你可以用下面这个命令来显示这个 issue 相关的所有提交:

      git log --grep="JRA-224:"
    

    你也可以传入 -i 参数来忽略大小写匹配。

  • git cz

    团队对提交的commit message格式有约定俗称的要求,但是没有一个统一的规范,导致大家提交的commit message或多或少不太一样。因此,需要一个工具来帮助大家统一commit message的格式,也方便后续的分析和拓展。 commitizen 是一个帮助规范commit message的工具 commitizen和cz-customizable配置git commit message 安装步骤如下:

      npm install -g commitizen
      npm install -g cz-conventional-changelog
      echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
    

    现在,进入任何git repository, 使用git cz代替git commit提交commit

  • private pod update

    验证 lib

      pod lib lint
    

    提交 pod

      pod repo push PrivateSpecs --sources=http://url/PrivateSpecs.git,master SGChart.podspec --allow-warnings
    
  • 分离 HEAD (2018-11-17 更新)

    HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。

    HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git命令都是从改变HEAD 的指向开始的。

      git checkout commit_id
    

    查看 HEAD 指向

      方式一:
      cat .git/HEAD
        
        
      方式二:
      git symbolic-ref HEAD
    

    分离的 HEAD 就是让其指向了某个具体的提交记录而不是分支名。

    Git学习推荐learngitbranching

  • 选择父提交记录

    操作符 ^~ 符一样,后面也可以跟一个数字。

    但是该操作符后面的数字与 ~ 后面的不同,并不是用来指定向上返回几代,而是指定合并提交记录的某个父提交。一个合并提交有两个父提交,所以遇到这样的节点时该选择哪条路径就不是很清晰了。

    Git 默认选择合并提交的“第一个”父提交; 在操作符 ^ 后跟一个数字可以改变这一默认行为。

  • gitignore

    https://www.gitignore.io/

    命令行使用方式

      curl https://www.gitignore.io/api/xcode,macos,swift,cocoapods,objective-c > .gitignore
    
  • 浅克隆

    仓库太大无法克隆时,可使用浅克隆

      git clone --depth 1 xxxxxxxxxxxxxx
    
Loading Disqus comments...
Table of Contents