版本模型
分支类型 | 名称 | 永久 | 命名规范 | 来源 | 操作 | 合并到 | 角色 |
---|---|---|---|---|---|---|---|
master | 主干,正式环境 | Y | master | release,hotfix | 无 | 无 | 发布人员 |
develop | 开发分支,开发环境,测试环境 | Y | dev | 无 | 任意 | 无 | 开发人员 |
feature | 功能分支 | N | V2.3_ft_pay_lyx。V版本号__ft_功能说明_负责人 | dev | 任意 | dev | 开发人员 |
release | 版本发布分支 | N | V2.3_rl_20161111。V版本号__rl_版本日期 | dev | bugfix | dev | 发布人员,开发人员 |
hotfix | 补丁分支 | N | V2.2_hf_123456-332452_wyq。V版本号__hf_bug说明_负责人 | master | bugfix | dev | 发布人员,开发人员 |
精简模型的操作:
- hotfix无需另开分支,直接在master开发【否则还需部署一套环境】。合并操作同hotfix。
- 当前版本的feature无需另开分支,直接在dev开发。长期feature需开分支。
环境清单
- 每个环境都有一套:执行程序,数据库,配置
环境 | 对应分支 | 执行程序 | 数据库 | 设置 | 说明 |
---|---|---|---|---|---|
开发环境 | dev+feature | 开发人员自行搭建,独立 | 可复用测试数据库 | 可复用测试配置 | |
测试环境 | dev | 独立 | 独立 | 独立 | |
发布环境 | release或者hotfix | 独立 | 可复用测试数据库 | 独立 | |
正式环境 | master | 独立 | 独立 | 独立 |
使用
日常流程
初始化
- 从master克隆dev:git checkout master; git branch dev;
开发feature分支
- 从dev克隆feature:git checkout dev; git branch V2.3_ft_pay_lyx;
- 开发人员检出:git checkout V2.3_ft_pay_lyx;
- feature合并回dev:git checkout dev; git merge V2.3_ft_pay_lyx;
开发release分支
- 从dev克隆release:git checkout dev; git branch V2.3_rl_20161111;
- 开发人员检出:git checkout V2.3_rl_20161111;
- release合并回dev:
- release合并到master(是一个发布版本。同时需要打标签):
开发hotfix分支
- 从master克隆hotfix:git checkout master; git branch V2.2_hf_123456-332452_wyq;
- 开发人员检出:git checkout V2.2_hf_123456-332452_wyq;
- hotfix合并回master:
- hotfix合并到dev/release:
hotfix时,当有一个release分支同时存在(当前版本快发布了,却发现上个版本的bug)。这个hotfix分支必须被合并到release分支而不是dev分支(release后续会合并到dev)。
部署环境
- 获取代码(测试环境):git -C DIR checkout dev; git -C DIR pull;
- 部署
常用操作
选择提交的分支
按照以下顺序选择:
- release分支:bugfix(无bugfix分支的情况下),需尽快发布的小改动和功能
- dev分支:
- 下个版本 && 小改动
- 下个版本 && (新增功能 && 不修改原有逻辑)
- feature分支:到了测试和发布阶段再合并回dev分支
- !下个版本
- 下个版本 && 调整功能
- 下个版本 && (新增功能 && 修改原有逻辑)
暂存文件
- 工作区代码暂存,会记录来源分支
- 使用场景:有新工作要做(如bugfix)+ 当前工作区有不少修改了却无法提交的文件
- 暂存当前工作区,切换到新工作,恢复当前工作区
打补丁
- 跨分支代码迁移
- 使用场景:提交了代码到主分支+该功能代码需要先发布上线
- 在主分支上选择该功能对应的所有提交,创建成一个补丁,在发布分支上应用本补丁
取消本地没push的commit
- 重置到commit前的上一个版本,常用mixed
- soft:提交内容放在缓冲区(相当于git add了)
- mixed:提交内容不放在缓冲区(相当于改动后什么都没操作,git add后等于soft)
- hard:丢弃提交内容
pull时冲突处理
无commit(2种方法,推荐暂存)
暂存处理
- stash暂存改动
- pull最新的版本
- stash pop,手动解决冲突
冲突处理
- commit
- “有commit”的流程
有commit
- pull,手工解决冲突
- commit(解决冲突)merge版本
- push
冲突各方说明
方式 | 我的(LOCAL) | 他人(REMOTE) |
---|---|---|
暂存 | 本地文件 | 暂存 |
分支合并 | 目标分支(LOCAL) | 源分支(REMOTE, 被合并的) |
补丁 | 本地文件 | 补丁 |
代码合并
- Git – Fast Forward 和 no fast foward
- BASE是双方的父亲
- 冲突文件说明
<<<<<<< HEAD 我的 ======= 他人 >>>>>>>6853e5ff961e684d3a6c02d4d06183b5ff330dcc
仓库迁移
- https://help.github.com/cn/articles/duplicating-a-repository
重置目录
- “git -C src fetch && git -C src reset –hard && git -C src checkout B1 && git -C src pull”
- src是git目录路径,B1是分支或者标签。如是标签pull会失败,可忽略
信息获取
- git -C $3 symbolic-ref –short -q HEAD // 分支
- git -C $3 describe –always –tag // 标签
- git -C $3 rev-parse –short HEAD // 提交
变基(rebase)
- merge和rebase的最终结果没有任何区别
- https://xiaozhuanlan.com/topic/6873210549
- https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA
- https://blog.csdn.net/kuangdacaikuang/article/details/79619828
方式 | 说明 | 优点 | 缺点 |
---|---|---|---|
merge | 合并时遇到冲突,修改后重新commit | 记录commit的实际情况,方便查看 | 无改动会快进合并,否则自动创建一个新的merge commit |
rebase | 将commit历史进行合并,并行变串行。本质是补丁模式 | 提交历史更加整洁 | 发生冲突时不容易定位问题,因为rewrite了history |
清除已删除的文件(其存在于历史提交中)
// 下载全部分支
git clone --bare <git_url>
// 获取前十个最大的文件
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -10 | awk '{print$1}')"
// 将文件名存入large_files.txt,基于文件清除
git filter-branch -f --prune-empty --index-filter "git rm -rf --cached --ignore-unmatch `cat large_files.txt`" --tag-name-filter cat -- --all
// 如果文件所在目录删除了,就无法清除文件了,只能清除目录
git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch 相对目录' --tag-name-filter cat -- --all
// 提交到远程仓库
git push origin --all -f
提交失败相关处理
设置大缓存,用于大文件提交失败:git config --global http.postBuffer 52428000
显示命令的详细信息,用于提交失败原因定位:export GIT_CURL_VERBOSE=1
显示所有配置:git config -l
统计
- 统计工具:cloc, git_stats
- 统计脚本
echo "统计结果:" && git log --first-parent master --author="andrew" --after="2018-09-16 12:00:00" --before="2019-09-16 00:00:01" --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "增加行数:%s 删除行数:%s 变化总行数:%s\n",add,subs,loc }' echo "详情如下:" && git log --first-parent master --author="andrew" --word-diff --since="2019-05-16 00:00:01" --until="2019-09-16 12:00:00" -p --stat
同一台电脑上的仓库目录用不同账号提交
- 相同或不同仓库都可以
- 操作如下,核心是设置仓库实例的git账号信息
cd 仓库目录 git config --local user.name NAME git config --local user.email EMAIL@email.com
下载部分文件
- 只能生效一次,再做需要重头操作
- 支持多层目录
git init && git config core.sparseCheckout true && echo "design/" >> .git/info/sparse-checkout git remote add -f origin url && git pull origin master
命令脚本
branch
- git clone -b master –single-branch –depth=1 URL // 只克隆指定的版本,克隆深度是1
- 显示当前分支:git branch
- 显示所有分支,含远程分支:git branch -va
- 显示分支的提交记录:git show-branch
- 显示当前分支的版本号(commit id):git rev-parse HEAD
- 切换分支/标签
- 切换本地分支:git checkout 分支/tag/commit,git checkout branch1, git checkout tag1, git checkout commit1
- 下载远程分支并切换【下载前先git pull同步】:git checkout -b <本地分支> origin/<远程分支>,git checkout -b lb origin/rb远程分支>本地分支>
- 下载远程标签并切换【下载前先git pull同步】:git checkout -b <本地分支> origin/<远程tag>远程tag>本地分支>
- 基于当前分支创建新分支/切换分支:git branch <分支>分支>
- 删除分支:git branch -d <远程分支>远程分支>
commitadd命令
- git add -f . && git commit -m “msg” && git push // 快速提交
- git checkout -b abc && git push origin abc:abc // 本地创建分支并推送到远程同名分支
- 添加所有的文件,包括删除的[所有跟踪文件中被修改过或已删除文件,所有未跟踪的文件]:git add -A .
- 查看所有的commit提交记录:git log
- 查看所有的commit提交记录(含文件清单):git log –name-status
- 查看最新的commit:git show
- 查看指定commit hashID的所有修改:git show commitId
- 查看某次commit中具体某个文件的修改:git show commitId fileName
其他
- git fetch && git reset –hard @{upstream} && git clean -ffdx // 重置目录到服务器状态
- git status // 显示当前目录的文件情况
- git blame file_path // 显示文件内容的具体修改情况
- git cat-file -p commitid // 显示提交号的具体内容
- git show commitid // 显示提交号的具体内容
- “git clone –depth 1
<目录>" // 下载最后一次commit,加快速度目录> - **指定在特定目录执行git:git -C <目录> 执行命令**目录>
- 拉取当前分支:git pull
- 拉取分支:git pull <远程主机> <远程分支>:<本地分支>,git pull origin master:master本地分支>远程分支>远程主机>
- 合并分支(远程分支合并到当前分支):git merge <远程分支>远程分支>
- 查看提交信息:git show <提交号(7位)>
- 清除当前目录所有commit冲突的文件,不会回退:git reset hard
- git reset .
- 清除当前目录下所有没commit的管理文件的修改:git checkout .
- 清除当前目录下所有非管理文件:git -C . clean -xdf
- 撤销合并,需指定parent:git revert -m 1 <提交号(7位)> m参数的值可以是1或2,对应parent在merge commit信息中的顺序,1是合并目标,2是合并来源
- 永久删除远程分支上的提交。非常规操作,不建议使用【本方法已无效】
cd <目录> git reset --hard HEAD^ // 删除最近的一次提交,删除n次提交就执行n次 git push origin master -f // 提交到远程, origin是远程名称,master是分支名称
- 重置branch:分支存在但所有commit记录清空了,一般用于master
思路:用空分支替换需重置的branch(master) 步骤: git clone并进入目录 git checkout --orphan new_branch && rm * -rf // 创建孤儿空分支,清空 echo linux > README.md && git add -A && git commit -am "Initial commit" // 空分支加一个文件,没有文件无法创建commit,就没法替换master git branch -D master && git branch -m master && git push -f origin master // 删除master,将空分支提交到master
- Git查看和修改账户, git config
- git 免除账号密码的设置
- git config –global credential.helper store // 记住账号密码
- rm ~/.git-credentials // 取消账号密码记忆
- 忽略SSL证书:git config –global http.emptyAuth true
gitlfs
- gitlfs安装后默认git clone是下载lfs文件的
- 不下载lfs文件 配置: git config –global filter.lfs.smudge “git-lfs smudge –skip”
- 下载lfs文件 配置: git config –global filter.lfs.smudge “git-lfs smudge – %f”
资料
参考
- Learn Git Branching,很好的示范
- git push & git pull 推送/拉取分支
- Git - 分支的新建与合并
- SourceTree使用流程和方法
- git – 简易指南
- 强制删除远程分支上的某次提交
- Git下的冲突解决
- git多账号提交适配
- git中detached HEAD、amend、rebase和reset
- Detached HEAD
账号
- git账号:通过邮箱区分
- author:作者,通过commit命令添加
- committer:提交者,通过配置添加 1. 全局配置: /user/NAME/.gitconfig
- 服务商账号:服务商自定义,比如github账号密码
提交
- github提交时不会检查服务商账号是否和git的committer一致,所以只要有github仓库权限就可以伪造成其他人的提交
- github仓库首次输入会记忆