在实际开发中,使用git flow可以很方便的对项目各个版本进行管理,功能开发也能够提高效率。具体使用方法如下:
https://github.com/petervanderdoes/gitflow-avh/wiki/Installation
选择对应的平台即可。
这里默认使用Windows平台的git:Git for Windows
PS:
1.日常开发中也会同时安装TortoiseGit,方便本地仓库中文件提交的显示,同时也能很方便的提交到远程仓库。
TortoiseGit下载链接:Download – TortoiseGit – Windows Shell Interface to Git
注意:
1.TortoiseSVN是SVN的工具,当项目中使用SVN作为版本管理工具时则需要使用TortoiseSVN来进行版本开发。下载链接:下载 · TortoiseSVN
Git 和 SVN的区别:Git与SVN对比 - WindrunnerMax - 博客园
2.TortoiseGit 和 TortoiseSVN 在对应的下载链接中都有相对应的LanguagePack多语言包,不同工具的LanguagePack不可共用。
git clone 远程仓库链接
注意:
1.当使用git clone指令后会自动在当前目录下自动以远程仓库链接中项目的名字来创建文件夹
如在当前目录“D:\Project\Unity”下鼠标右键选择“Git Bash Here”打开git窗口:
使用git clone指令后会自动根据远程仓库链接的项目名生成对应文件夹“testBranch”。
所以并不需要另外新建一个文件夹来放置远程仓库项目,避免嵌套
2.在clone指令完毕后,
*** 会自动将本地仓库与远程仓库关联起来
*** 并且会根据远程仓库的默认分支自动在本地仓库中创建同名分支(Gitlab中默认分支是main)。
*** 如果后续需要,可以自由更改以上根据远程项目自动创建的同名文件夹的名字。
注意:更改文件夹名字并不会改变本地仓库与远程仓库的关联。
3.之后对该本地仓库和远程仓库的所有操作都需要先进入“testBranch”文件夹后再打开git窗口,不可在“testBranch”同级目录下操作。
PS:
查看本地仓库的关联状态:
git remote -v
将本地仓库与远程仓库关联起来:
git remote add 远程仓库别名(默认为origin,也可以自定义) 远程仓库链接
注意:
1.设置远程仓库别名的作用只是在后续需要使用远程仓库链接时可以直接使用这个别名来代替,不用输入长串链接。
2.将本地仓库与远程仓库同名分支关联起来也可以使用:
git push -u origin 本地分支名
PS:在第一次使用git clone指令后会默认将远程项目最新内容clone到本地仓库,此时并不需要另外再同步。
同步远程仓库指定分支到本地仓库指定分支:
git pull 远程仓库别名 远程仓库指定分支:本地仓库指定分支
同步远程仓库指定分支到本地仓库当前分支:
git pull 远程仓库别名 远程仓库指定分支
这里会设置Git项目各个分支的name,包含发布分支release、开发分支develop,、功能分支feature等,保持默认配置即可。
注意:执行 git flow init 指令完成后会自动将本地仓库切换到develop分支。
但是这只是在本地仓库中新建develop分支,并不会在远程仓库中新建develop分支。如果需要在远程仓库中创建develop分支则可以使用 “git push origin 本地分支名:远程分支名”,或者直接在Gitlab上创建新分支
PS:执行初始化时可能遇到分支name不对的问题导致无法初始化成功
这是由于分支名字不对,有的项目主分支使用的是“master”。所以这里“Branch name for production releases”填写master即可
在实际开发中,通常都会针对某个功能创建一个独立分支用来开发。当这个功能开发完成后再合并回develop分支,方便管理。
创建功能开发feature分支:以上git flow init指令时针对功能开发使用的分支前缀是feature,可以自由设定
git flow feature start 分支名
执行以上命令后会自动在本地仓库中创建"feature/分支名"分支:
注意:
1.git flow feature start 分支名,是在本地仓库中以develop为基础创建新分支,并不是以远程仓库中的develop分支为基础而创建,所以在开始feature分支开发时需要将本地的develop分支同步到最新状态。
2.创建的功能分支会自动添加feature前缀,所以以上得到的分支实际名字是:feature/分支名
首先添加指定文件追踪:
git add 文件路径
注意:
1.这里的文件路径是相对路径,并且是项目根目录下的相对路径
如以下添加file01.txt文件时,则直接使用 "git add file01.txt"即可
PS:当需要提交根目录下所有文件时可以使用“git add .” —— 点号,即代表根目录下所有文件
2.使用 “git status” 查看文件提交状态:
然后,在把文件都添加完成后,则将这些修改过的文件提交到本地仓库缓存区:
git commit -m "注释"
注意:如果使用TortoiseGit,那么在执行完git commit -m "注释"后则所有文件都会变绿,即提交到本地仓库完成
将本地仓库当前分支推送到远程仓库指定分支:
git push origin <本地分支名>:<远程分支名>
将本地仓库当前分支推送到远程仓库中的同名分支:
git push origin <本地分支名>
注意:
1.当需要提交的文件较大时,有可能会提交失败,此时可以配置git缓存区大小:
# 缓存大小单位:B,例如:524288000(500MB)
$ git config --global http.postBuffer <缓存大小>
2.执行git push origin 操作后,如果远程仓库中没有该分支,则自动在远程仓库中创建该分支;如果有,则将本地仓库当前分支的内容同步到远程仓库同名分支中。
在整个功能都实现,并验收确认无误后,则可以使用git flow关闭该分支:
git flow feature finish 分支名
注意:
1.分支的实际名字是“feature/分支名”,但以上指令中只需要写“分支名”即可,不需要添加“feature”前缀
2.当执行以上指令后,会自动将本地仓库的分支“feature/分支名”删除,并自动切换到本地仓库的develop分支。
默认情况下,远程仓库的“feature/分支名”也会被删除,如果本地develop分支与远程develop分支不同步或者其他情况,可能导致远程的“feature/分支名”并不会被删除
3.以上操作只是将本地仓库切换到develop分支,远程仓库的develop分支不会有任何修改。所以如果要同步到远程仓库的develop分支,则需要另外使用 git push origin 本地分支名
PS:
1.在执行以上指令关闭feature分支时有可能会遇到以下问题:
$ git flow feature finish archiveDrawing
Branches 'develop' and 'origin/develop' have diverged.
Fatal: And branch 'develop' may be fast-forwarded.
原因:此时虽然已经将远程“develop”分支最新的内容拉取到本地的“feature/archiveDrawing”分支中,但本地的“develop”分支依然没有最新的内容,所以需要先切换到本地的“develop”分支,然后更新本地的“develop”。之后再使用“git flow finish”关闭feature分支
解决办法:
第一步:先将本地切换到“develop”分支,然后拉取远程develop分支最新内容
git checkout develop //先将本地切换到develop分支
git pull origin //更新本地develop分支到最新
第二步:以本地当前最新的develop分支为根基切换到archiveDrawing分支:
git flow feature rebase archiveDrawing //archiveDrawing为feature分支名
此时有可能会有一些冲突文件。所以建议在执行“git flow feature finish”指令前,先在本地archiveDrawing分支上拉取最新的远程develop分支内容。在这一步直接处理有可能导致冲突的文件。处理完后,在这里使用“git flow feature rebase”指令时通常就不会出现冲突了
PS:在使用git flow feature rebase 指令时遇到“REBASE 1/1”:
在分支末尾出现“REBASE 1/1”标记
这是由于拉取远程分支后与本地的文件有冲突导致的。此时直接执行“git rebase --continue”指令是不行的。
解决办法:
首先直接使用“git rebase --skip”跳过当前commit。
然后切换到develop分支,拉取develop最新内容到本地。放弃使用feature功能分支,直接在develop分支上commit以及push修改的内容即可
第三步:重新执行“git flow feature finish archiveDrawing”指令
执行“git flow feature rebase”指令后,即将本地切换到了“archiveDrawing”分支。此时再重新执行“git flow feature finish archiveDrawing”指令即可正常删除本地和远程的“archiveDrawing”分支。之后再push到远程develop即可完成提交流程
这是很重要的一步:
原因:
1.使用git flow feature finish 指令,只是将本地仓库切换到develop分支,并没有把修改同步到远程仓库的develop分支,所以必须要再执行git push 指令后,
git push origin develop
远程仓库才拥有这些修改内容,否则远程仓库的develop分支不会有任何修改
2.同一个项目中develop分支一般都会保存当前项目已经验收无误并相对稳定的功能,因此develop可能会被多人同时修改。每个人在把当时的功能完成后都会合并到develop分支中。因此我们本地仓库中的develop分支可能落后于远程仓库中的develop分支
所以为了避免还原某些文件,我们在同步之前需要首先把远程仓库develop分支中最新内容同步到本地
在拉取远程仓库develop分支到本地develop分支时有可能会有某些文件冲突,因此需要首先处理冲突,在处理冲突完成后,再将处理过后的内容"git commit -m"到本地仓库develop的缓存区,然后再使用git push origin develop同步到远程仓库的develop分支
以上则是正常的git flow开发流程,下面是简化版本:
在实际使用中git flow虽然可以统一管理开发流程,但在完成feature分支并合并到develop时,“git flow feature finish 分支名”指令经常会遇到一些问题导致关闭分支失败,所以这里简化下流程:
1.在开发初依然使用指令“git flow feature start 分支名”在develop的基础上创建新feature分支,之后所有的提交都在该分支上操作。
2.在feature分支开发完成后,需要将feature分支的修改提交到本地和远程的同名feature分支。流程如下:
首先需要将develop分支最新内容拉取到feature分支。由于项目有多人开发,因此经常会遇到文件冲突的情况。
1.在pull远程develop分支到本地feature分支时,为了避免本地的修改被覆盖导致丢失,git会自动停止pull的操作,提示需要先“stash”本地修改,即先commit本地修改内容到本地feature分支,避免丢失。
2.在commit修改到本地feature分支后,再pull远程develop分支,此时git会自动将同一个文件中不同地方的修改内容合并。但如果修改了同一个文件的同一行代码,那么此时git会提示选择哪个对应的版本,根据具体情况选择对应develop或者自身feature的修改即可。
如此冲突处理完成
其次在拉取develop最新内容到feature分支后,由于本地具有了最新的develop分支内容,因此需要再次commit到本地的feature分支仓库。
最后将本地feature分支push到远程的feature仓库即可。这样feature分支就完成了。
首先将本地分支切换到develop: git checkout develop
然后更新本地的develop分支,如果本地develop不是最新的,那么是无法进行合并操作的:
git pull origin develop。 —— 这一步建议使用git工具来做,工具比较简单明了
最后将feature合并到develop分支:
注意:
1.如果是将branch a 合并到 branch b,那么本地需要checkout 到branch b,在branch b的基础上把branch a合并过来。
2.在合并的过程中经常会遇到冲突的情况,由于之前在提交feature分支内容时已经合并过一次,因此可以避免一部分的冲突,但仍然有出现冲突的可能
合并feature到develop分支的操作可以直接使用git工具来做:
上图“From”中的“Branch”指代被合并的分支C,“Merge message”中不需要填写合并,会自动生成。选择完毕,即代表将分支C合并到develop
点击“OK”后则会开始合并。合并过程中可能会出现冲突处理,按照具体情况选择使用的版本即可。
合并分支的参考链接:git合并分支(一看就懂) - 简书
合并完成后,本地即拥有了两个分支的内容,但由于之前修改的内容已经使用分支C提交过,因此当把分支C合并到develop后是不需要再次把这些修改的内容使用develop分支重新commit一次 —— 在合并完毕后则develop分支已经包含分支C曾经commit过的内容,因此只需要将develop分支push到远程仓库的develop分支即可
在开发中有时候commit并push到远程仓库后发现有些内容不适宜提交,此时需要返回原来的版本,可以使用“git reset --soft”和“git reset --hard”:
git reset --soft:
只回退到指定版本A,使用该指令后,本地仓库会回退到版本A,在版本A后所有的提交在本地仓库都无效了,相当于本地仓库直接回退到版本A的当时情况。——注意是本地仓库,本地的分支依然保留着之前的修改内容,以方便再次提交
但远程仓库依然保留着最新版本的情况,但由于是首先更新本地与远程仓库一致,然后才使用“git reset --soft”,因此当再次push到远程仓库时不会有冲突情况——如果有别人提交了东西,此时pull下即可
使用该指令后,本地仓库回退到版本A的情况,但依然保留最近一次commit时的本地修改,这些修改还没有提交到本地仓库,因此也被称为“soft”回退。此时可以按照正常流程再次commit,push
git reset --hard:
将本地仓库回退到版本A,并且本地修改的内容全部删除。由于清除了本地修改的内容,因此也被称为“hard”回退,此时只能重新编写代码
回退流程:
仔细选择需要回退到的指定版本,由于soft时会保留本地修改的内容,所以通常都只是回退到最近提交记录的上一个版本即可—— 也可以根据具体情况自由指定
2.使用“git reset --soft”回退到指定版本,但保留本地修改:
git reset --soft acf6abf01d622a89dd14db10a7d03ae842ec9b4f
使用“git reset --hard”回退到指定版本,但不保留本地修改:
git reset --hard acf6abf01d622a89dd14db10a7d03ae842ec9b4f
执行以上“git reset”指令完毕后,可以输入“git log”查看当前版本情况,发现已经回退到了目标版本
3.再次使用commit将本地修改提交到本地仓库,之后push到远程仓库。
由于是先pull本地仓库到最新版本B,然后再使用“git reset”回退本地仓库到版本A,之后重新commit后本地仓库变成版本C,因此此时重新push到远程仓库时需要先pull下,而此时的pull是在本地仓库版本C的基础上把远程仓库其他修改的内容(如果有)更新到本地仓库。
PS:由于在“git reset"之前,本地仓库已经具有了远程仓库的版本B,所以此时重新拉取也就不会出现版本B把版本C覆盖的情况了。但如果远程仓库在版本B后有其他新的提交内容,那么只会把这些提交更新到本地仓库——而这就是正常的版本更新内容,按照通常的流程即可
当跨平台开发项目时,由于windows、mac、unix系统换行符的差异导致文件在push到远程时会有明显的不同:
当在windows平台安装"git for windows"时会默认打开“core.autocrlf = true”:
需要注意的点:
1.为保证跨系统开发的一致性,同时git for windows自身默认的core.autocrlf设置,因此远程仓库一律使用“LF”作为换行符,而不是“CRLF”
2.不要随意更改“core.autocrlf”。当把core.autocrlf关闭后再重新开启“core.autocrlf = true”时,需要删除掉原有文件重新clone或生成才会使“core.autocrlf = true”生效 —— 删除原有文件重新clone,这一步很麻烦,所以轻易不要修改“core.autocrlf”参数
3.在windows平台安装git for windows后会默认开启“core.autocrlf = true”,因此可以保证push到远程仓库为“LF”换行符,在本地checkout开发时则是“CRLF”。—— 完全是无感的存在,不影响任何开发流程,这也是不轻易修改“core.autocrlf”参数的其中一个原因。
总结:
在windows平台中借助于git for windows的默认设置,“core.autocrlf”无需任何额外设置,对开发流程没有任何影响。故通常也不需要修改该参数
但如果windows平台中当前“core.autocrlf = false”,那么则需要重新打开,并且删除本地文件重新clone后才会起效
PS:Git其他常用指令
git branch:
列出本地所有分支,当前所在分支以“*”标出: git branch
在本地创建新分支: git branch 分支名
删除指定的本地分支:git branch -d 分支名
git checkout:
切换到本地的指定分支:git checkout 分支名
(1.如果本地没有该分支,但是远程仓库有该同名分支,那么在使用“git checkout 远程仓库同名分支”后,会
直接在本地仓库创建一个同名的分支,并且自动将远程仓库同名分支和本地仓库同名分支关联起来
2.如果在使用“git checkout 分支名”前,本地仓库已经有该分支,那么此时使用“git checkout 分支名”后只会切换到本地仓库该分支,并不会自动与远程仓库同名分支关联起来。所以后面要push或者pull时都需要在TortoiseGit工具面板中手动重新选择远程仓库指定分支才可
)
创建并切换到本地指定分支:git checkout -b 分支名
git push:
删除远程仓库的指定分支:git push 远程仓库别名 :远程分支名
git push 远程仓库别名 --delete 远程分支名
git config:
查看git配置信息:git config --list
查看用户名:git config user.name
查看邮箱:git config user.email
设置全局用户名:git config --global user.name "xxx"(输入你的用户名)
设置全局邮箱:git config --global user.email "xxx"(输入你的邮箱)
Git指令全集:Git命令大全 - 简书