目录 start
目录 end
|2018-07-17| 码云 | CSDN | OSChina
Git基础
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. --git-scm.com
版本控制系统(VCS)
Git常用命令
Git官网中文教程
git-tips学习Git的仓库
git权威指南的组织完整书籍,以及相关测试题
Tips
git ls-files
列出文件列表git ls-files | xargs wc -l
计算文件中程序代码行数 通过工具:xargs
wc
(中文命名的文件编码问题无法计算行数)git ls-files | xargs cat | wc -l
计算行数总和
- 二分查找捉虫记
通过分析提交历史查到哪次提交引起的Bug然后检出,修复
清理仓库
参考博客1 彻底删除 | 参考博客2 彻底删除 | 参考博客3 删除大文件
参考博客4 减小磁盘占用
删除仓库的某个时间点之前的历史记录,减少.git 目录大小
如何清洗 Git Repo 代码仓库
- 因为删除的文件是会留在仓库,为了以后恢复用,但是这样的话仓库就会越来越大了
强制删除
,并且从git索引中也去掉,相当于彻底删除
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch 文件的路径' --prune-empty --tag-name-filter cat -- --all
git push origin --force --all
git push origin --force --tags
- 使用
git rebase
来更新分支,而不是git merge
不然文件又回来了
- 然而这个笔记仓库,之前将图片文件也放在了仓库里,删除之前也改动了名字,现在根本找不到文件了,如果要减小仓库大小只能重建了
- 猜测他的文件都在
.git/objects/pack/
里留有备份 - 最简单的减小传输的大小的是clone时加上
--depth 1
对之前的分支延迟下载
- 猜测他的文件都在
gc
只能压缩一部分空间
git gc -h
:
--aggressive
默认使用较快速的方式检查文档库,并完成清理,当需要比较久的时间,偶尔使用即可--prune[=<日期>]
清除未引用的对--auto
启用自动垃圾回收模式--force
强制执行 gc 即使另外一个 gc 正在执行
fork相关操作
- fork之后,想要更新原作者的分支:
git remote add 名称 原作者URL
- 拉取更新 :
git fetch 名称
在合并别人仓库源码时,相当于两个不同源的分支之间的合并操作
仓库基本命令
如果没有一个Github 码云这样的平台, 而只是单独的两个点, 两个用户或者IP之间要使用同一个仓库进行开发
两个人互为对方的远程库, 互为服务器即可完成, 即使使用的是动态IP, 应该也不会受太大影响
使用git help 加上命令
, 就能看到命令对应的文档
config
git config user.email ***
和git config user.name ***
这两个是必须的,- 如果想统一配置不想每个仓库单独配置就
git config --global user.name
email同理
- 如果想统一配置不想每个仓库单独配置就
git config http.postBuffer 524288000
设置缓存区大小为 500mgit config core.fileMode false
忽略文件的mode变化,一般发生在文件的复制粘贴之后(跨系统?)
status
-s --short
简化输出- ?? 表示新添加未跟踪
- A 新添加到暂存区
- M 修改过的文件
- MM 修改了但是没有暂存
rm
- 删除文件
git rm 文件
- 从git仓库中删除文件, 但是文件系统中保留文件
git rm --cached 文件
- 如果仅仅是想从仓库中剔除, 那么执行完命令还要在
.gitignore
文件中注明, 不然又add回去了
- 如果仅仅是想从仓库中剔除, 那么执行完命令还要在
commit
- 官方文档
git commit -am "init"
: a git库已有文件的修改进行添加, m 注释git add *
如果有新建立文件就要add 再之后commit就不要a参数了git commit -m ""
- 如果只是修改文件没有新建
git commit -am ""
git commit
会自动进入VI编辑器- 第一行:用一行文字简述提交的更改内容
- 第二行:空行
- 第三行:记述更改的原因和详细内容
- 使用下面方法关闭退出
提交行为准则
- 提交之前先更新
- SVN更新的原则是要随时更新,随时提交。当完成了一个小功能,能够通过编译并且并且自己测试之后,谨慎地提交。
- 如果提交过程中产生了冲突,则需要同之前的开发人员联系,两个人一起协商解决冲突,解决冲突之后,需要两人一起测试保证解决冲突之后,程序不会影响其他功能。
- 如果提交过程中产生了更新,则也是需要重新编译并且完成自己的一些必要测试,再进行提交。
- 保持原子性的提交
- 每次提交的间歇尽可能地短,以一个小时,两个小时的开发工作为宜。如在更改UI界面的时候,可以每完成一个UI界面的修改或者设计,就提交一次。在开发功能模块的时候,可以每完成一个小细节功能的测试,就提交一次,在修改bug的时候,每修改掉一个bug并且确认修改了这个bug,也就提交一次。我们提倡多提交,也就能多为代码添加上保险。
- 提交时注意不要提交本地自动生成的文件
- 对于Java来说, IDE自身配置文件, 和字节码文件是无需提交的 例如 .idea目录 iml文件
- 不要提交不能通过编译的代码
- 代码在提交之前,首先要确认自己能够在本地编译。如果在代码中使用了第三方类库,要考虑到项目组成员中有些成员可能没有安装相应的第三方类库,项目经理在准备项目工作区域的时候,需要考虑到这样的情况,确保开发小组成员在签出代码之后能够在统一的环境中进行编译。
- 不要提交自己不明白的代码
- 提交之后, 你的代码将被项目成员所分享。如果提交了你不明白的代码,你看不懂,别人也看不懂,如果在以后出现了问题将会成为项目质量的隐患。因此在引入任何第三方代码之前,确保你对这个代码有一个很清晰的了解。
- 提前协调好项目组成员的工作计划
- 在自己准备开始进行某项功能的修改之前,先给工作小组的成员谈谈自己的修改计划,让大家都能了解你的思想,了解你即将对软件作出的修改,这样能尽可能的减少在开发过程中可能出现的冲突,提高开发效率。同时你也能够在和成员的交流中发现自己之前设计的不足,完善你的设计。
- 对提交的信息采用明晰的标注
- +) 表示增加了功能
- *) 表示对某些功能进行了更改
- -) 表示删除了文件,或者对某些功能进行了裁剪,删除,屏蔽。
- b) 表示修正了具体的某个bug
remote
常用参数
add name URL地址
添加远程关联仓库 不唯一,可以关联多个, 一般默认是originset-url name URL地址
修改关联仓库的URLrm URL
删除和远程文档库的关系rename origin myth
更改远程文档库的名称show origin
查看远程分支的状态和信息
删除远程库某分支
git push 远程URL的名称 --delete 分支名称
git ls-remote
显示本地仓库跟踪的那个远程仓库git remote -v
查看关联远程仓库的详情(push和pull的地址)
show
展示提交信息
- 显示当前提交的差异
git show HEAD
HEAD替换成commit的sha值就是显示指定提交的修改 git show -h
查看更多
push
常用参数
-h
查看所有参数和说明-q
控制台不输出任何信息-f
强制--all
推送所有引用-u
upstream 设置 git pull/status 的上游git push origin master
和git push -u origin master
区别在于 前者是使用该远程和分支进行推送- 后者也是推送, 并设置origin为默认推送的远程, 以后push就不用注明远程名了(多远程的情况下要注意)
-d
删除引用--tags
推送标签(不能使用 --all or --mirror)
出现
RPC failed; result=22, HTTP code = 411
的错误- 就是因为一次提交的文件太大,需要改大缓冲区
例如改成500m
git config http.postBuffer 524288000
- 就是因为一次提交的文件太大,需要改大缓冲区
提交本地所有分支
git push --all
pull时同理删除远程分支
git push 远程URL的名称 --delete 分支名称
第一次与远程建立连接
git push -u origin master
|git push --set-uptream master
|git push -all
- 这几个都是可以的,最后那个简单, 还能将别的分支一起推上去
log
更多说明 查看
git help log
| 官网文档
-p
显示每次提交的内容差异git log -p -2
仅显示最近两次提交的差异--stat
查看提交对仓库修改的总览---pretty=[online/short/full/fuller/format]
使用预定义格式显示- format 是可以自定义格式和占位符
--graph
图形的样子显示分支图git log --author='A'
输出所有A开头的作者日志git log 文件名 文件名
输出更改指定文件的所有commit 要文件在当前路径才可git log --after='2016-03-23 9:20' --before='2017-05-10 12:00'
输出指定日期的日志git shortlog
按字母顺序输出每个人的日志--numbered
按提交数排序-s
只显示每个提交者以及提交数量
彩色输出
alias glogc="git log --graph --pretty=format:'%Cred%h%Creset %Cgreen%ad%Creset | %C(bold cyan)<%an>%Creset %C(yellow)%d%Creset %s ' --abbrev-commit --date=short" # 彩色输出
alias gloga='git log --oneline --decorate --graph --all' # 简短彩色输出
alias glo='git log --oneline --decorate' # 最简单
alias glol='git log --graph --pretty='\''%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\'
alias glola='git log --graph --pretty='\''%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\'' --all'
对比两个分支的差异
- 查看 dev 有,而 master 中没有的
git log dev ^master
反之git log master ^dev
- 查看 dev 中比 master 中多提交了哪些内容:
git log master..dev
- 不知道谁提交的多谁提交的少,单纯想知道有什么不一样:
git log dev...master
- 在上述情况下,再显示出每个提交是在哪个分支上:
git log --left-right dev...master
- 注意 commit 后面的箭头,根据我们在 –left-right dev…master 的顺序,左箭头 < 表示是 dev 的,右箭头 > 表示是 master的。
diff
--cached
查看已暂存起来的变化 1.6以上 则是--staged
git diff [options] [<commit>] [--] [<path>...] git diff [options] --cached [<commit>] [--] [<path>...] git diff [options] <commit> <commit> [--] [<path>...] git diff [options] <blob> <blob> git diff [options] [--no-index] [--] <path> <path>
tag
查看所有标签
git tag
-l 'v1.0.*'
列出v1.0.*- 展示标签注释信息
git show tagname
- 新建一个标签并打上注释
git tag -a v1.0.0 -m "初始版本"
- 由指定的commit打标签
git tag -a v1.2.4 commit-id
- 由指定的commit打标签
- 切换标签
git checkout tagname
和切换分支一样的,但是标签只是一个镜像,不能修改 - 如果要在某tag上新建一个分支,
git checkout -b branchname tagname
提交指定的tag
git push origin tagname
(默认不会自动提交标签)- 提交所有的tag
git push --tags
- 提交所有的tag
删除本地标签
git tag -d tagname
- 删除远程的tag
git push origin --delete tag <tagname>
分支操作
clone
git clone branchname URL
克隆指定分支git clone URL 目录
克隆下来后更名为指定目录git clone --depth 1 URL
只克隆最近一次提交的历史, 能大大减小拉取的大小, 但是如果要用到之前的提交历史就还是要下拉下来的 类似于懒加载- 但是在新建一个远程仓库后, 推送时会报错:
shallow update not allowed
因为本地库是残缺的 - 所以需要新建一个目录, 把原仓库全拉下来, 再添加远程进行推送, 然后删除该目录, 残缺版的仓库也能正常向新远程推送提交了
- 但是在新建一个远程仓库后, 推送时会报错:
checkout
git checkout 文件名 文件名
git会在索引中找文件,有就取出,没有就从最新的commit回找,取出第一个找到的版本,- 每个文件都是这样,也就是说如果有被删除的文件,是可以通过此来找回的
git checkout .
取出文档库中所有文件的最新版本
git checkout commit 节点标识符或者标签 文件名 文件名。。。
- 取出指定节点状态的某文件,而且执行完命令后,取出的那个状态会成为head状态,
- 需要执行
git reset HEAD
来清除这种状态
撤销当前对文件的所有修改
git checkout -- 文件名
就会使用上次提交的文件来覆盖当前文件
- [ ] 有没有 svn cat 类似的功能
fetch
访问远程仓库, 拉取本地没有的数据
git fetch origin dev-test
下拉指定远程的指定分支到本地, 本地没有就会自动新建git fetch --all
下拉默认远程的所有分支的代码
pull
不仅仅是下拉代码, 还会进行merge合并, 所以安全起见, 是先fetch然后再进行合并操作
git pull origin dev
下拉指定远程的指定分支git pull --all
下拉默认远程的所有分支代码并自动合并
开发流程的常用分支操作
- 一般的开发过程中会使用到三种临时分支(用完就删)和两个主分支 master develop
- 功能分支
feature-*
- 预发布分支
release
- 修复bug
fixbug
- 功能分支
git checkout -b feature-x develop
从develop的分支生成一个功能分支,并切换过去- 完成功能后:
git checkout develop
- 合并:
git merge --no-ff feature-x
- 删除:
git branch -d feature-x
- 合并:
git checkout -b release-1.2 develop
新建一个预发布分支git checkout master
确认没有问题后git merge --no-ff release-1.2
合并到master分支git tag -a 1.2
打标签,这就是github上软件的版本控制- 没有问题后 合并到develop分支
git checkout develop
git merge --no-ff release-1.2
- 删除预发布分支
git branch -d release-1.2
git checkout -b fixbug-0.1 master
新建修复bug的分支git checkout master ``git merge --no-ff fixbug-0.1 ``git tag -a 0.1.1
修补结束后合并到master分支git checkout develop
git merge --no-ff fixbug-0.1
再合并到develop分支- 删除分支
git branch -d fixbug-0.1
- 删除远程没有本地有的分支
git fetch -p
merge
- 官方文档
配置mergetool工具:
git config --global merge.tool kdiff3
git config --global mergetool.kdiff3.cmd "'D:/kdiff3.exe' \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\" -o \"\$MERGED\""
git config --global mergetool.prompt false
git config --global mergetool.kdiff3.trustExitCode true
git config --global mergetool.keepBackup false
git merge develop
默认会直接将master分支指向Develop分支。(一条拐弯的线)git merge--no-ff develop
将当前master分支与分支Develop合并,在Master分支上生成一个新节点(有一个环的线)- 也就是说master将develop分支拉取下来然后合并 develop向master合并
- 如果遇到冲突:
git mergetool
使用工具进行分析冲突文件方便修改
rebase
衍和操作 参考博客 | Git rebase -i 交互变基 | git rebase的原理之多人合作分支管理
他会将分支中的圈, 消除掉, 成为线性结构
- 效果和merge差不多,但是分支图更清晰?TODO 有待详细学习
- 与master合并:
git merge master
换成git rebase master
- 当遇到冲突:
git rebase --abort
放弃rebasegit rebase --continue
修改好冲突后继续
grep
- 搜索文字
git grep docker
-n
搜索并显示行号--name-only
只显示文件名,不显示内容-c
查看每个文件里有多少行匹配内容(line matches):- 查找git仓库里某个特定版本里的内容, 在命令行末尾加上标签名(tag reference):
git grep xmmap v1.5.0
git grep --all-match -e '#define' -e SORT_DIRENT
匹配两个字符串
常用文件
gitattributes
Tools
git-svn
Submodules
- 能够在一个git仓库中将一个文件夹作为一些独立的子仓库进行管理
各个VCS工具的区别以及优缺点
Git
分布式的去中心化的, 年轻化的团队在用, 个人也是习惯性用Git了
SVN
- 中心化的, 代码统一保存, 如果中心发生错误, 代码会全部毁掉, 旧的技术栈以及非开发人员还在用
- 允许部分的进行修改, 下拉提交, 而对于Git来说一个仓库就是一个整体
- 能够精确控制每个目录的每个人的访问权限
repos的使用
综合各个VCS的管理方式