# GIT
# 1. git 原理
Git 是目前世界上最先进的分布式版本控制系统(没有之一)。
还是去看看阮老师写的吧,链接: Git 原理入门- 阮一峰 (opens new window)
# 2. 目录解析
.git 目录下有几个重要的文件/文件夹
* config # 文件,主要存储项目的一些配置信息
* objects # 文件夹, 存储git对象
* HEAD # 文件,记录当前的头指针
* index # 文件,存储暂存区的信息
* refs # 文件夹, 存储分支的指针
* hooks # 文件夹,存储钩子文件
# 3. 常用命令
git init # 初始化git
git status -s # 以极简的方式显示文件状态
git clone <url> # 克隆项目
git add . # 添加所有文件到暂存区
git add <fileName> # 添加指定文件到暂存区
git commit -m <commitInfo> # 提交暂存区到仓库区
git commit --amend # 会将修改追加到上一次的提交里
git pull # 取回远程仓库的变化,并与本地分支合并
git pull --rebase # 推荐添加 --rebase
git push # 推送到远程仓库
git push [远程主机名] [本地分支名]
git fetch --all # 下载远程仓库的所有变动
git merge [分支名] # 合并指定分支到当前分支
git branch # 列出所有本地分支
git checkout [分支名] # 切换到指定分支
git checkout -b [本地分支名] origin/[远程分支名] # 拉取远程分支
git branch -d [本地分支名] # 删除本地分支
#查看项目中git配置
git config --list
# 配置全局信息
git config --global user.name "[name]"
git config --global user.email "[email address]"
# 项目中配置
git config user.name "[name]"
git config user.email "[email address]"
# 查看当前分支是从哪个分支拉出来的
git reflog --date=local | grep <branchName>
# 3.1 git remote
管理远程仓库
git remote # 查看远程仓库
git remote -v # 查看关联的远程仓库的详细信息
git remote add origin [远程仓库地址] # 添加远程仓库的关联
git remote remove [远程仓库名称] # 删除远程仓库的关联
git remote update origin --prune # 更新远程仓库的分支
# 3.2 git rebase
git rebase 一般被翻译为 变基,这个名字很灵性。他会找共同的父亲,然后将 commit 插入到 commit 列表中,可以把本地未 push 的分叉提交历史整理成直线;
# 4. 常见应用
# 4.1 本地项目上传至多个远程库
# 关联远程库
git remote add gitee [项目URL地址]
git remote add github [项目URL地址]
git remote rm [origin] # 删除
# 推送
git push gitee master
git push github master
# 4.2 git 远程分支强制覆盖本地分支
git fetch --all
git reset --hard [origin/master]
git pull
# 4.3 .gitignore 不生效解决方案
清除缓存 重新提交
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
git push
# 4.4 远程分支操作
git push origin --delete [远程分支名称] # 删除远程分支
# 4.5 本地分支操作
git branch # 查看本地分支
git branch -D <branchName> # 删除本地分支
git checkout <branchName> # 切换本地分支
# 4.6 git stash 暂存
git stash # 将修改存储到暂存区,工作区会删除这些修改
git stash pop # 取出修改
git stash list # 查看暂存区的所有暂存修改
git stash apply stash@{0} # 取出相应的暂存
git stash drop stash@{0} # 将记录列表中取出的对应暂存记录删除
# 4.7 清除无用的 branch ref
git 官网: git remote prune [-n | --dry-run]
… (opens new window) Deletes stale references associated with
<name>
. By default, stale remote-tracking branches under<name>
are deleted, but depending on global configuration and the configuration of the remote we might even prune local tags that haven’t been pushed there. Equivalent to git fetch --prune, except that no new references will be fetched. 删除与
<name>
关联的陈旧引用。 默认情况下,删除<name>
下过时的远程跟踪分支,但根据全局配置和远程配置,我们甚至可能会修剪尚未推送到那里的本地标签。 等同于 git fetch --prune,除了不会获取新的引用。
git remote prune origin # 清除无用的 branch ref
# 4.8 撤销本次 pull rebase(变基) 回退到 pull 前的代码
git reflog # 参看本地记录
git reset --hard <commitId> # 回退到指定 commit
git rebase --abort # 取消 rebase 状态
# 4.9 批量删除分支
# 批量删除本地分支 xxx 为匹配字符
git branch |grep 'xxx' |xargs git branch -D
# 批量删除本地非 develop master 分支
git branch |egrep -v "(^\*|master|develop)" |xargs git branch -D
# 批量删除远程分支 xxx 为匹配字符
git branch -r |grep 'xxx' |xargs |awk '{gsub("origin/","");print $0}' |xargs git push origin -d
# 4.10 代码回退到某个 commit
谨慎使用,回退不可逆 或使用 --soft
git log # 查找指定 commit 的 id
git reset –hard edfab6afce95d0ebbd35d34219dba365773b5b4e # 版本回退
# 5. git 提交规范
Feat:新功能(feature)
Fix:修补bug
Docs:文档(documentation)
Style: 格式(不影响代码运行的变动)
Refactor:重构(即不是新增功能,也不是修改bug的代码变动)
Test:增加测试
Chore:构建过程或辅助工具的变动
Modify: 修改
# 6. git cherry-pick
git cherry-pick 是将某个分支的 commit 提交到当前分支
git checkout <needPickBranch> # 进入需要被提交的分支
git cherry-pick <commitHash> # 填写 commitHash 进行提交
# 7. reset 与 revert(回滚/回退)
git revert
回滚(撤销)对应 commit 。git revert 后多出一条 commit 来提醒开发者,这里是回撤。
git revert HEAD # 撤销前一次 commit
git revert HEAD^ # 撤销前前一次 commit
git revert <commitHash> # 撤销指定的版本
# 参数
git revert <commitHash> --no-edit # 执行时不打开默认编辑器,直接使用 Git 自动生成的提交信息。
git revert <commitHash> --no-commit # 只抵消暂存区和工作区的文件变化,不产生新的提交。
git reset
回退到对应 commit 版本,直接将之前 commit 丢弃。
git reset HEAD # 回退前一次 commit
git reset HEAD^ # 回退前前一次 commit
git reset <commitHash> # 回退到指定的版本
# 参数
git reset --hard <commitHash> # 参数可以让工作区里面的文件也回到以前的状态。
git reset --soft <commitHash> # 回退后a分支修改的代码被保留并标记为add的状态(git status 是绿色的状态)
git reset --mixed <commitHash> # 重置索引,但不重置工作树,更改后的文件标记为未提交(add)的状态。默认操作。
git reset --hard <commitHash> # 重置索引和工作树,并且a分支修改的所有文件和中间的提交,没提交的代码都被丢弃了。
git reset --merge <commitHash> # 和--hard类似,只不过如果在执行reset命令之前你有改动一些文件并且未提交,merge会保留你的这些修改,hard则不会。【注:如果你的这些修改add过或commit过,merge和hard都将删除你的提交】
git reset --keep <commitHash> #和--hard类似,执行reset之前改动文件如果是a分支修改了的,会提示你修改了相同的文件,不能合并。如果不是a分支修改的文件,会移除缓存区。git status还是可以看到保持了这些修改。
# 8. git reflog
git reflog <subcommand> <options>
git reflog [show] [log-options] [<ref>]
# expire 子命令会删除掉更老的 reflog 条目。
git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all | <refs>…]
# delete 子命令从 reflog 中删除一个条目。
git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] ref@{specifier}…
# exists 子命令检查一个 ref 是否有一个 reflog。
git reflog exists <ref>
git log 是显示当前的 HEAD 和它的祖先的,递归是沿着当前指针的父亲,父亲的父亲,…,这样的原则。
git reflog 根本不遍历 HEAD 的祖先。它是 HEAD 所指向的一个顺序的提交列表:它的 undo 历史。reflog 并不是 repo(仓库)的一部分,它单独存储,而且不包含在 pushes,fetches 或者 clones 里面,它纯属是本地的。
reflog 可以很好地帮助你恢复你误操作的数据,例如你错误地 reset 了一个旧的提交,或者 rebase,…,这个时候你可以使用 reflog 去查看在误操作之前的信息,并且使用 git reset --hard 去恢复之前的状态。
下面研究一下这个命令的具体用法。
先了解一下 git 的版本表示方法:
HEAD@{2} means “where HEAD used to be two moves ago”, master@{one.week.ago}means “where master used to point to one week ago in this local repository”
HEAD@{2}表示 HEAD 指针在两次移动之前的情况;而 master@{one.week.ago}表示 master 在本地仓库一周之前的情况。
“show”子命令显示所指定的参考的日志。
# 9. git log 优化
%H: commit hash
%h: 缩短的 commit hash
%T: tree hash
%t: 缩短的 tree hash
%P: parent hashes
%p: 缩短的 parent hashes
%an: 作者名字
%aN: mailmap 的作者名字 (.mailmap 对应,详情参照git-shortlog(1)或者git-blame(1))
%ae: 作者邮箱
%aE: 作者邮箱 (.mailmap 对应,详情参照git-shortlog(1)或者git-blame(1))
%ad: 日期 (--date= 制定的格式)
%aD: 日期,RFC2822 格式
%ar: 日期,相对格式 (1 day ago)
%at: 日期,UNIX timestamp
%ai: 日期,ISO 8601 格式
%cn: 提交者名字
%cN: 提交者名字 (.mailmap 对应,详情参照git-shortlog(1)或者git-blame(1))
%ce: 提交者 email
%cE: 提交者 email (.mailmap 对应,详情参照git-shortlog(1)或者git-blame(1))
%cd: 提交日期 (--date= 制定的格式)
%cD: 提交日期,RFC2822 格式
%cr: 提交日期,相对格式 (1 day ago)
%ct: 提交日期,UNIX timestamp
%ci: 提交日期,ISO 8601 格式
%d: ref 名称
%e: encoding
%s: commit 信息标题
%f: sanitized subject line, suitable for a filename
%b: commit 信息内容
%N: commit notes
%gD: reflog selector, e.g., refs/stash@{1}
%gd: shortened reflog selector, e.g., stash@{1}
%gs: reflog subject
%Cred: 切换到红色
%Cgreen: 切换到绿色
%Cblue: 切换到蓝色
%Creset: 重设颜色
%C(...): 制定颜色,as described in color.branch.* config option
%m: left, right or boundary mark
%n: 换行
%%: a raw %
%x00: print a byte from a hex code
%w([[,[,]]]): switch line wrapping, like the -w option of git-shortlog(1).
example:
git log --graph --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative
alias glo="git log --graph --date=format:'%Y.%m.%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s <%an> %Cgreen(%cd)%Creset' --abbrev-commit"
参考文章