Git命令
基础
初始化仓库
初始化本地仓库:
git init初始化默认分支名为master, 可以通过--initial-branch参数更改:
git init --initial-branch=分支名克隆远程仓库
git clone 仓库地址
例:
git clone https://gitee.com/eTank/MES-QZ.git会自动在当前目录新建项目同名文件夹,如MES-QZ
若出现用户名密码输入框,输入远程仓库的用户名密码。
查看状态
git status暂存
修改代码后,将改动文件添加到暂存区:
git add 文件名或添加所有改动文件到暂存区:
git add .取消暂存
取消暂存,退回到工作区:
git restore --staged 文件名取消改动,退回到改动前状态:
git restore 文件名删除文件
删除后改动会直接被添加到暂存区:
git rm 文件名删除后并取消跟踪:
#删除跟踪,并保留本地文件
git rm --cached 文件名
#删除跟踪,并删除本地文件
git rm --f 文件名删除跟踪后的文件在工作区中还是会出现(如git status),想让Git完全忽略此文件,可以使用.gitignore文件。在根目录下创建.gitignore文件,每一行为一个规则,例:
# 过滤整个 template 文件夹
/template/
# 过滤所有.zip文件
*.zip
# 过滤某个具体文件
/template/readme.txt在前面加个!表示需要添加到仓库中的文件,如:
#只需要管理 template 下的 config.txt 文件,其它文件都不需要跟踪
/template/
!/template/config.txt如果你不慎在创建
.gitignore文件之前就push了项目,那么即使你在.gitignore文件中写入新的过滤规则,这些规则也不会起作用,Git仍然会对所有文件进行版本管理。
提交
提交并备注提交信息:
git commit -m "备注或说明"
#暂存并提交(已经跟踪的文件)
git commit -am "备注或说明"查看提交记录
git log如果记录过多,则按Page Up、Page Down、↓、↑来控制显示,按q退出。
常用参数:
--stat:显示每次更新的修改文件的统计信息,每个提交都列出了修改过的文件,以及其中添加和移除的行数,并在最后列出所有增减行数小计。
-p:显示每个更新间的diff差异,比--stat信息更全。
--shortstat:只显示--stat中最后的行数添加修改删除统计
--name-status:显示新增、修改和删除的文件清单
--graph:显示ASCII图形表示的分支合并历史
--abbrev-commit:仅显示SHA-1的前几个字符
--oneline:一行显示,只显示SHA-1的前几个字符和提交说明
-n:显示前n条
--after=:指定日期之后的记录,如git log --after="2010-10-1",还可以用相对时间,比如"1 week ago"和"yesterday"
--before=:指定日期之前的记录,同上
--author=:指定提交者的记录,模糊匹配。包含了提交者的名字和email,可用正则。
--grep=:指定描述的记录,模糊匹配
--(空格):指定文件的记录,如:git log -- foo.js bar.js,如果后面的文件路径不会和某个branch产生混淆,可以省略--,如git log foo.js
分支名 --:查看某分支的记录,如 git log master --,如果分支名与文件名相同,系统会提示错 误,可通过--选项来指定给定的参数是分支名还是文件名。比如:在当前分支中有一个名为v1的文件,同时还存在一个名为v1的分支:
`git log v1 --` 此时的v1代表的是分支名字
`git log -- v1` 此时的v1代表的是名为v1的文件
`git log v1 -- v1` 代表v1分支下的v1文件
--no-merges:过滤掉merge commit。默认情况下会输出merge commit
--merges:只显示merge commit
git log <since>..<until>:按范围查看提交。比如:git log master..feature,表示包含了在feature有而在master没有的所有提交,同样,如果是feature..master则表示包含所有master有但是feature没有的提交。如果三个点,表示或的意思,如:git log master...test, 表示查询master或test分支中的提交记录。
git log tag名: 以标签查询提交。如:git log v1.0是查询v1.0之前的提交。加两个点git log v1.0.. 是查询从v1.0以后的提交历史记录(不包含v1.0)
一些alias:
git config --global alias.lm "log --no-merges --color --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit"
git config --global alias.lms "log --no-merges --color --stat --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit"
git config --global alias.ls "log --no-merges --color --graph --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit"
git config --global alias.lss "log --no-merges --color --stat --graph --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Cblue %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit"查找提交
有时程序出现某些bug,可能需要知道到底是哪次提交造成了错误?这次提交都改动了什么造成bug?这个时候就可以使用bisect命令。它的原理是按照二分法不断缩小定位。首先给出查找范围,然后确定问题出在前半部分,还是后半部分,不断执行这个过程,直到范围缩小到某一次代码提交。
先通过log命令查看提交日志,然后用bisect start确定范围:
git bisect start [终点] [起点]
# 例:
git bisect start HEAD C1执行后代码库会切换到这个范围间正中的那次提交。通过good和bad 来确定当前代码是否符合查找要求:
git bisect good
# 或:
git bisect bad接着代码库会根据命令继续切换到下一个位置。不断重复此过程,知道找到最终的提交,这时会输出:
xxxxx is the first bad commit这时就可以检查代码找到问题。
最后可以用reset回到最近的提交:
git bisect reset撤销提交
撤销提交可以使用reset和revert,分别适用于本地和远程仓库。
使用reset撤销后,撤销的提交便不存在了,就和没有提交过一样,有点像“时间倒流”。
git reset [--soft | --mixed | --hard] [HEAD]reset有三种模式:
hard: 退回并撤销所有未提交的修改内容soft: 退回到暂存区mixed(默认): 退回到工作区
例:
git reset HEAD^ # 回退所有内容到上一个提交
git reset HEAD^ hello.js # 回退 hello.js 文件的版本到上一个提交
git reset --soft 052e # 回退到指定提交
git reset –hard HEAD~3 # 回退上上上一个提交
git reset --hard origin/master # 将本地的状态回退到和远程的一样reset对远程仓库是无效的,若要同步你的撤销,则需要使用revert。
revert会产生一次提交,这次提交的更改就是撤销所作更改,这样便可将更改同步到远程。
例:撤销最近一次提交
git revert HEADHEAD 说明
HEAD 是一个对当前检出记录的符号引用 —— 也就是指向当前你正在工作的位置。 HEAD 总是指向当前分支上最近一次提交记录,通常情况下是指向分支名的。
如果想看 HEAD 指向,可以通过 cat .git/HEAD 查看。 如果 HEAD 指向的是一个引用,还可以用 git symbolic-ref HEAD 查看它的指向。
使用:
HEAD表示当前版本HEAD^上一个版本HEAD^^上上一个版本HEAD^^^上上上一个版本- 以此类推...
也可以使用~数字指定返回几步:
HEAD~0表示当前版本HEAD~1上一个版本HEAD^2上上一个版本HEAD^3上上上一个版本- 以此类推...
^后也可以跟数字,但和~不同,它是用于指定合并提交记录的某个父提交(Git默认选择合并提交的“第一个”父提交。第一个父提交记录是指合并提交记录正上方的那个提交记录。)
#检出到 master 的第一个父节点,等同于 HEAD^1
git checkout master^
#检出到 master 的第二个父节点
git checkout master^2^和~还支持链式操作:
git checkout HEAD~^2~2
# 等同于:
git checkout HEAD~
git checkout HEAD^2
git checkout HEAD~2存储
存储是将当前的改动保存起来,并还原到改动前的状态。
新建存储:
git stash -m "备注或说明"
# 包含未跟踪的文件
git stash -u -m "备注或说明"查看储存列表:
git stash list查看存储详情:
git stash show 存储索引应用存储:
git stash apply 存储索引
# apply 后不会删除存储恢复最近的存储:
git stash pop
# pop 会应用并删除存储删除存储:
git stash drop 存储索引清空存储:
git stash clear添加远程仓库
先在仓库官网新建项目或仓库,获得仓库地址。
git remote add 仓库名 仓库地址
例:
git remote add origin https://gitee.com/eTank/MES-QZ.git查看远程仓库信息
git remote -v查看远程/本地分支的对应关系
git remote show origin拉取
将远程仓库的更新信息全部取回本地(是将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态,它不会更新你的本地分支,也不会修改你磁盘上的文件):
git fetch origin当远程分支有新的提交时,使用fetch之后,本地分支并不会随之更新。可以像合并本地分支一样合并远程分支来更新,如:
git merge origin/master
#或
git cherry-pick origin/master
#或
git rebase origin/master由于先抓更新再合并到本地分支这个流程很常用,因此Git提供了pull命令来完成这两个操作:
git pull 远程仓库名 分支名例:
#拉取默认远程仓库的默认分支并合并到当前分支
git pull
#拉取远程 origin 的 master 分支,合并到本地的 dev 分支
git pull origin master:dev
#如果远程分支是与当前分支合并,则冒号后面的部分可以省略:
git pull origin master推送
推送到远程仓库:
git push
#或
git push origin 分支名若出现用户名密码输入框,输入远程仓库的用户名密码。
移动提交记录
cherry-pick可以将一些提交复制到当前位置(HEAD)下。
git cherry-pick <提交1> <提交2> ... <提交n>
#将 c1 和 c2 复制到当前位置:
git cherry-pick C1 C2提示
cherry-pick可以将提交树上任何地方的提交记录取过来按输入顺序追加到HEAD上(只要不是HEAD上游的提交就没问题)。
交互式 rebase
cherry-pick需要知道提交记录的哈希值,但是在你不清楚提交记录的哈希值时,可以利用交互式rebase从一系列的提交记录中找到想要的记录。
交互式rebase 是指使用带参数 --interactive 的 rebase 命令, 简写为 -i。
#复制最近4次提交记录
git rebase -i HEAD~4git 会打开文本编辑器并列出将要被复制到目标分支的提交记录,同时会显示每个提交记录的哈希值和提交说明,可以调整提交的顺序、删除不想要的提交、合并提交等。
分支
查看分支
查看本地分支:
git branch查看远程分支:
git branch -r查看所有分支,包括本地和远程:
git branch -a创建分⽀
git branch 新分支名 源分支名
#基于B1创建分支B2
git branch B2 B1
#不写源分支就基于当前分支创建
git branch B2基于当前分支创建新分支并切换:
#创建后会自动切换到新分支B2
git checkout -b B2切换分支
git checkout 分支名删除分支
git branch -d 分⽀名删除远程分支
git push origin -d 分支名合并分支
merge
合并目标分支到当前分支:
git merge 目标分支rebase
和marge不同的是合并后不会增加父节点:它会将源分支的提交记录,“复制”到目标分支下。它的优势是可以创造更线性的提交历史。
#默认当前分支为源分支
git rebase 目标分支也可以指定两个分支名,分别表示目标分支、源分支:
git rebase 目标分支 源分支
# 等同于
git checkout 源分支
git rebase 目标分支若出现冲突,git 会停止 rebase 并会让你去解决冲突。在解决完冲突后,用 git add 命令去更新这些内容。注意,你无需执行 git commit提交更新,只要用--continue参数继续执行rebase,git会继续剩下的工作:
git rebase --continue在任何时候,我们都可以用 --abort 参数来终止 rebase 的行动,并且分支会回到 rebase 开始前的状态:
git rebase --abort删除远程不存在的分支
注:删除的是本地分支,即:删除已经不存在的远程分支对应的本地分支
git remote prune origin移动分支
git branch -f 分支名 提交
#例:将 master 分支强制指向 HEAD 的第 3 级父提交
git branch -f master HEAD^3标签
标签(tag)可以(在某种程度上 —— 因为标签可以被删除后重新在另外一个位置创建同名的标签)永久地将某个特定的提交命名为里程碑,然后就可以像分支一样引用了,就像代码库的一个“锚点”。更难得的是,它们并不会随着新的提交而移动。你也不能检出到某个标签上面进行修改提交,它就像是提交树上的一个锚点,标识了某个特定的位置。
标签有两种:
轻量标签(lightweight): 简单标签,只是某个提交的引用,可以理解为是一个提交的别名附注标签(annotated):是存储在git仓库中的一个完整对象,包含打标签者的名字、电子邮件地址、日期时间 以及其他的标签信息。它是可以被校验的,可以使用 GNU Privacy Guard (GPG) 签名并验证
查看标签
#查看所有标签
git tag
#筛选xxx开头的标签(*为通配符)
git tag -l "xxx*"
#查看标签v1.0的提交信息
git show v1.0新建标签
创建轻量标签:git tag 标签名 提交名
#给提交 C1 打上标签 v1.0
git tag v1.0 C1
#不指定提交则指向HEAD位置
git tag v1.0创建附注标签:git tag -a 标签名称 提交版本号 -m 附注信息
#给提交 C1 打上标签 v1.0
git tag -a v1.0 C1 -m "附注信息"
#不指定提交则指向HEAD位置
git tag -a v1.0 -m "附注信息"推送到远程仓库:
#将标签v1.0上传到远程仓库origin
git push origin v1.0
#将所有不在远程仓库origin中的标签上传
git push origin --tags删除标签
git tag -d 标签名称删除远程标签:
#删除远程仓库origin的v1.0标签
git push origin :refs/tags/v1.0
#或:
git push origin --delete v1.0签出标签
签出标签一般是为了要在此标签基础上进行其他的开发或操作,因而应以标签为基础版本,新建一个分支,再继续其他的操作:
#在标签v0.1基础上新建分支B1
git checkout -b B1 v0.1查看最近标签
describe 命令用以显示离当前位置最近的标签:
git describe [ref]ref是任何能被Git识别成提交记录的引用,如果没有指定,默认为当前检出位置(HEAD)。
git describe master
# 输出:
v1.0-2-g5abb3fe输出的格式为:<tag>-<numCommits>-g<hash>
tag表示的是离ref最近的标签numCommits表示这个ref与tag相差有多少个提交记录hash表示的是你所给定的提交记录哈希值前几位
当指定的提交记录上就有某个标签时,则只输出标签名称。
describe默认只显示附注标签,要显示所有的标签,用--tags参数:
git describe --tags