摘要:本次学习首先跟着廖雪峰老师的Git教程,了解了Git的基础概念、常用命令;然后阅读了阮一峰老师关于Git的相关总结性文章,有了更加立体的认识。在此,对二位老师表示诚挚的感谢。本小结主要参考阮一峰老师的总结文章(见文后参考文献),结合学习廖雪峰老师教程的心得,补充了一些自己的理解。主要目的在于强迫自己进行实践以加深理解。
一、相关术语
- Workspace: 工作区,指操作目录,包含未被Git管理的文件及未添加至暂存区的修改;
- Index/Stage: 暂存区,指工作区与仓库之间的缓存,包含尚未提交到本地仓库的修改;
- Repository: 本地仓库,指本地管理的代码仓库,用于离线工作;
- Remote: 远程仓库,指远程服务器管理的代码仓库,用于多方协作;
二、常用命令
1. 创建仓库
# 初始化本地仓库,dir参数指创建指定目录并初始化为本地仓库
git init [dir]
# 克隆远程仓库,会包含远程库的所有信息,并在本地创建与远程master分支(默认分支)关联的本地分支;
# url支持多种协议:https,ssh,git等,通常来说git协议速度最快
git clone [url]
# 关联本地仓库到远程仓库,url指远程仓库链接
git remote add origin [url]
2. 增加或删除文件
# 将指定文件夹或目录(包含子目录)添加至暂存区
git add [file | dir] [file | dir] ···
# 将当前目录下所有文件到暂存区
git add .
# 删除指定文件夹及目录(包括子目录),并将修改添加至暂存区
git rm [file | dir] [file | dir] ···
# 将指定文件从git管理中删除,但保留在工作区
git rm --cached [file]
# 重命名文件,并将修改添加至暂存区
git mv [file-original] [file-renamed]
3. 提交修改
# 提交暂存区修改到本地仓库
git commit -m “commit message”
# 提交工作区或暂存区中指定文件或目录到本地仓库
git commit -m “commit message” [file | dir] ···
# 提交工作区及暂存区中的所有修改到本地仓库
git commit -m “commit message” -a
# 提交时显示diff信息
git commit -v
# 提交指定文件或目录到本地仓库,并覆盖上一次的提交信息
git commit -m “commit message” --amend [file | dir] ···
4.撤销修改
# 恢复暂存区的指定文件到工作区
git checkout [file | dir]
# 恢复本地仓库中指定commit的指定文件到工作区
git checkout [commit] [file | dir]
# 恢复本地仓库中上一个commit的所有文件到工作区
git checkout .
# 重置暂存区中的指定文件至本地仓库中的上一次commit,工作区中文件保持不变
git reset [file]
# 重置暂存区及工作区中文件至本地仓库中上一次commit的状态
git reset --hard
# 重置暂存区(及工作区(--hard))中文件至本地仓库中指定commit的状态
git reset [--hard] [commit]
# 重置HEAD指向指定commit,但保持暂存区及工作区不变
git reset --keep [commit]
# 新增一个commit用以撤销本地仓库中指定commit中的修改
git revert [commit]
5. 分支操作
# 列出所有本地分支
git branch
# 列出所有远程分支
git branch -r
# 列出所有本地分支和远程分支
git branch -a
# 新建一个分支,但依旧留在当前分支
git branch [local-branch]
# 新建一个分支,并切换到新建的分支
git checkout -b [local-branch]
# 新建一个分支,指向指定commit
git branch [local-branch] [commit]
# 新建一个分支,与指定的远程分支建立追踪关系
git branch --track [local-branch] [remote-branch]
# 本地分支:则切换到指定本地分支,并更新工作区至指定分支的最近一次commit
# 远程分支:则切换为指向指定远程分支的“detached HEAD”态
git checkout [branch]
# 建立本地分支与远程分支的追踪关系,以进行同步
git branch --set-upstream [local-branch] [remote-branch]
# 合并指定分支所有修改到当前分支
git merge [branch]
# 选择一个commit,合并该commit之前的所有修改进当前分支
$ git cherry-pick [commit]
# 删除分支,当分支有未合并数据且决定丢弃时需要用“-D”进行强制删除
$ git branch -d [branch-name]
# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
6. 标签操作
# 列出所有tag
git tag
# 新建一个tag在当前commit
git tag [tag]
# 新建一个tag在指定commit
git tag [tag] [commit]
# 删除本地tag
git tag -d [tag]
# 提交指定tag
git push [remote] [tag]
# 提交所有tag
git push [remote] --tags
# 删除远程tag
git push origin :refs/tags/[tagName]
# 查看tag信息
git show [tag]
# 新建一个分支,指向某个tag
git checkout -b [branch] [tag]
# 创建签名tag,采用GPG签名,详见参考网址
git tag -s [tag]
7. 查看信息
查看当前修改状态
git status
查看日志信息
# 显示当前分支的版本历史,--stat会显示每次commit的修改文件及其对应的修改数
git log [--stat]
# 显示截止到指定commit的版本历史
git log [commit]
# 显示两个commit之间(包含这两个commit)的版本历史
git log [lt-commit]...[gt-commit] --grep feature
# 显示每次commit中指定文件的元数据修改信息
git log -p [file]
# 显示某个文件的版本历史(包括文件改名)
git whatchanged [file]
# 显示指定文件的修改历史(包含修改时间及作者)
git blame [file]
# --pretty=[onelile | format ···],用于设定显示格式
# --grep="regex",用于搜索提交说明
# 详见git help log
查看差异信息
# 显示工作区与暂存区的差异
git diff
# 显示工作区与指定commit之间的差异
git diff [commit]
# 显示暂存区和指定commit的差异
git diff --cached [commit]
# 显示两次commit之间(包含这两个commit)的差异
git diff [lt-commit]...[gt-commit]
# 以上查看差异的命令中均可指定file,以查询指定文件的差异
查看commit或tag信息
# 显示某次commit或tag的所有元数据修改
git show [commit | tag]
# 显示某次commit或tag发生变化的文件名
git show --name-only [commit | tag]
# 显示某次commit或tag中指定文件的所有内容
git show [commit | tag]:[filename]
查看最近git操作
git reflog
8. 远程同步
# 显示所有远程仓库
git remote -v
# 显示某个远程仓库的信息
git remote show [remote]
# 增加一个新的远程仓库,并命名。当ssh被屏蔽,可以配置https协议等
git remote add [shortname] [url]
# 同步远程仓库的所有修改
git fetch [remote]
# 取回远程仓库的变化,并与本地分支合并,相当于fetch + merge
git pull [remote] [branch]
# 上传本地指定分支到远程仓库
git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
git push [remote] --force
# 推送所有分支到远程仓库
git push [remote] --all
9. 其他
# 调整指定commit及之后的所有commit的结构
git rebase -i [commit]
# 调整两个commit之间(包含这两个commit)的所有commit的结构
git rebase -i [lt-commit]...[gt-commit]
# 使用交互模式时首先会进入所选提交的rebase编辑界面:
#
# 相关命令:
# p, pick = 使用提交
# r, reword = 使用提交,但是需要更新提交说明
# e, edit = 使用提交,但处理该提交的时候暂停以进行修正,如可以将一个commit分割成多个commit等
# s, squash = 将该提交放入其之前的一个提交中,保留提交说明到上一个提交的提交说明
# f, fixup = 将该提交放入其之前的一个提交中,放弃提交说明
# x, exec = 执行相应的shell命令
# d, drop = 删除提交
#
# 相关说明:
# 所有的提交可以调整顺序,执行时自上而下执行;
# 如果仅仅移除其中一行提交信息,会导致该提交丢失
# 如果删除所有提交信息,会导致rebase终止
# 注意空提交将被注释
10. 配置
~/.gitconfig文件
# 配置git的用户信息
[user]
name = xxx
email = xxx
# 配置别名,顺便安利下某大神log输出的配置
[alias]
lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
project/.git/config文件
# 核心配置,尚在研究中
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
# 远程仓库地址,可配置多个不同协议的远程仓库
[remote "origin"]
url = xxx
fetch = +refs/heads/*:refs/remotes/origin/*
# 本地分支,可设置多个
[branch "master"]
# 指定使用的远程仓库
remote = origin
# 指定追踪的远程分支
merge = refs/heads/master
project/.gitignore文件
该文件指定那些不需要git管理的文件,见gitignore模板
三、场景应用之GitHub
四、场景应用之Bug分支
假设正在dev分支上开发时,接到优先级更高的bug修复任务,因此需要先保存dev分支的现场,然后新开bug分支完成修复任务之后再恢复dev分支的现场,继续之前的开发:
# 假设当前在dev分支
# 保存dev分支的现场,此时工作区变为clean
git stash
# 切换到需要修复bug的分支,新建并切换bug分支
git checkout [fix-branch]
git checkout -b [issue]
# 修复完bug之后提交,并回到需要修复bug的分支进行合并,之后删除bug分支
git checkout [fix-branch]
git merge [issue]
git branch -d [issue]
# 切回dev分支,并恢复现场后继续开发工作
git checkout dev
git stash pop
stash用于保存现场,现场会被保存在一个现场栈中,有以下操作命令:
# 查看现场栈信息
git stash list
# 保存当前分支的现场
git stash
# 恢复指定现场,当不在现场栈中删除
git stash apply [stash@{N}]
# 在现场栈中删除指定现场
git stash drop [stash@{N}]
# 恢复并删除栈顶现场
git stash pop