小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
配置
查看所有配置
git config --list
查看所有配置以及他们所在的文件
git config --list --show-origin
设置用户信息
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
如果使用了
--global
选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。 当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有--global
选项的命令来配置。
查看配置信息
git config <key>
例如查看用户名 git config user.name
帮助
以下三种方式等价
git help <verb>
git <verb> --help
man git-<verb>
假如我想查一下 config 的帮助文档
git config --help
或 git config -h
基础
获取Git 仓库
克隆现有仓库
git clone <url>
git clone -b <branchName> <url>
:从指定分支里面克隆
记录每次更新到仓库
检查当前文件状态 <工作区,暂存区>
git status
: 查看哪些文件处于什么状态
状态简览 git status -s
忽略文件
目录下创建 .gitignore
文件, 将需要忽略的文件写入
文件 .gitignore 的格式规范如下:
所有空行或者以 # 开头的行都会被 Git 忽略。
可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
匹配模式可以以(/)开头防止递归。
匹配模式可以以(/)结尾指定目录。
要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反
例子
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf
Tips: GitHub 有一个十分详细的针对数十种项目及语言的
.gitignore
文件列表, 你可以在 github.com/github/giti… 找到它。
对比
git diff
要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 git diff
:
若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --staged
命令。 这条命令将比对已暂存文件与最后一次提交的文件差异:
用 git diff --cached
查看已经暂存起来的变化
提交
git commit
git commit -am"提交说明"
修改提交信息
git commit --amend
移除文件
git rm
: 会从暂存区和工作目录都删除
git rm --cached <fileName>
: 只从暂存区移除,仍然保留在当前目录,不会继续被追踪
git rm
命令后面可以列出文件或者目录的名字
$ git rm log/\*.log
$ git rm \*~ # 该命令会删除所有名字以 ~ 结尾的文件。
移动文件
git mv file_from file_to
查看提交历史
查看提交历史
git log
: 列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。
不传入任何参数的默认情况下,
git log
会按时间先后顺序列出所有的提交,最近的更新排在最上面。
其中一个比较有用的选项是 -p
或 --patch
,它会显示每次提交所引入的差异(按 补丁 的格式输出)。 你也可以限制显示的日志条目数量,例如使用 -2
选项来只显示最近的两次提交:
git log -p -2
你想看到每次提交的简略统计信息,可以使用 --stat
选项:
git log --stat
格式化显示
git log --pretty=format:"%h - %an, %ar : %s"
选项 | 说明 |
---|---|
%H | 提交的完整哈希值 |
%h | 提交的简写哈希值 |
%T | 树的完整哈希值 |
%t | 树的简写哈希值 |
%P | 父提交的完整哈希值 |
%p | 父提交的简写哈希值 |
%an | 作者名字 |
%ae | 作者的电子邮件地址 |
%ad | 作者修订日期(可以用 --date=选项 来定制格式) |
%ar | 作者修订日期,按多久以前的方式显示 |
%cn | 提交者的名字 |
%ce | 提交者的电子邮件地址 |
%cd | 提交日期 |
%cr | 提交日期(距今多长时间) |
%s | 提交说明 |
选项 | 说明 |
---|---|
-p | 按补丁格式显示每个提交引入的差异。 |
--stat | 显示每次提交的文件修改统计信息。 |
--shortstat | 只显示 --stat 中最后的行数修改添加移除统计。 |
--name-only | 仅在提交信息后显示已修改的文件清单。 |
--name-status | 显示新增、修改、删除的文件清单。 |
--abbrev-commit | 仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。 |
--relative-date | 使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。 |
--graph | 在日志旁以 ASCII 图形显示分支与合并历史。 |
--pretty | 使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。 |
--oneline | --pretty=oneline --abbrev-commit 合用的简写。 |
撤销操作
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有
--amend
选项的提交命令来重新提交:
git commit --amend
取消暂存的文件
git reset HEAD CONTRIBUTING.md
撤消对文件的修改
git checkout -- CONTRIBUTING.md
远程仓库的使用
作为一个研发, 我改如何查看远程仓库?
git remote
: 查看远程仓库服务器的简写
git remote -v
: 显示需要读写远程仓库使用的git保存的简写以及对应的URL
作为一个研发,我想添加一个远程仓库
git remote add <shortname> <url>
作为一个研发,我想拉取我的远程仓库
git fetch <remote-name>
我想推送到远程仓库
git push origin master
我想查看某个远程仓库的更多信息
git remote show origin
作为一个研发 ,我想重命名或移除我的远程仓库
git remote rename <shortname> <shortnewname> # 重命名
git remote remove <shortname> # 移除
打标签
作为一个研发,我想查看我当前项目下有多少Tag
git tag
作为一个研发,我想查找与1.8.5相关的tag
git tag -l "v1.8.5*"
作为一个研发,我想创建一个标签
GIt支持两种标签: 轻量标签(lightweight)和附注标签(annotated)
轻量标签很像一个不会改变的分支——它只是某个特定提交的引用。
附注标签是存储在 Git 数据库中的一个完整对象, 它们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard (GPG)签名并验证。 通常会建议创建附注标签,这样你可以拥有以上所有信息。但是如果你只是想用一个临时的标签, 或者因为某些原因不想要保存这些信息,那么也可以用轻量标签。
git tag -a v1.4 -m "my versuib 1.4"
: 创建附注标签
git tag v1.4-1w
:创建轻量标签
git show v1.4
: 查看提交的信息
作为一个研发, 我想对过去的提交打标签
git tag -a v1.2 9fceeb02
作为一个研发, 我想删除一个标签
git tag -d v1.4-1w
: 删除本地的标签
git push origin :refs/tags/v1.4-1w
:删除远程的tag
或者
git push origin --delete <tagname>
作为一个研发, 我想检出一个标签
git checkout -b version2 v2.0.0
Git 别名
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
自己搞一个
git config --global alias.unstage 'reset HEAD --'
# 这会使下面的两个命令等价:
$ git unstage fileA
$ git reset HEAD -- fileA
分支模型: 必杀技特性
起步
HEAD 特殊指针:在 Git 中,它是一个指针,指向当前所在的本地分支
作为一个研发, 我想创建一个test分支
git branch test
作为一个研发, 我想切换到我新建的test分支
git checkout test
作为一个研发, 我想创建并切换到一个新分支
git checkout -b new-branch
# 解释: 上面的代码是下面两条命名的简写
git branch new-branch
git checkout new-branch
合并分支
git checkout master
git merge hotfix
> Fast-forward
# 删除hotfix分支
git checkout -d hotfix
解决冲突
为什么会出现冲突?
如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 如果你对 #53 问题的修改和有关
hotfix
分支的修改都涉及到同一个文件的同一处,在合并它们的时候就会产生合并冲突
首先, 使用 git status
查看查看因包含冲突而处于为合并状态的文件
然后使用编辑器修改, 然后 add , commit
分支管理
作为研发人员,我想看到我的项目的分支列表
git branch
作为研发人员, 我想看每一个分支的最后一次提交
git branch -v
作为研发人员,我想查看哪些分支已经合并到当前分支
git branch --merged
作为研发人员,我想查看哪些分支为合并到当前分支
git branch --no-merged
作为研发人员, 我想删除已经合并的分支
git branch --merged
testing
git branch -d testing
分支开发工作流
长期分支
主题分支(短期分支)
远程分支
作为研发人员, 我想显式地获得远程引用的完成列表
git ls-remote
作为研发人员,我想推送内容到远程分支
`git push origin master
作为研发人员,我想基于远程master分支创建一个主题分支并且切换到该分支
git checkout master
git pull origin master
git push origin HEAD:<branchname>
git checkout -b <branchname> <branchname/branchname>
变基
在 Git 中整合来自不同分支的修改主要有两种方法:
merge
以及rebase
。可以使用
rebase
命令将提交到某一分支上的所有修改都移至另一分支上
git checkout experiment
git rebase master
问题
git pull origin master 与 git pull origin/master的区别?
git pull origin master 与 git merge origin master 的区别?