记录平时对git的使用方法和技巧
创建本地git库
进入test.git
1
| git init --bare --shared
|
Window下进行跨平台的clone操作,下载链接前需要添加ssh
1 2
| > git remote add origin ssh://hostname@192.168.1.1:/test.git >
|
Linux:
1 2
| > git remote add origin hostname@192.168.1.1:/test.git >
|
创建分支
删除本地分支:
1
| git branch -d branch_name
|
切换分支
1
| git checkout branch_name
|
下载
下载较大工程:
depth用于指定克隆深度,为1即表示只克隆最近一次commit.
创建本地镜像仓库
1
| git clone --mirror <URL>
|
日志
日志规范
1 2 3 4 5
| <type>(<scope>): <subject> // 空一行 <body> // 空一行 <footer>
|
type
feat
:新功能(feature)fix
:修补bugdocs
:文档(documentation)style
: 格式(不影响代码运行的变动)refactor
:重构(即不是新增功能,也不是修改bug的代码变动)test
:增加测试chore
:构建过程或辅助工具的变动
scope
scope
用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。
subject
subject是 commit 目的的简短描述,不超过50个字符。填写要求:以动词开头
提交
更新
添加代码
1 2
| git add <filename> git add -A #添加所有修改
|
查看日志
1 2 3 4 5 6
| git log git log -n #查看前n条日志 git log --stat #查看日志的修改情况 git log -p #查看日志的具体修改 git log <filename/dirname> #查看该文件或目录的修改日志 git log -S [keyword] #在提交log中搜索关键词
|
tig
命令行下查看git历史提交记录的工具
回退
1
| git reset HEAD <filename> #将该文件从缓冲区撤回
|
查看远程库
添加远程库:
1
| git remote add <name> <url>
|
获取远程库中的最新版本,但与git pull 不同它不会merge
作用:可以对比远程库与当前本地的差异。
查看标签
作用:一个稳定的版本或者完成一个功能,为了发布或者保存而打的标签,主要是发布
切换标签
暂存当前改动
保存当前工作进度,会把暂存区和工作区的改动保存起来。执行完这个命令后,在运行git status命令,就会发现当前是一个干净的工作区,没有任何改动。使用git stash save ‘message…’可以添加一些注释
显示保存进度的列表。也就意味着,git stash命令可以多次执行。
1
| git stash pop [–index] [stash_id]
|
git stash pop 恢复最新的进度到工作区。git默认会把工作区和暂存区的改动都恢复到工作区。
1
| git stash apply [–index] [stash_id]
|
除了不删除恢复的进度之外,其余和git stash pop 命令一样。
1
| git stash drop [stash_id]
|
删除一个存储的进度。如果不指定stash_id,则默认删除最新的存储进度。
删除所有存储的进度。
恢复本地错误操作
查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)
1 2
| $git reflog -h usage: git reflog [ show | expire | delete ]
|
show
: 显示所有条目,缺省值expire
: 删除掉更老的reflog条目delete
: 从reflog中删除一个条目
模块管理
添加模块
1
| git submodule add projectB.git projectB
|
使用子模块
1 2
| git submodule init git submodule update
|
克隆项目后,默认子模块目录下无任何内容。需要在项目根目录执行此命令完成子模块的下载
在clone整个项目时添加递归参数:--recurse-submodules
删除子模块
rm -rf 子模块目录
删除子模块目录及源码vi .gitmodules
删除项目目录下.gitmodules文件中子模块相关条目vi .git/config
删除配置项中子模块相关条目rm .git/module/*
删除模块下的子模块目录,每个子模块对应一个目录,注意只删除对应的子模块目录即可
执行完成后,再执行添加子模块命令即可,如果仍然报错,执行如下:
commit统计
可以大致了解一下每个人对这个项目提交的commit数量和大致的贡献度
git获取最近一次提交的commit-id
获取完整commit id
获取short commit id
1
| git rev-parse --short HEAD
|
.git无法忽略target,或者不生效的情况
.gitignore
未生效,原因是.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交
1 2 3
| git rm -r --cached . git add . git commit -m 'update .gitignore'
|
强制更新代码
1
| git push origin master --force
|
- 错误:
1
| remote: error: denying non-fast-forward refs/heads/master (you should pull first)
|
该消息表示您不允许进行非快进推送, 远程存储库很可能在其配置中denyNonFastforwards = true
, 要更改设置,请执行git config receive.denynonfastforwards false
从git中打包代码
打包某一个分支
1
| git archive --format=tar.gz --output "output.tar.gz" master
|
打包某一个commit
1
| git archive --format=tar.gz --output "output.tar.gz" ac1c53d
|
打包某些目录
1
| git archive --format=tar.gz --output "output.tar.gz" master dir1 dir2
|
合并代码
合并指定分支到当前分支
选择一个commit,合并到当前分支
1
| git cherry-pick [branch_name]
|
查看信息
git服务器
1
| git daemon --export-all --verbose --base-path=.
|
--export-all
: “–base-path”下所有的repo仓库--base-path=.
: 定义为当前目录--verbose
: 任何操作都会给当前repo通知
svn仓库迁移至git
- svn的日志提交者与git相关用户进行绑定
1
| svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt
|
users.txt
的意义仅在于,将svn里面的提交者日志,注意是提交者,不是svn里面所有的用户信息都得关联
1 2
| aaa = git-aaa <aaa@xx.com> #用户名 邮件地址 bbb = git-bbb <bbb@xx.com>
|
1
| sudo apt install git-svn
|
1
| git svn clone <SVN_URL> --no-metadata --trunk="svnproject" --tags="tags" --branches="svnbranches" --authors-file=users.txt --preserve-empty-dirs project-dir
|
--no-metadata
: 阻止git导出SVN包含的一些无用信息--trunk="svnproject"
: 指定导出仓库的主干项目路径,默认trunk--tags="tags"
: 日志标记--branches="svnbranches"
: 指定svn的分支项目路径--authors-file=users.txt
: 指定svn帐号在git中的映射--preserve-empty-dirs
: 保留原SVN项目中的空目录
1
| git remote add origin <GIT-URL>
|
1
| git push origin master #--all
|
修改已提交的用户名和邮箱
1 2 3 4 5 6 7 8 9
| git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "old_email@email.com" ]; then GIT_AUTHOR_NAME="new_name"; GIT_AUTHOR_EMAIL="new_email@email.com"; git commit-tree "$@"; else git commit-tree "$@"; fi' HEAD
|
注:可以修改但是在github中还是可以看到之前的用户名,效果不太好
命令行工具——tig
- commit操作:
上/下键
可以选择log中的commit - 查看修改信息:
j/k
- 展示commit-id:
shift+x
删除已删除文件或目录的所以历史记录
删除文件
1
| git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch pom.xml' --prune-empty --tag-name-filter cat -- --all
|
删除目录
1
| git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch qemu/qemu-4.2.0/' --prune-empty --tag-name-filter cat -- --all
|
删除回收
1 2 3 4
| rm -rf .git/refs/original/ git reflog expire --expire=now --all git gc --prune=now git gc --aggressive --prune=now
|
错误处理
git clone
1 2 3
| fatal: The remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed
|
1
| git config --add core.compression -1
|
compression 是压缩的意思,从clone的终端输出就知道,服务器会压缩目标文件,然后传输到客户端,客户端再解压。取值为 [-1, 9],-1 以 zlib 为默认压缩库,0 表示不进行压缩,1..9 是压缩速度与最终获得文件大小的不同程度的权衡,数字越大,压缩越慢,当然得到的文件会越小。
DoTo
- Git 最佳实践:分支管理
- git-config(1) Manual Page