我的 Git 备忘单
0. Git 基本概念
0.1 Git 与 SVN 区别
1. Git 是分布式版本控制系统,SVN 是集中式版本控制系统;2. Git 把内容按照元数据方式存储,每次提交的文件全部内容(snapshot)都会记录,SVN 是按照文件存储的,存储每次提交(commit)之间的差异;3. Git 的分支是在同一个工作目录下的,SVN 的分支就是版本库中的一个目录;4. Git 没有一个全局的版本号,SVN 的版本号是全局的;5. Git 使用SHA-1哈希算法确保代码内容的完整性以及出问题时对版本库最低的破坏,SVN 相比就差一些。
0.2 Git 对象
1. 所有用来表示项目历史信息的文件,是通过一个40个字符的(40-digit)“对象名”来索引的,对象名看起来像这样: 3ff87c4664981e243g625791c8ea3bbb5f2279a3。 每一个“对象名”都是对“对象”内容做SHA1哈希计算得来的,从而保证两个不同内容的对象不可能有相同的“对象名”2. 每个对象(object) 包括三个部分:类型(blob、tree、commit 和 tag)、内容(内容取决于对象的类型)和内容大小。 2.1 blob -- 用来存储文件数据,通常是一个文件; 2.2 tree -- 类似目录,用来管理一些 tree 和 blob; 2.3 commit -- 一个 commit 只指向一个 tree,标记项目某一个特定的时间点状态,包括 一些时间点的是元数据,如 时间戳、最后一个提交者等; 2.4 tag -- 标记某一个 commit 的方法。
0.3 Git 使用时的数据转换
# git 的四区 :工作区、暂存区、本地仓库及远程仓库及其使用时的关系。## 工作区 暂存区 本地仓库 远程仓库# (workspace) (index) (local repository) (remote repository) # | ---> add (-u) ---> | | |# | <--- checkout <--- | | |# | <--- diff ---> | | |# | rm --cached <--- | | |# | | ---> commit ---> | |# | | <--- reset HEAD <--- | |# | <------------ diff HEAD -------------> | |# | ------------> commit -a -------------> | |# | <------------ checkout HEAD <------------- | |# | | | ---> push ---> |# | | | <--- fetch <--- | # | <------------ merge <------------- | | # | <------------ pull or rebase <------------ |
1. 命令
1.1 开始
1.1.1 当前文件夹初始化为 git 本地仓库
$git init
1.1.2 从远程 git 仓库获取代码
$git clone url
1.2 配置
1.2.1 设置命令行显示颜色
$git config --global color.ui true
1.2.1 设置 push 到远端 分支时, 默认 push 的本地分支
$git config --global push.default current
1.2.1 设置默认的编辑器
$git config --global core.editor vim
1.2.1 设置使用 git 时默认的用户名(一般设置为名字或工号)
$git config --global user.name "user_name"
1.2.1 设置使用 git 时默认的邮箱名(一般设置为公司内的邮箱)
$git config --global user.email "user_name@126.com"
1.2.1 设置默认的 git diff 时比较工具
$git config --global diff.tool diff3
1.3 本地分支操作
1.3.1 查看所有本地分支
$git branch
1.3.2 切换到一个已经存在的本地分支
$git checkout local_branch_name
1.3.3 从本地分支切换到一个新建的分支 new_branch_name
$git checkout -b new_branch_name
1.3.4 合并 other_branch_name 名的分支到当前分支(不保留被合并分支的历史信息)
$git merge other_branch_name
#feature 分支合并到当前分支 develop:git merge feature # | <- develop -> | # | | # A.1 --> A.2 --> A.3 -- B.1 --> B.2 --> B.3 # | | # | <- feature -> |
1.3.5 合并 other_branch_name 名的分支到当前分支(保留被合并分支的历史信息)
$git merge –no-ff other_branch_name
#feature 分支合并到当前分支 develop:git merge –no-ff feature# | <- develop -> |# | |# A.1 --> A.2 --> A.3 ------------------------> C.1# | |# | --> B.1 --> B.2 --> B.3 -->|# | |# | <- feature -> |
1.3.6 删除本地分支 branch_name(非强制删除,分支未合并时,会提示)
$git branch -d branch_name
1.3.7 删除本地分支 branch_name (强行删除分支,不做任何提示,类似 rm -rf)
$git branch -D branch_name
1.4 更新当前分支
1.4.1 查看所有提交
$git log
1.4.2 展示好看一些的查询
$git log --pretty=format:"%h %s" --graph
1.4.3 查看 user_name 用户过去一周做过什么
$git log --author='user_name' --after={1.week.ago} --pretty=oneline --abbrev-commit
1.4.4 查看所有未被合并过的提交信息(假如该分支是从 master 创建的)
$git log --no-merges master..
1.4.5 查看当前分支名称
$git branch
1.4.6 查看当前分支的状态
#比 git status 更简洁化的一个命令 $git status -s
1.4.7 增加指定文件名 file_name 到待提交的 list 中
$git add file_name
1.4.8 增加所有未提交的文件 到待提交的 list 中
$git add .
1.4.8 增加指定类型 .txt 格式的到待 提交的 list 中。
$git add '*.txt'
1.4.9 让 git 不再 提交指定的文件 file_name
$git rm file_name
1.4.10 使用 git 默认的编辑器将待提交的 list 中文件提交
$git commit
1.4.11 通过命名行的模式将待提交的 list 中文件提交
$git commit -m 'your commit msg'
1.4.12 修改已经提交但是未 push 到远端的提交 msg
$git commit --amend
1.5 高级命令
1.5.1 回退到上个版本,只保留源码
$git reset
1.5.2 回退到上个版本,本地的源码也会变为上一个版本的内容
$git reset --head HEAD
1.5.3 当前分支情况下,回退到指定的历史
$git reset tag $git reset commit_hash
1.5.4 暂存当前的变更,不提交
$git stash
1.5.5 取出暂存的变更到当前分支
$git stash pop
1.5.6 撤销当前分支下对某个文件的变更
$git checkout file_name
1.6 比较变更
1.6.1 显示工作目录与索引区文件之间的差异
$git diff
1.6.2 显示工作目录与git仓库之间的差异
$git diff HEAD#比较上次提交 $git diff HEAD^#比较上2次提交 $git diff HEAD~2
1.6.3 当前分支与 other_branch_name 分支进行比较
$git diff other_branch_name
1.6.4 使用配置文件中的比较工具进行比较(和 git diff 类似)
$git difftool
1.6.5 查看当前分支与目标分支的文件变更
$git diff --no-commit-id --name-only --no-merges origin/master..
1.6.6 查看当前分支文件变更的状态
$git diff --stat
1.7 远程分支操作
1.7.1 查看本地仓库有哪些远程连接(带 url 地址)
#备注: 当 git clone 一个仓库的时候,会自动创建一个别名为 origin 的远程连接到 clone 的仓库。 $git remote -v
1.7.2 创建一个连接到远程仓库的连接(假如 origin 没有设置)
$git remote add remote_origin_name https://one_git_remote_url
1.7.3 当前分支 push 到 远端分支 - 1
#上传本地所有分支代码到远程对应的分支上 $git push
1.7.3 当前分支 push 到 远端分支 - 2
#当前分支与多个主机存在追踪关系,则可以使用 -u 选项指定一个默认主机,后面就可以不加任何参数使用 git push。 $git push -u orgin master
1.7.4 当前分支 push 到 远端分支 - 3
#上传本地当前分支代码到 master 分支 $git push origin master
1.7.4 获取远端对应分支更新到本地
$git pull
1.7.5 获取远端指定分支名 branch_name 到本地
$git pull origin branch_name
1.7.6 获取远端分支的更新历史 - 1
$git fetch
1.7.7 获取远端分支的更新历史 - 2
#假如远端分支有被删除,此命令也会把本地对应的分支删除。 $git fetch --prune
1.7.8 获取远端更新并合并到当前分支
#此组合命令,和 git pull 的作用一样的。#git fetch 获取远端分支到本地,不合并到当前分支。#尽量少用git pull,多用git fetch和merge。 $git fetch && git merge origin/remote_branch_name
1.7.9 查看远端所有分支
$git branch -a
2. 一些资料
2.1 git 命令在线学习
https://try.github.io
2.2 git 分支在线学习
http://learngitbranching.js.org/?NODEMO
2.3 《Pro Git》 在线免费书
2.3.1 英文原版
https://git-scm.com/book/en/v2
2.3.2 中文版
http://git.oschina.net/progit/
2.4 《Git 权威指南》 在线免费书
https://github.com/gotgit/gotgit/
3. git 历史查看工具
3.1 SourceTree
https://www.sourcetreeapp.com/
3.2 TortoiseGit
https://tortoisegit.org/
3.3 命令行下的 Git 浏览器
3.3.1 官网
https://jonas.github.io/tig/
3.3.2 安装
$sudo apt-get install tig or $brew install tig
3.4 gitk
http://gitk.sourceforge.net/
3.5 其他
https://git-scm.com/downloads/guis
4. 一些文件对比的工具
4.1 Meld
http://meldmerge.org/
4.2 opendiff
http://guides.macrumors.com/opendiff
4.3 diff3
https://en.wikipedia.org/wiki/Diff3
4.4 beyond compare
http://www.scootersoftware.com/
4.5 P4Merge
https://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools
4.6 其他(git 配置文件)
https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#External-Merge-and-Diff-Tools
5. git flow
5.1 git flow 模型
http://nvie.com/files/Git-branching-model.pdf
5.2 git flow on github
https://github.com/nvie/gitflow
5.3 基于git的源代码管理模型——git flow
http://www.ituring.com.cn/article/56870
6. 其他
6.1 命令行我自己常用的 git 历史查询的别名
6.1.1 git lg
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
6.1.2 git tlg
tlog = log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative
6.1.3 git plg
plog = log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'
6.1.4 git glg
glog = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
6.3 所有提交者的提交次数排行榜
rank = shortlog -sn --no-merges
6.3 没有被 merge 的删除的分支
bdm = "!git branch --merged | grep -v '*' | xargs -n 1 git branch -d"
6.4 彩蛋
6.4.1 彩蛋 - 1 (历史重演)
$git log --reverse -p
6.4.2 彩蛋 - 2(历史追溯)
$git show HEAD~1
参考文献
https://git-scm.com/dochttp://nvie.com/posts/a-successful-git-branching-model/https://github.com/gotgit/gotgit/https://longair.net/blog/2009/04/16/git-fetch-and-merge/http://stackoverflow.com/questions/292357/what-is-the-difference-between-git-pull-and-git-fetch