Git 指令记录
# 配置
git config
选项:
- --system:当前系统所有用户
- --global:当前用户所有仓库
- --list:查看所有配置
- 无:当前仓库
参数:
- 用户信息:user.name/user.email 配置姓名和邮箱
- 颜色:color 配置主题
如果只传参数名不传值, 表示查看该参数的配置信息.
# 帮助
帮助有两个命令:
git help <command>
git <command> --help
2
# 克隆
git clone
参数:
- 第一个参数是远程仓库的 url
- 第二个参数是本地仓库的自定义名称,可省略。
# 文件状态
git 中的文件状态有
- 未跟踪:之前的版本库或暂存区中没有该文件快照;
- 已暂存未修改:处于暂存区中;
- 已修改未暂存:跟踪过但本次修改未被暂存的文件;
- 已修改并暂存:处于暂存区中的被修改文件
状态间跳转如图所示:
# 查看状态
git status
选项:
- --short:简略版状态(1--??,2--A,3-- M,4--M ),M 出现在左侧表示被修改并暂存,出现在右侧表示已修改未暂存,同时出现 2 个 M 表示修改暂存后又被修改。
# 文件比较
git diff
用途:
- 获取没有被暂存的更新文件差异
- 获取没有被提交的更新文件差异
参数:
- 不加参数:处理用途一;
- --staged:处理用途二;
- --check:检测空白符错误。
# 暂存
git add
暂存指定文件或目录
选项:
- -i:进入交互式 add 界面,可以选择暂存某些文件。
# 提交到仓库
git commit
选项:
- 无:打开编辑器,如 vi,输入提交信息;
- -m:输入提交信息;
- -a: 将所有已修改未暂存的文件都提交, 省去了 git add. 相当于
git add .
.
# 删除文件
git rm
当删除一个文件后, 使用 git rm <文件名>
来将文件保存到暂存区. 也可以使用 git add
, 但是不建议, 语义不好.
选项:
- -f:强制删除已经修改过并暂存的文件。
- --cached:删除暂存区中的文件,但保留工作区中的该文件。
# 修改文件名
git mv <old name> <new name>
相当于:
mv <old file> <new file>
git rm <old file>
git add <new file>
2
3
运行 git status:
renamed: <old name> -> <new name>
# 查看日志
git log
选项:
- -p:显示每次提交的内容差异;
- -n:n 是一个数字,用来显示最后 n 条提交记录。如-2 表示显示最后两条记录;
- --stat:显示每次提交的简略信息,如被修改的文件数以及修改的具体行数。类似于:
README | 6 ++++++
Rakefile | 23 +++++++++++++++++++++++
lib/simplegit.rb | 25 +++++++++++++++++++++++++
3 files changed, 54 insertions(+)
2
3
4
- --pretty:这个选项有许多值让你选择来显示 log 的格式,如 oneline:
git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
2
3
4
log 将在一行中显示. 此外还有 short、full 和 fuller.
最重要的值应该是 format. 使用时格式如下:
git log --pretty=format:"%h - %an,%ar:%s"
命令中的占位符说明如下:
选项 | 说明 |
---|---|
%H | 提交对象(commit)的完整哈希字串 |
%h | 提交对象的简短哈希字串 |
%T | 树对象(tree)的完整哈希字串 |
%t | 树对象的简短哈希字串 |
%P | 父对象(parent)的完整哈希字串 |
%p | 父对象的简短哈希字串 |
%an | 作者(author)的名字 |
%ae | 作者的电子邮件地址 |
%ad | 作者修订日期(可以用 --date= 选项定制格式) |
%ar | 作者修订日期, 按多久以前的方式显示 |
%cn | 提交者(committer)的名字 |
%ce | 提交者的电子邮件地址 |
%cd | 提交日期 |
%cr | 提交日期, 按多久以前的方式显示 |
%s | 提交说明 |
- --graph:图形化提交历史,可以与--pretty 结合显示美观的 log。
- 其他常用格式选项:
选项 | 说明 |
---|---|
--stat | 显示每次更新的文件修改统计信息. |
--shortstat | 只显示 --stat 中最后的行数修改添加移除统计. |
--name-only | 仅在提交信息后显示已修改的文件清单. |
--name-status | 显示新增、修改、删除的文件清单. |
--abbrev-commit | 仅显示 SHA-1 的前几个字符, 而非所有的 40 个字符. |
--relative-date | 使用较短的相对时间显示(比如, "2 weeks ago"). |
限制输出选项:
选项|说明 --since|从某个时间起, 比如
--since=2.weeks
或--since=2008-01-15
. --until|到某个时间为止, 格式与--since 相似. --author|指定作者 --grep|搜索提交说明中的关键字 --all-match|相当于选项的与操作 -S|显示对某个关键字符串进行修改的提交--decorate:查看当前所有分支指向的 commit 对象。
# 撤销操作
git commit --amend
合并缓存区的修改和最近的一次 commit, 然后用生成的新的 commit 替换掉老的. 如果缓存区没有内容, 那么利用 amend 可以修改上一次 commit 的描述.
# Edit hello.py and main.py
git add hello.py
git commit
# Realize you forgot to add the changes from main.py
git add main.py
git commit --amend --no-edit
2
3
4
5
6
7
--no-edit 能让我们修复 commit, 而且不要修改 commit 描述.
# 远程仓库
git remote
选项:
- -v:显示远程仓库的 url;
- add <name> <url>:新增远程仓库。
# 远程仓库抓取
git fetch <remote-name>
将指定名称的远程仓库数据全部拉取到本地, 包括所有的分支.
git pull <remote-name> <branch-name>
将远程仓库的最新版本拉取到本地分支.
选项:
- --allow-unrelated-histories: 将两个没有相关历史的仓库合并. 比如你在 github 上建立了一个仓库, 编辑了一些内容. 然后又在本地有一个仓库, 编辑了一些内容. 当你 pull 时会被告知
fatal: refusing to merge unrelated histories
. 这时, 加上这个选项就可以了.
两者最主要的区别在于 fetch 不会自动合并, 而 pull 在拉取后会自动合并分支. 相比较而已, fetch 更安全一些, 可以避免冲突.
相当于 pull=fetch+merge.
# 推送
git push <remote-name> <branch-name>
推送本地提交到远程仓库. 如果有多人同时提交, 其中一些会被拒绝, 直到合并他人的推送.
选项:
- --delete:删除远程某个指定分支
# 查看远程信息
git remote show <remote-name> 可以获取本地当前工作分支和远程所有分支等信息.
# 本地重命名远程仓库
git rename <old-name> <new-name>
将本地的远程别名修改为新名.
# 删除本地克隆的仓库
git rm <remote-name>
# 标签
git tag
显示所有标签.
选项:
- -l:
git tag -l <正则匹配>
可以列出匹配到的所有 tag - -d:删除指定标签
# 打标签
标签一般默认打在最新的 commit 上.
# 附注标签
git tag -a <tag-name> -m <commit message> -s <PGP 私钥>
这种标签被称为附注标签, 拥有 tag 的所有信息. 如果使用 git show <tag-name>
命令可以看到该标签与相应提交的信息. 推荐使用这种标签.
# 轻量标签
轻量标签只需要提供标签名称即可:
git tag <tag-name>
# 指定 commit 打标签
git tag -a <tag-name> <SHA1 校验码>
# 推送标签
git push <remote-name> <tag-name> 或是 git push <remote-name> --tags
# 删除远程标签
git push <remote-name> :refs/tags/<tagname>
# 分支
首先要讲一下 Git 的文件对象:blob 对象、tree 对象和 commit 对象. 每个 blob 对象代表一个文件; tree 对象代表一个目录, 保存指向该目录下所有 blob 对象的指针; commit 对象是指向每次提交的对象, 而分支, 比如 master 就是一个指向最新 commit 对象的指针. 每一个 commit 对象保存一个指向上一个 commit 对象的指针, 类似于链表的头插法.
HEAD 指针是一个指向当前分支的指针, 切换分支就是修改 HEAD 的值.
# 创建分支
git branch <branch-name>
创建分支就是创建一个新的指针.
选项:
- 无参数:显示所有分支,当前分支前有一个*号;
- -v:显示所有分支及其最后一次 commit 记录;
- --merged:显示所有已合并到当前分支的子分支;
- --no-merged:显示所有未合并到当前分支的子分支;
- -d:删除某分支,该分支必须已经被合并到当前分支;
- -D:强制删除分支,即使该分支中有未合并的内容;
# 切换分支
git checkout <branch-name>
选项:
- -b: 创建并切换到新分支. 如果要基于一个远程分支来创建本地分支, 可以使用
git checkout -b <local-branch> <remote-name>/<branch-name>
命令. - --track:
git checkout --track <remote-name>/<branch-name>
追踪一个远程分支, 相当于-b 选项的简写. - --vv:列出所有分支与其跟踪的远程分支的落后或超前情况。
# 合并分支
git merge <branch-name>
流程:
git checkout -b dev
创建开发分支;修改需要处理的文件;
git commit -a
提交代码;git checkout master
切换到主分支;git merge dev
将 dev 分支合并到主分支.上面如果没有冲突, 将使用 fast forward 模式快速合并. 也就是说, 从 master 可以直接跳到 dev 分支时, 只需要修改 master 指针等于 dev 指针即可.
问题:
如果新建 dev 分支后,又从 master 中新建一个 issue 分支,并且先合并了 issue 分支。那么再合并 dev 分支时,将自动选择 master 和 dev 分支的最优共同祖先进行合并。这时将不能使用 fast forward 模式。
如果产生冲突:
- 先解决冲突: 使用 git mergetool 图形化工具或手动修改文件即可;
- 再提交代码.
# 变基
git rebase <base-branch> <to-merge-branch>
变基与合并的作用类似, 都是为了将两个分支的修改合并起来. 变基是以某一分支为基础, 将另一个分支的修改应用在这个分支上, 再在基础分支上执行 git merge
合并操作.
但是在提交历史中, 不像 merge 有分叉口, 相反, 会表现成一条直线.
选项:
- --continue: 如果变基过程中出现了冲突, 在解决冲突后调用
git rebase --continue
继续执行变基操作. - --skip:跳过冲突文件。
- --onto:
git rebase --onto master server client
表示取出 client 分支, 找出处于 client 分支和 server 分支的共同祖先【之后的修改】, 然后把它们在 master 分支上重放一遍. - -i:交互式变基,能够修改多个提交信息。
注意: 不要对别人仓库中也存在的分支进行变基操作. 所以, 建议的做法是: 只对尚未推送或未分享给别人的本地修改执行变基操作清理历史, 从不对已推送至别处的提交执行变基操作.
# 引用日志
git reflog
引用日志记录了最近几个月你的 HEAD 和分支引用所指向的历史. 每当你的 HEAD 所指向的位置发生了变化, Git 就会将这个信息存储到引用日志这个历史记录里.
# 分支间的提交差集
# 双点
git show <origin-branch>..<target-branch>
使用 ..
可以获取 <origin-branch>
上没有而 <target-branch>
上有的提交记录.
# 三点
git show <1st-branch>...<2nd-branch>
使用 ...
能够获取【两个分支的并集】与【两个分支的交集】的【差集】.
选项:
- --left-right:显示差集中每个元素所属分支方向。
# 多点
git show <target-branch> --not <origin-branch> 或 git show ^<origin-branch> <target-branch>
分支前使用 ^
或 --not
表示剔除 <origin-branch>
中有的分支. 与双点类似, 但是可以处理两个及多个分支情况.
# 存储工作区和暂存区文件
把本地的项目文件夹想象成一个工作区, 暂存区是一个盒子, Git 本地仓库是另一个盒子. 工作区和暂存区、仓库都是唯一的, 不管创建了多少个分支, 这三个区域都是共享的.
那么, 想象一下, 当前分支还没开发完成时, 需要新建一个分支去处理 bug. 但是你并不想提交当前尚未完成的文件. 那么, 就需要将当前的工作区和暂存区存储起来, 然后在切换分支修复 bug.
git stash
存储当前所有【已跟踪的】文件到一个栈中. 执行之后, 工作区会回到上一次提交后的状态. 相当于 git checkout HEAD
.
选项:
- --index:应用存储时,保留所有状态:暂存的仍暂存,修改的仍修改。如果不加这个参数,原先暂存的修改被存储后,再应用时将不在暂存区。
- --keep-index: 跟在
git stash
后面, 表示不要存储暂存区里的文件, 仅存储工作区文件. - --include-untracked:将未跟踪的文件也存储起来。
- -u:同上。
- --all:存储所有文件。
参数:
- list:查询存储栈中所有 stash;
- apply stash@{n}:应用栈中第 n 个存储,但应用后不会从栈中移除该存储。n 从 0 开始;
- drop stash@{n}:移除栈中指定存储;
- pop stash@{n}:应用某个存储并从栈中移除它。
- branch <branch-name>: 创建一个新分支,检出储藏工作时所在的提交,重新在那应用工作,然后在应用成功后扔掉储藏
# 清理文件
git clean
除了 rm 选项, 还可以使用 clean 命令来删除未跟踪的, 且不在【.gitignore】中的文件.
选项:
- -n:列出所有可以被清理的文件;
- -f:强制删除所有未跟踪文件;
- -d:可以删除未跟踪的目录;
git reset --hard
和 git clean -f
是一对好基友. 结合使用他们能让你的工作目录完全回退到最近一次 commit 的时候.
# 查找
git grep
查找正则匹配到的字符.
选项:
- -n:匹配到的字符串所在行号;
- --count:文件内符合匹配的个数;
# 重置
git reset
重置 HEAD 指针到某个历史 commit 对象.
选项:
- --soft:仅回退 HEAD 指针,不回退工作区和暂存区。
- --mixed:回退 HEAD 指针,并且将回退后的文件内容覆盖暂存区内容。
- --hard:回退 HEAD 指针,并且覆盖暂存区和工作区。
相比较与 checkout 而言, reset 会影响到工作区的文件, 而 checkout 会单独开一个分支, 将回退后的 HEAD 指针指向这个分支. 所以 checkout 会比较安全.
# 打包
git bundle
在断网情况下, 可以使用 bundle 命令将要 push 的文件都打包起来, 然后将该包用其他方式交给其他用户解压.
# Git 的优点
- 分布式:每个成员都可以在本地电脑上修改、提交代码;
- 无需互联网:即使没有网络,项目成员依然能够开发自己的功能。等到网络条件较好时再合并。
- 分支的创建与切换十分方便:Git 的文件都以对象保存,每次创建分支都是新建一个指向最新代码的指针,而切换分支也是改变 HEAD 指针的指向。相比较于 SVN 等版本控制系统每次创建分支都要复制所有代码,Git 实在是太方便了。
- 01
- 搭配 Jenkins 实现自动化打包微前端多个项目09-15
- 02
- 自动化打包微前端多个项目09-15
- 03
- el-upload 直传阿里 oss 并且显示自带进度条和视频回显封面图06-05