工作中用过的命令~
编辑状态维护
-
文件位置
-
文件状态
- Untracked: 本地新建的尚未被仓库跟踪的文件
- Unmodify: 仓库有并且本地没修改
- Modified: 仓库已有,本地修改
- Staged: 暂存,作为提交的范围
-
状态查看
- 放弃对文件的修改
重新从库里取出一份,即回到未修改状态
- 放弃最近提交的修改,回到指定提交的状态
不保留后续修改
1
| git reset --hard <commit>
|
后续修改保留,回到暂存状态
1
| git reset --soft <commit>
|
※ reset本质上是移动头指针指向历史的某个提交,并非删除修改
也可用来强制把本地分支和远程同步
1
| git reset --hard origin/<branch>
|
- 加入部分修改
一个文件修改了多处,但是不想一次全部提交
一次提交只解决一个问题更加清晰
执行后进行交互,会询问每个修改块是否暂存
- 删除未暂存文件
物理删除并且把改动加入暂存,会进入提交范围;不通过git直接删已跟踪的文件,不会进入暂存
- 删除已暂存文件
物理删除文件,同时解除已经暂存的改动
- 递归删除
接受正则表达式,但是要注意转义,不转义走shell模式,只会删除当前目录下,转义后作为一个pattern被git接受,可以递归
- 清除新增文件和目录,即未跟踪部分
选项f代表强制,选项d代表目录
选项n并不真正清空,可以告知要删哪些内容,起到确认作用,推荐先执行一遍
- 脱离仓库
不物理删除文件,但是放弃管理这个文件,即相当于删除远程仓库文件,恢复成未跟踪状态
比如.gitignore
遗漏的文件,已被仓库管理
1
| git mv <old-file> <new-file>
|
分支管理
1
| git checkout -b <branch>
|
1
| git checkout --track <remote>/<branch>
|
1
| git checkout -b <local-branch> <remote>/<remote-branch>
|
- 列出包含指定提交的分支
可用于验证cherry-pick结果
1
| git branch --contains <commit>
|
1
| git branch <branch> <commit>
|
强制删除
※ 删除分支其实只是删除了一个指针
1
| git branch --set-upstream <local-branch> <remote>:<remote-branch>
|
1
| git push <remote> --delete <remote-branch>
|
另一种语法,语义相当于把本地空白推送到远程
1
| git push <remote> :<branch>
|
提交
- 跳过暂存,提交所有已跟踪的文件
即新增文件不会被提交
撤销指定的提交
※ revert撤销不会修改已有历史,而是生成新的提交反作用抵消
- 少提交了文件
表面上是修改,实际上是用新提交替换,只适合改本地,不适合改远程仓库的提交
1 2
| git add <file> git commit --amend --no-edit
|
- 合并一段线性提交
指定最老的提交,在此提交之后的就是本次操作范围,执行后进入编辑模式
- pick:原样保留这个提交
- reword: 保留但是需要修改提交信息,即修改历史提交信息
- edit: 编辑提交
- squash: 合并这个提交
- fixup: 合并同时丢弃提交信息
- drop: 丢弃
- 合并过程中可能有冲突中间状态
- abort: 放弃本次的合并操作
- continue: 解决冲突后继续合并
- skip: 无视冲突继续合并
1 2 3
| git rebase --abort git rebase --continue git rebase --skip
|
其他变更操作也可以在这个模式里完成
- 改变提交顺序,直接文本编辑调整里面提交的顺序即可
- 拆分提交,选择
edit
,会回到暂存状态,结合reset
命令可以重新进行提交
※ 注意修改会导致新的提交,如果修改了中间一个提交,那么后续所有提交哈希值都会变化,即后续其实是新的提交,头指针指向新的,旧的被丢弃
- 从所有提交中删除文件
比如以前错误的加了某个文件,现在要在历史里也彻底清除这个文件
1
| git filter-branch --tree-filter 'rm -f xxx.txt' HEAD
|
- 将子目录设为根目录
改变目录后,跟这个目录无关的提交会被排除
1
| git filter-branch --subdirectory-filter <folder> HEAD
|
1 2 3 4 5 6 7 8 9
| git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "aaa@example.com" ]; then GIT_AUTHOR_NAME="AAA"; GIT_AUTHOR_EMAIL="bbb@example.com"; git commit-tree "$@"; else git commit-tree "$@"; fi' HEAD
|
分支合并
- 合并进来,但是不自动提交
默认行为是直接生成一个新提交代表合并后的结果
可以先合并过来,后期自己手动进行提交
1
| git merge --no-commit <branch>
|
- 局部合并
不合并整个分支,而是合并单独挑出的几个提交
1
| git cherry-pick <commit>
|
1
| git merge-base <branch1> <branch2>
|
- 改动融合到主分支之后
先找两个分支的公共祖先,然后将特性分支在主分支之后重演
1
| git rebase <base-branch> <feature-branch>
|
- 指定主干分支,将特性分支与参照分支公共祖先之后的部分接上
即比较两个分支,取出特性分支的独有部分,接到主干分支后面
1
| git rebase --onto <base-branch> <reference-branch> <feature-branch>
|
配置及管理
- 添加远程仓库信息
比如本地新建项目时,添加远程仓库信息
1
| git remote add <remote> <address>
|
- 列出综合后生效的配置信息,可加三类限制查看各级的配置
针对全局的设置在/etc/gitconfig
,使用--system
针对用户的设置在~/.gitconfig
,使用--global
针对项目的设置在.git/config
,使用--local
1
| git config --get user.name
|
- 设置信息,通常要设置用户名称
user.name
和邮箱user.email
1
| git config --global user.name <name>
|
1
| git config --global unset http.proxy
|
1
| git config --global credential.helper store
|
临时记住,默认15分钟
1
| git config --global credential.helper cache
|
1
| git config --global core.longpaths true
|
标记
- 显示对应提交内容
标签就视为提交的别名,直接show
本地远程数据同步
- 默认推送
推送到默认远程仓库,与当前分支名相同的分支
1
| git push <remote> <local-branch>:<remote-branch>
|
- 强行推送
适合本地已经和远程不兼容,以本地为准的情况
- 强行推送前检查
强行推送会强制覆盖,有可能丢失远程新加的内容
更安全的方式是检查,远程如果有新更新会拒绝
1
| git push --force-with-lease
|
- 更新本地的远程内容
取回远程分支的最新内容,不和本地合并
远程内容在本地以remote/branch
的形式存在
1
| git fetch <remote> <remote-branch>
|
- 拉取远程最新内容,并与当前合并
相当于fetch
和merge
结合
1
| git pull <remote> <remote-branch>
|
- 拉取远程最新内容,指定以衍和方式进行合并
相当于fetch
和rebase
结合
1
| git pull --rebase origin develop
|
检查
- 检查空白字符
默认配置检查末尾空格和空格后Tab字符
查找提交记录
1
| git log --author=<author>
|
- 显示时间范围
多种时间表达式
- n.days/weeks
- “yyyy-MM-dd”
1
| git log --since <datetime>
|
1
| git log --oneline --decorate --graph --all
|
1
| git log --graph --abbrev-commit --date=relative --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
|
1
| git log --grep <content>
|
- 查看在基准分支上新增的提交
即把原来分支上已有的提交排除掉
1
| git log <feature-branch> --not <main-branch>
|
或者用上三角表示排除
1
| git log ^<main-branch> <feature-branch>
|
或者使用双点操作符
1
| git log <main-branch>..<feature-branch>
|
1
| git log --left-right <branch1>...<branch2>
|
- 单行显示每个提交
单行显示并且使用短哈希码,相当于--pretty=oneline
和--abbrev-commit
的组合
限制行数范围
1
| git blame -L <from>,<to> <file>
|
同时检测原始出处,是否复制重命名而来
差异比较
1
| git diff --cached <file>
|
1
| git diff <branch1> <branch2> --stat
|
- 以公共祖先为基准的比较
特性分支原来从主干分支而来,后来主干有了新修改,那么直接和主干比较不合适
应该以当时的主干节点为基准,即公共祖先
1
| git diff <main-branch1>...<feature-branch2>
|
分支比较,显示具体增删行数和绝对路径文件名
1
| git diff <branch1> <branch2> --numstat
|
提交之间比较
1
| git diff <commit> <commit> -- <file>
|
分支比较 特定文件
1
| git diff <branch1> <branch2> -- <file>
|
※ 分支名就是指针,本质和提交等价
特定类型文件,只显示修改的文件, include
1
| git diff <branch1> <branch2> --diff-filter=M
|
小写表示不显示修改的文件, exclude
1
| git diff <branch1> <branch2> --diff-filter=m
|
查看上次提交
查看单次提交的改动
Shortlog
按作者统计提交列表
s
不显示具体提交信息只显示提交数量,n
按数量排序
Clone
下载后进入指定分支,默认是master
分支
1
| git clone <repo> -b <branch>
|
只下载指定分支最新的commit, 可以避免项目过大时全部下载慢
1
| git clone <repo> --b <branch> --single--branch --depth=1
|
指定远程名字,默认是origin
1
| git clone -o hostname <remote>
|
下载到指定目录
默认会在当前目录下新建项目名目录
1
| git clone <repo> <folder>
|
储藏
工作到一半,需要切换分支,但又不想提交这个未完成部分
储藏是堆栈结构,可以储藏多份,查看列表
以stash@{n}
区分多次储藏
重新应用储藏内容
删除储藏内容
应用最近一次储藏并删除
应用储藏后撤销
1
| git stash show -p <stash> | git apply -R
|
以应用储藏内容后的结果创建新分支
1
| git stash <stash> branch <branch>
|
引用日志
查看HEAD
的移动历史,仅本地保存
通过可以找出已经不在历史中的游离的提交,比如本地不小心reset后退,可以通过reflog查找先前的提交,再恢复回去
引用作为一道安全屏障前提是本地要有提交,并且没超过90天的过期期限
查看引用日志详细信息
子模块
将一个仓库作为子模块,放在指定文件夹下
执行后会产生.gitmodules
文件记录子模块地址
而文件夹作为一个特殊的链接,指向了子模块项目的一个提交
1
| git submodule add <repo> <folder>
|
连同子模块下载,不加参数的话子模块将是空的
1
| git clone --recurse-submodules <repo>
|
更新主项目时只更新了子模块指针,但是子模块代码没有同时更新
忽略文件
.gitignore
模板
https://github.com/github/gitignore
检查哪一行配置造成了文件忽略
文件入库,但是忽略本地修改
比如库里有标准配置,每个开发有自己配置,不提交
1 2
| git update-index --assume-unchanged <file> git update-index --no-assume-unchanged <file>
|
显示被忽略文件列表
1
| git ls-files -v | grep ^[a-z]
|
强制加入被忽略文件
git是不跟踪文件夹的,如果文件夹为空,无法提交到远端
解决方式是在文件夹下建立.gitkeep
文件
图形工具
提交历史
解决冲突
kdiff3配置
1 2 3
| git config --global --add diff.guitool kdiff3 git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe" git config --global --add difftool.kdiff3.trustExitCode false
|
一次打开所有差异文件
1
| git difftool --dir-diff <commit> <commit>
|
元数据查看
SSH配置
生成key
1
| ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
启动SSH代理
把生成的key加入
复制生成的公钥key,粘贴进git网站配置
1
| clip < ~/.ssh/id_rsa.pub
|
测试连接