Git 是一个分布式版本控制与代码管理系统,用于自动跟踪文件和文件夹的历史变化,以及协调多人在同一项目上的协作开发,并在需要时进行版本回退和分支管理。
一、准备工作
1、安装Git
官网下载安装,把git-bash.exe
所在的目录追加到系统变量的Path
中。完成后,在任意文件夹内鼠标右键就能看到Git Bash Here
,即输入Git命令行的地方。
2、上传公钥
任意位置鼠标右键,配置用户
git config --global user.name "gitee注册用户名" |
然后生成公钥
ssh-keygen -t rsa -C "gitee注册邮箱" |
按默认设置一路回车,直到最后出现矩形图案,说明公钥已生成到C:\Users\用户\电脑用户名\.ssh
文件夹中。复制文件夹内id_rsa.pub
中的内容到gitee上,位置为设置>>SSH公钥
。一份公钥可链接整个gitee账户的所有项目。
二、基于Git命令行运作
1、基于Git命令行上传项目
假设本地有一个Test文件夹,内涵诸多代码,视为一个项目。上传方法为:先在gitee上创建名为Test的仓库,然后在本地的Test文件夹内依次执行下列命令。
git init # 创建git环境(同一文件夹内只需执行一次,有【.git】即可) |
至此,Test项目就被推送到远程仓库。后面对本地工程做修改后,都需要重新依次执行第2、3、5行命令。
关于推送流程的示意图:
绿、黄、蓝、橘色部分:工作区、缓冲区、本地仓库、远程仓库
2、基于Git命令行解决冲突
如果有两个开发者A和B协作开发此项目,最大的问题就是读写冲突。其包括文件冲突(文件被增、删)与代码冲突(文件被修改),下面用一个例子来解释怎样解决。
以下面的代码工程为例,Test文件夹下有三个txt文件,每个txt文件的内容都是: 我是A
Test |
A最先按照上述步骤把项目push到远程仓库。B在自己的Test文件夹内通过下面命令pull下来最新版本的项目。
git init |
至此,A与B的代码完全一致。
A开始编辑,修改了1.txt(内容为:两行 我是A
),删除了2.txt,新增了4.txt(内容为:我是AA
)。效果为:
然后用下面三行代码推送到远程仓库。
git add . |
不报错,非常顺利,远程仓库内容也能跟随变更。
B此时开始编辑手里的代码,修改了1.txt(内容变为: 我是B
),修改了2.txt(内容变为: 我是B
),删除了3.txt,新增了5.txt(内容为:我是BBB
)。
然后同样依次执行上面三行代码,报错,内容是系统发现远程仓库与本地仓库的原始版本不一致,即发生了冲突。(此时还不知道哪些文件发生了冲突)
首先需要把远程仓库合并到本地:
git pull --rebase origin master |
此时可以查看哪些文件发生了什么冲突了(很重要的信息):
git status # 先rebase合并再查看status,顺序不能颠倒 |
可以看出涉及到了4个文件(红绿色各两个),另外注意,自从rebase后,红框内所处分支已经从最开始的master
变成了 master|REBASE 1/1
,后面会复原。
打开本地仓库检查,此时,B手中的Test仅剩1、2、4、5.txt,具体为:
解释其现象:
2.txt,内容仍为
我是B
,虽说A已删除且已同步到远程仓库。但B执行合并后,自己的文件及其更改仍然保留。(对写者B是一种保护,对写者A无影响);3.txt,B刚刚已经删掉了,虽说A中有且已同步到远程仓库。但合并后仍然没有出现在B中。(对写者B是一种保护,对读者A没有影响);
4.txt,B中没有,是A新增的。B执行合并后,保留A的变更追加到了B中。(对读者B无影响,对写者A是一种保护);
5.txt,B新增的,A中没有。B执行合并后,仍然保留该文件以及自己的变更。(对写者B是一种保护,对读者A无影响);
以上皆为文件的增或删,属于文件冲突,更重要的是代码冲突,即1.txt。
1.txt,合并后被一些字符标记,git自动保留了每个人编辑过的痕迹。git授权当前的提交者决定保留哪些代码,同时需要手动删除
<<
、==
、>>
等标记符,这里选择保留所有人的代码。(这种决定需要开发者之间相互沟通,在公司中非常常见)。然后用下面的命令重新commit、继续rebase、再重新push即可:git add .
git commit -m 注释
git rebase --continue # 这句会让 【master|REBASE 1/1】重新变为【master】。不执行这一句直接push仍然会报冲突错误
git push origin master
检查gitee远程仓库,发现冲突已经按最后提交者的意愿解决:
后面,
- 如果B需要继续开发,且赶在了A提交之前提交,那么就像刚刚的A一样非常顺利,直接提交成功不需要解决任何冲突。
- 如果A需要继续开发,因为远程仓库已经与他手里的不一样了,他就需要像刚刚的B一样,手动解决代码冲突。
因此,总是靠后的提交者需要解决代码冲突,代码冲突是正常且非常常见的问题(IDEA支持一键解决)。文件冲突一般可以忽略,让Git自行解决。
三、基于IDEA版本控制运作
1、基于IDEA上传项目
在IDEA中引入Git,设置中添加先前安装好的git.exe文件。
open打开Test项目后,点开功能栏的VCS,点击其中的Create Git Repository
来初始化Git工作区。
create之后,IDEA页面发生变化:右侧工程代码文件变成红色(关于颜色后面说);VCS变成Git;且右侧多了三个Git的快捷按钮,分别是pull、commit、push。
创建远程仓库。与Git命令行不同的是,IDEA要求首次推送时Gitee上没有该仓库,它可以自动创建,如图所示,Git->Gitee->Share...
。
弹出一个界面,可以设定远程仓库的基本信息,无误后点击Share。
最后自定义要上传的文件,无误后点击Add,即可完成本地仓库的上传,即push推送。上传后代码文件由红色变为白色。
检查远程仓库,无误。
另外,后面再创建新代码文件时,最好点击这个Add按钮,他能自动把该文件放置到Git工作区,从而自动将其加入版本控制,其颜色也就能从红色变为绿色。
如果后续对该项目又有了其他修改(修改后文件变成蓝色),想最后重新提交所有文件到远程仓库。在IDEA中只需点击三个按钮即可。
首先点击上面提到的Git快捷键中的第2个(commit
动作):
commit后会在左侧显示发生变化的文件(Change部分),然后添加本次提交的注释(必填),最后点击右下角的Commit and Push
(若报异常就再次点击)。
下一个页面再点击一下Push
,即可完成本地仓库到远程仓库的推送。
最后补充代码文件颜色变化的详细说明:
2、基于IDEA解决冲突
就像第二.2
部分提到的文件冲突和代码冲突,如果远程仓库早先已被人更新过,那么在最后一步点击Push
推送时,就会报下面的冲突。
IDEA支持按键式合并来解决冲突。这里选择Merge和Rebase都能进行合并,我一般选择后者。点击Rebase后IDEA会自动分析哪些文件发生了哪些冲突,就像下图中绿色框的部分,可以看出1.txt发生了代码冲突,自己和远程仓库都进行了Modified
。如果多个文件发生了冲突会逐一列出,这里仅以1.txt举例。
双击列出的文件可进入查看具体的冲突。
可以看出左侧栏为自己的版本(只读);右侧栏为当前远程仓库的版本(只读);中间栏是动态的,代表合并后的版本(可读可写)。而怎样合并取决于自己,点击<<
或>>
或都点击
可实现不同的效果,这里都点击
,即都保留,最后Apply
,冲突解决。
在返回后的页面上重新点击Commit and Push
,然后再下一个页面上继续点击Push
,即可完成本地仓库到远程仓库的推送。
检查远程仓库,多人的修改都得到了保留,无误。
四、将多分支应用于我们的多项目
gitee中默认的主分支为master,可自行创建其他分支。其他分支的本意是服务于master的,比如电商项目中将支付、商品、购物车模块分离给各个开发组,各自开发完成之后自主合并到master。
1、适用于我们需求的设想
为适应我们的需求,打算让其他分支各自独立,各自做存储与代码版本控制,永不合并到master。
以DWF后端程序为例,master维护一版基础性代码,同时基于此为多个地区的项目开辟多个分支,比如chengdu、beijing、tianjin等,如下图所示。每个子分支维护一份地区的DWF后端项目,在推送时分开推送,有冲突时也是分开解决。
同理,前端程序、TCP-Server、EDA各自占用一个仓库,每个仓库中也是以master为基础,以地区为依据开辟多个分支来分开管理。
至于多个开发者,每个仓库的管理员分别邀请即可,邀请进来的开发者有权限对本仓库的所有分支进行开发
2、基于Git命令行对多分支项目进行管理
IDEA同样支持分支的切换,但不同开发者的IDEA编辑器版本不同,其方法也略有差异,这里仅以Git命令行为例进行说明。
1)创建远程空分支
新建的分支都是基于master的,与master一致。我们的需求需要新分支为空,然后上传与master分支不一样的内容,所以需要清空新建的分支,或者直接创建空的分支。
后者很简单:创建该仓库时master分支是空的,这时候开辟新分支,也将是空的。
前者:先切换分支,然后执行下面分支进行清空:
git rm -rf * # 或者【git rm -r --cached .】先清掉本地分支的内容 # 只删掉指定文件:【git rm -r --cached 文件名】
git commit -m 'Empty the branch' # 提交空分支
git push origin 分支名 # 如果出错可以强制推送git push -u origin 分支名 -f
2)提交代码
假设远程仓库中已经建立好了各地区的空分支(如上图所示),本地也已有Test项目,进行推送时需要依次执行下列命令。
cd Test |
3)解决冲突
关于解决冲突,和二.2
一样,只是所处的分支变了。
git pull --rebase origin chengdu |