Git 高阶操作
上一章节我们了解了 Git 的基本流程和常见命令后,这一章节我们来继续介绍 Git 的一些场景和高阶操作,希望能够帮助大家进一步了解 Git 的使用方法。
分支管理规范
通常情况下,每个成员各自一条用户分支(除非项目特大,需要更多分支),还可能需要有 develop/dev(开发),test(测试),release(预发布),master/main(线上发布)分支各一条。除此之外,一些情况下,还可能有一些其他分支。
develop/dev :开发分支 ,开发人员每天需要拉取和提交最新代码的分支;
test :测试分支 ,开发人员开发完毕并完成代码自测后,用于发布到测试环境的分支;
release :预发布分支 ,测试环境测试通过后,将测试分支的代码发布到预发环境的分支;(需要看实际是否需要)
master/main :线上分支 ,预发环境测试通过后,运营/测试会将此分支代码发布到线上环境;
bug/hotfix :修复分支 ,当线上版本出现 bug 时,会使用该分支进行 bug 修复;
feature :新功能分支 ,当线上版本需要添加新功能时,可能会使用该分支,或者使用原有 dev 分支。
这些就是常用的分支,下面来介绍一些常规的项目开发流程。
开发者每天在自己用户分支 开发后,拉取并更新开发分支 ;
开发完毕后,开发人员自测后,提交到测试分支 ,供测试人员测试;
测试完毕后,将代码提交到预发布分支 ,并进行预发布环境测试;如果不存在该分支,则直接提交到线上分支 ,并打 tag 标签版本。
当出现 bug 时,使用修复分支 ,进行修复,随后合并到线上分支 ;
分支管理命令
branch
功能:进行分支切换和管理。
使用场景:当多用户开发时,每个用户需要在自己的分支上进行代码编写,此外代码合并人员需要将多个开发人员的代码在 dev 分支进行合并。
git branch | git branch -l git branch -r git branch -a git branch -av git branch -vv $ git branch branchname $ git checkout branchname $ git checkout -b aaa $ git checkout -b aaa master $ git brnach -d branchname $ git branch -D branchname $ git push origin :远程分支名 $ git push origin --delete 远程分支名 $ git branch -m branchname
diff
功能:查看文件差异。
使用场景:大部分情况下,每个用户修改的文件是不存在冲突的,往往用于个人代码的修改和管理;但极少数情况可能会存在多用户修改单文件的情况。
git diff filename git diff git diff --stat git diff --cached/--staged git diff branchname git diff HEAD git diff branchname..branchname filename git diff branchname..branchname git diff origin/branchname..branchname git diff origin/branchname..origin/branchname git diff commit1..commit2
stash
功能:对未提交的修改 (不包括新增)进行暂存,方便后期恢复(要注意如果暂存区没有该文件,则无法对其进行堆栈暂存)
使用场景:当产品出现 bug 时,一般情况下直接开辟新的 bug 分支进行修复,随后将其合并至 master 分支即可,但当此时本地在进行功能开发时(并且一半会儿无法完成,或者 bug 情况紧急),代码不能直接提交仓库 ,就可以使用 stash
命令,将工作区内容 “暂存”,等修复 bug 后,再 stash pop
进行恢复即可。
git stash git stash save "存储" git stash -u git stash list git stash apply "stash@{index}" git stash pop "stash@{index}" git stash drop "stash@{index}" git stash clear git stash show "stash@{index}" git stash show -p "stash@{index}"
merge / rebase
功能:分支、代码的合并。
使用场景:对不同阶段时的分支进行合并。
这里简单介绍一下三种合并方式,后面会对集中合并方式进行详解。
merge(默认 --fast-forward):快进式合并,指针移动造成合并假象 。
merge --no-ff:对比不同版本差异,创建新的 commit ,并实现真真合并。
merge --squash:把所有的改动合并,然后放在本地文件,需要你再次手动执行 git commit 操作 。
rebase:将要合并分支的历史 commit 合并成一条线,保持 commit-tree 的线性 。
git merge git merge --no-ff git merge --squash git rebase
tag
功能:给仓库提交版本进行标识命名。
使用场景:主要用于发布版本命令的管理。
git tag v1.0 git tag v0.9 f52c633 git tag -a v0.1 -m "version 0.1 released" git tag git show <tagname> git push origin <tagname> git push origin --tags git tag -d v0.1 git push origin :refs/tags/<tagname>
版本管理命令
checkout
功能:不同版本和分支的切换。
使用场景:主要用于版本的回退、历史代码查看以及测试 bug。当 checkout 某一次的提交时,你可以进行编辑、编译、运行都可以,他并不会影响项目当前状态 ,当你想要回到项目最新状态 ,只需 git checkout branchname
即可回到项目状态。这里注意,「在开发的正常阶段,HEAD
一般指向 master 或是其他的本地分支,但当你使用 git checkout <commit id>
切换到指定的某一次提交的时候,HEAD
就不再指向一个分支了——它直接指向一个提交,HEAD 就会处于 detached 状态(游离状态)」。
git checkout <filename> git checkout . git checkout HEAD git checkout HEAD -- filename git checkout HEAD^ git checkout <当前你正在使用的分支> git checkout <commit_id> git checkout <tag>
reset
功能:将当前分支重设到某一版本。
使用场景:通常用于本地修改 ,常常用于移除提交的快照(因为 reset 回滚到先前版本后,该版本后的新版本在下一次提交时会被删除)。注意,一旦回退到一个旧版本后 ,此时再用 git log
查看提交记录,会发现之前的新版本记录没有了,此时想要恢复到原来的新版本 ,可以使用 git reflog
来查看原来的 id,并恢复到那个新版本。
git reset <fileName> git reset | git reset HEAD (默认) git reset --hard git reset --hard HEAD^ git reset --mixed <commit> | git reset <commit> git reset --soft <commit> git reset --hard <commit>
revert
功能:撤销当前分支的某一版本。
使用场景:通常适用于线上公共仓库 ,它不是移除提交快照,而是在提交记录上面添加一个新提交,在追踪和修改 bug 时很有帮助,更加安全,可记录。每次提交,你必须假设其他开发者会依赖于它 。移除一个其他团队成员在上面继续开发的提交在协作时会引发严重的问题。当他们试着和你的仓库同步时,他们会发现项目历史的一部分突然消失了。一旦你在重设 reset 之后又增加了新的提交,Git 会认为你的本地历史已经和 origin/master 分叉了,同步你的仓库时的合并提交(merge commit)会使你的同事困惑。
git revert HEAD git revert HEAD^ git revert HEAD^^ git revert HEAD~num git revert <commit_id> git revert <commit_id> --no-edit
三者区别
checkout:本地、远程均可使用,作用于 commit 和暂存区。用于代码的历史查看和 bug 测试等。
reset:本地使用,作用于 commit 和暂存区。用于版本和文件回滚,在此之后的修改都会退回到暂存区。
revert:远程使用,作用于 commit。用于安全撤销公共提交,主要通过创建新的 commit 来撤销旧的 commit 的修改。