GIT 最佳实践
一. 分支规划
- master: 主分支,主要用来版本发布。
- develop:日常开发分支,该分支正常保存了开发的最新代码。
- feature:具体的功能开发分支,只与 develop 分支交互。
- release:release 分支可以认为是 master 分支的未测试版。比如说某一期的功能全部开发完成,那么就将 develop 分支合并到 release 分支,测试没有问题并且到了发布日期就合并到 master 分支,进行发布。
- hotfix:线上 bug 修复分支。
各分支使用场景
- master创建开发分支
git branch develop
git push -u origin develop
- 功能开发
2.1 develop - > user-dev
git checkout develop
git pull origin develop
git checkout -b user-dev //创建新的功能分支并切换
分支创建完毕之后,开始在branch上进行编码,它的主要任务就是完成task的编码工作,并最终将代码push到当前分支对应的远程分支上去。
2.2 提交代码
git status
git add * //改动的代码放入index
git commit -m "the first commit message"
2.3 拉取develop代码,合并至功能分支
git checkout develop
git pull origin develop //获取远程分支代码
git checkout user-dev
git rebase -i develop // 合并代码至deveplop分支
-i : 当前分支之前的commit压缩成为一个commit,这样做的好处在于当我们之后创建pull request并进行相应的code review的时候,代码的改动会集中在一个commit
2.4 功能完成后,push远程分支
git push origin user-dev //可选择push功能分支,直接合并,如需code review可push
git checkout master
git merge --no-ff user-dev
git push origin master
git branch -d user-dev //删除分支
--no-ff
- 版本发布
git checkout -b release-0.1.0 develop //创建测试版本
... 完成测试功能之后准备发布
git checkout master
git merge --no-ff releash-0.1.0
git push
git branch -d releash-0.1.0
git push origin --delete release-0.1.0 //清除分支
git tag -a v0.1.0 master //标记版本
git push --tags
- 主版本bug修复
git checkout -b hotfix-0.1.1 master
... 完成bug修复
git checkout master //合并至稳定版本
git merge --no-ff hotfix-0.1.1
git push
git checkout develop //合并至开发版本
git merge --no-ff hotfix-0.1.1
git push
二. 常用场景
- 恢复单个文件
- 查看文件日志:
git log lost_file
- 从指定版本恢复工作目录:
git checkout xxxxx lost_file
xxxx就是git 库中的sha-1码 - 从缓存区恢复工作目录:
git checkout lost_file
- 从指定版本恢复缓存区:
git reset xxxx lost_file
- 撤销合并
git reset --hard HEAD
- 历史版本切换
git reset --hard xxxxx 恢复到指定版本
git reset --hard ORIG_HEAD 用来撤销已经commit 的merge.
git reset --hard HEAD 用来撤销还没commit 的merge,其实原理就是放弃index和工作区的改动
git reset --hard orign/master #将本地的状态回退到和远程的一样
- 创建版本库
- 查看远程仓库地址:
git remote -v
- 创建仓库
cd my-project
git init
git remote add origin git@code.aliyun.com:anneng/ybss-manager.git
git add .
git commit -m "init project"
git push -u origin master
- 更改托管服务器
git clone --bare git://github.com/username/project.git //目标库克隆一份裸版本库
cd project.git
git push --mirror git@gitcafe.com/username/newproject.git //以镜像方式上传代码
cd ..
rm -rf project.git
若只更换地址
git remote set-url origin remote_git_address
- 配置帐号
git config --global gui.encoding utf-8 Git Gui中文乱码
git config --global user.name "leidy" Git 全局设置
git config --global user.email "zichen616@163.com"
- 更新提交场景
git diff 比较的是工作区和暂存区的差别
git diff --cached 比较的是暂存区和版本库的差别
git diff HEAD 可以查看工作区和版本库的差别
git add 工作区提交至stage
git commit -a -m "command" -a 把修改的文件先提交到stage,然后再从stash提交到branch
git rm --cached readme.txt 从stage和版本库中删除,保留物理文件,本地不受影响,团队更新后删除文件
git rm readme.txt 不但从stage中删除,同时删除物理文件,
git mv a.txt b.txt 把a.txt改名为b.tx
- 合并场景
git ls-files -u 显示冲突的文件,-s是显示标记为冲突已解决的文件
git ls-files --stage 检查保存在stage的文件
将开发中的分支(develop),合并到稳定分支(master)
git checkou master
git merge --noff develop
分支衍合:分支衍合不会保留合并的日志,不留痕迹,而 分支合并则会保留合并的日志
git checkou master
git rebase develop
git rebase --continue
有时候只需要合并部分提交的代码可以
git checkou master
git cherry-pick 62ecb3
但是cherry pick 虽好,但一次只能合并一个commit。 连续多个commit就要用到 rebase
git checkout -b develop 62ecb3
git rebase —onto master 76cada^ #从 76cada 的 commit 开始合并(作为新的commit)
git checkou master
git cherry-pick 62ecb3
- ignore无效
.gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。之所以你的规则不生效,是因为那些 .log 文件曾经被 Git 记录过,因此 .gitignore 对它们完全无效
git rm --cached logs/xx.log #从 Git 的数据库中删除对于该文件的追踪
vim .gitignore logs/xx.log #把对应的规则写入.gitignore
git commit #提交+推送
另一种方式是.git/info/exclude 这里设置的则是你自己本地需要排除的文件,但同样只能作用于Untracked Files
- git提交时忽略已提交过但本地已修改的文件,ignore针对于untrack File,对于已经添加追踪的文件使用如下
$ git update-index --assume-unchanged [file-path] #忽略跟踪
$ git update-index --no-assume-unchanged [file-path] #恢复跟踪
$ git ls-files -v | grep '^h\ ' 查找忽略文件
应用了该标识之后,Git 停止查看工作区文件可能发生的改变,所以你必须 手动 重置该标识以便 Git 知道你想要恢复对文件改变的追踪。当你工作在一个大型项目中,这在文件系统的调用非常迟钝的时候会很有用。
但带来的不良后果:
1 所有的团队成员都必须对目标文件执行:git update-index --assume-unchanged
2 一旦有人改变目标文件之后没有 git update-index --assume-unchanged
10.删除untracked files
# 删除 untracked files
git clean -f
# 连 untracked 的目录也一起删掉
git clean -fd
# 连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
# 在用上述 git clean 前,墙裂建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nf
git clean -nfd
三. 命令详解
3.1 分支操作
- git branch 默认查看本地分支 -a 查看所有分支 -r 查看远程分支
- git branch [branchName] 创建名为branchName的branch
- git checkout [branchName] 切换到branchName的branch
- git checkout -b [branchName] 创建并切换,也就是上面两个命令的合并
- git checkout -b [branchName] origin/develop 获取远程分支并分化一个新分支
- git brach [branchName] ef71 从commit ef71创建名为branchName的branch
- git branch 查看分支,-a 查看远程分支
- git branch -d branchName 删除分支
- git branch -r -d branchName 删除远程分支
- git push origin [branchName] 将本地分支branchName提交到推送远程分支上
- git push origin :[branchName] 将branchname删除
- git merge origin/branchName 将远程分支合并到当前分支
3.2 代码下载
- git fetch 将会取到所有你本地没有的数据,所有取下来的分支可以被叫做remote branches,它们和本地分支一样(可以看diff,log等,也可以merge到其他分支),但是Git不允许你checkout到它们
- git pull 会首先执行git fetch,然后执行git merge,把取来的分支的head merge到当前分支.这个merge操作会产生一个新的commit.
- git push [alias] [branch] 将会把当前分支merge到alias上的[branch]分支.如果分支已经存在,将会更新,如果不存在,将会添加这个分支.