Git 使用说明
Git 是一个分布式版本控制系统。
基本用法
环境
配置
# 设置用户信息
$ git config --global user.name "Name"
$ git config --global user.email "email@example.com"
配置Git信息,设置身份标识user.name
和user.email
用于仓库管理
使用不同的参数和配置文件的作用域,可用不同的身份管理各仓库,包括--system
, --global
, --local
, --worktree
和 --file <filename>
:
系统配置:参数--system
,包含系统上每一个用户及他们仓库的通用配置 (/etc/gitconfig)
全局配置:参数--global
,当前用户信息目录中(~/.gitconfig 或 $HOME/.config/git/config )
本地配置:参数--local
,当前使用仓库中(.git/config)
帮助
$ git --version
# git help [COMMAND|GUIDE]
$ git help
$ git help init
忽略
无需纳入 Git 的管理的文件添加到.gitignore
文件
# 忽略所有的 .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
格式规范如下:
- 所有空行或者以
#
开头的行都会被 Git 忽略。 - 可以使用标准的 glob 模式,即简化了的正则表达式匹配,它会递归地应用在整个工作区中。
- 匹配模式可以以(
/
)开头防止递归。 - 匹配模式可以以(
/
)结尾指定目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(
!
)取反。
原理
文件有三种状态:已修改(modified) 、已暂存(staged)、已提交(committed)。
对应三各区域:工作区、暂存区以及仓库(Git 目录)。
Git 仓库中有三种对象:一个提交对象(包含着指向树对象的指针和所有提交信息)、一个树对象(记录着目录结构和 blob 对象索引)、多个 blob 对象(保存着文件快照)。分支、标签等仅仅是指向提交对象的指针。
基本的 Git 工作流程如下:
- 在工作区中修改文件。
- 将你想要下次提交的更改选择性地暂存,这样只会将更改的部分添加到暂存区。
- 提交更新,找到暂存区的文件,将快照永久性存储到 Git 目录。
本地仓库
创建
# 把当前目录变成Git可以管理的仓库
# git init [directory]
$ git init
# directory,为初始化的仓库目录,如果有则初始化,如果没有则创建后初始化
$ git init project
初始化后,当前目录变成Git可以管理的仓库(repository ),会在当前目录下创建.git
隐藏目录作为版本库。
版本库最重要的是称为stage(或者index)的暂存区
和初始自动创建的第一个分支master
,以及工作指针HEAD
。仓库内版本库外为工作区
。
提交
# 把文件修改添加到暂存区,-A所有,-v详情,f强制
# git add [-A | --all] [-v | --verbose] [-f | --force] [<pathspec>…]
$ git add readme.txt LICENSE
$ git add .
# 把暂存区的所有内容生成commit,提交到当前分支
# git commit [--amend] -m <msg>
$ git commit -m "commit"
# --amend,在上一次提交的commit上追加修改(包括提交信息),生成一个新的commit,提交到当前分支
$ git commit --amend -m "amend"
Git是对工作区的修改生成commit,进行版本管理。
查看
# 显示工作区和暂存区与当前HEAD提交之间的差异,-s短格式,-v详情
# git status [<options>…] [--] [<pathspec>…]
$ git status
# 显示工作区相对暂存区所做的修改
# git diff [<options>] [--] [<path>…]
$ git diff
# 显示工作区相对版本库所做的修改
# git diff [<options>] [<commit>] [--] [<path>…]
$ git diff HEAD
# 显示暂存区相对版本库的修改,默认为HEAD提交
# git diff [<options>] --cached [<commit>] [--] [<path>…]
$ git diff --cached
# 从最近到最远显示提交日志
# git log [<options>] [<revision range>] [[--] <path>…]
$ git log
# options: --pretty[=<format>],指定展示提交历史方式
$ git log --pretty=oneline
# options: --since=<date>,最近两周内的提交
$ git log --since=2.weeks
# 管理reflog信息,可以查找看不到的commit
$ git reflog
# 显示标签信息
# git show [<options>] [<object>…]
$ git show a36f26d
修改
# 撤销工作区修改,与暂存区一致,暂存区空即与版本库一致。-- 建议携带,防止与切换分支命令冲突。
# git checkout [--] <pathspec>…
$ git checkout -- readme.txt
$ git checkout .
# 回退工作区和暂存区,与提交一致,默认HEAD提交。~ 代表上一个提交。
# git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
# 工作区不变,只清理暂存区
$ git reset HEAD~
# --hard,清理暂存区和工作区
$ git reset --hard HEAD~3
# --keep,保持暂存区和工作区不变
$ git reset --keep
# 从工作区和暂存区删除文件
# git rm [--cached] [--] [<pathspec>…]
$ git rm readme.txt
# --cached,从暂存区移除,提交后可移除仓库内文件的版本管理,工作区内文件无影响
$ git rm --cached -- readme.txt
# 移动或改名
# git mv [-v] [-f] [-n] [-k] <source> <destination>
$ git mv readme.txt LICENSE
远程仓库
SSH Key
在用户主目录下,查找.ssh
目录及其下的id_rsa
和id_rsa.pub
两个文件。如没有使用以下命令创建,一路回车,使用默认值即可。
$ ssh-keygen -t rsa -C "email@example.com"
id_rsa
是私钥,不能泄露出去。id_rsa.pub
是公钥,配置到远程仓库,即可使用ssh
协议。此外还可以使用https
等其他协议。
创建
# 克隆远程仓库,-b指定分支
# git clone [-b <name>] [--] <repository> [<directory>]
$ git clone git@github.com:username/project.git
# 增加一个新的远程仓库关联
# git remote add <name> <url>
$ git remote add origin git@github.com:username/project.git
# 移除远程仓库
# git remote remove <name>
$ git remote remove origin
# 显示远程仓库,-v详细
# git remote [-v | --verbose]
$ git remote
# 显示指定远程仓库的信息
# git remote [-v | --verbose] show [-n] <name>…
$ git remote show origin
第一次连接GitHub时,会提示警告,需要你确认GitHub的Key的指纹信息,yes
即可。
origin
是远程仓库的默认名称。
推送
# 推送修改到远程仓库,--all所有分支,--tags标签,-f强制,-d删除
# git push [--all | --mirror | --tags] [-f | --force] [-d | --delete] [-u | --set-upstream] [<repository> [<refspec>…]]
$ git push origin dev
# <refspec>…,格式为:<src>:<dst>,<src>代表指向的提交,:<dst>可以省略,代表同名分支
$ git push origin dev:master
$ git push origin HEAD:dev
# -u,建立上游关联并推送修改
$ git push -u origin master
本地仓库分支必须与远程仓库分支建立关联,才能推送本地提交到远程仓库,与远程分支交互。
获取
# 从另一个仓库下载对象和引用,-v详情
# git fetch [<options>] [<repository> [<refspec>…]]
$ git fetch
# 下载所有
# git fetch --all [<options>]
$ git fetch --all
# 从一个分支拉取并合入提交,默认为关联分支
# git pull [<options>] [<repository> [<refspec>…]]
$ git pull
# 发生了冲突,回退
$ git reset --merge
git pull
等价于git fetch
加git merge FETCH_HEAD
分支
查看
# 查看本地分支, -v详情、-vv详情和上流分支、-r远程分支、-a所有分支、--list列表
# git branch [-v [--abbrev=<length> | --no-abbrev]] [<commit>]] [(-r | --remotes) | (-a | --all)]
$ git branch -a
# 显示分支合并图
$ git log --graph --pretty=oneline --abbrev-commit
当前分支前面会标一个*
号。
创建
# 创建本地分支,start-point指定分支或提交,--track与远程分支建立关联
# git branch [--track | --no-track] [-f] <branchname> [<start-point>]
$ git branch dev
$ git branch --track dev origin/master
# 切换分支,-c创建并切换,start-point指定分支或提交
# git switch [<options>] (-c|-C) <new-branch> [<start-point>]
$ git switch dev
$ git switch -c dev
# 切换分支,-b创建并切换,start-point指定分支或提交
# git checkout [-b|-B|--orphan] <new_branch> [<start_point>]
$ git checkout dev
$ git checkout -b dev
# -,上一个分支
$ git checkout -
git-switch
是2.23版本发布的新命令。
删除
# 删除分支,-r远程分支,-D强制删除
# git branch (-d | -D) [-r] <branchname>…
$ git branch -d dev
$ git branch -D dev
# 删除远程分支
$ git branch -dr origin/dev
$ git push origin --delete dev
关联
# 在现有分支与指定分支之间建立关联
# git branch (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
$ git branch -u remotes/origin/master
$ git branch --set-upstream-to=origin/dev dev
# 取消分支的关联
# git branch --unset-upstream [<branchname>]
$ git branch --unset-upstream dev
origin/master
等价于remotes/origin/master
,代表远程服务器origin
的master
分支。
合并
# 合并指定分支到当前分支
# git merge [-m <msg>] [<commit>…]
$ git merge dev
# 禁用 Fast forward 模式,在当前分支合并重新生成新的提交
$ git merge --no-ff -m "merge with no-ff" dev
# 图形化工具处理合并冲突
# git mergetool [--tool=<tool>] [-y | --[no-]prompt] [<file>…]
$ git mergetool
# 抛弃合并过程并且尝试重建合并前的状态
# git merge (--continue | --abort | --quit)
$ git merge --abort
# 合并特定提交到当前分支
# git cherry-pick <commit>…
$ git cherry-pick a36f26d
# 变基,在新的提交基础上,重新生成本地提交
git rebase [<upstream> [<branch>]]
$ git rebase
无冲突,Git会用Fast forward
模式,直接把当前分支指向指定分支最新提交。
有冲突,Git会用<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容,修改后重新提交。
储藏
# 保存当前工作区和暂存区
# git stash [push [--] [<pathspec>…]]
$ git stash
# 查看保存列表
# git stash list [<options>]
$ git stash list
# 恢复工作内容,并删除保存信息
# git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
$ git stash pop
# apply,只恢复工作内容不删除保存信息
$ git stash apply stash@{0}
# 删除保存信息
# git stash drop [-q|--quiet] [<stash>]
$ git stash drop
保存当前工作后处理其他工作,结束其他工作后恢复工作内容。
标签
查看
# 显示标签
$ git tag
# 显示标签信息
# git show [<options>] [<object>…]
$ git show v1.0
创建
# 创建本地标签,-a标签名,-m标签注释
# git tag [-a | -s | -u <keyid>] [-f] [-m <msg> | -F <file>] [-e] <tagname> [<commit> | <object>]
# 轻量标签
$ git tag v1.0
$ git tag v1.0 a36f26d
# 附注标签
$ git tag -a v1.0 -m "version 1.0" a36f26d
# 删除本地标签
# git tag -d <tagname>…
$ git tag -d v1.0
推送
# 推送标签
$ git push origin v1.0
# 推送所有标签
$ git push origin --tags
# 推送删除远程标签
$ git push origin :refs/tags/v1.0
$ git push origin --delete tagname