Git简介
Git是目前世界上最先进的分布式版本控制系统
git的两大特点:
- 版本控制:可以解决多人同时开发的代码问题,也可以解决找回历史代码的问题
- 分布式:Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。首先找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。可以自己搭建这台服务器,也可以使用GitHub网站
安装
sudo apt-get install git
安装成功后,运行如下命令
git
配置
在ubuntu的命令行中,修改某台机器的git配置,在家目录下:
修改为注册github时的邮箱,填写用户名,要求组员的用户名不能重复
如果上述配置用户名和邮箱不能用的话,可以使用这种配置github用户名和邮箱的方法
git config --global user.name "zb" git config --global user.email "1273844671@qq.com"
最后可以通过 git config -l 这个命令查看已配置的用户名和邮箱信息
git config -l
使用流程
在实际项目开发中,按照如下步骤使用git进行代码管理
- 1.项目经理在开发之初,创建好仓库,上传项目的框架、组员分支
- 2.组员克隆项目框架,同步分支,按分工开发,在分支提交代码
- 3.在需要发布时,项目经理将各分支合并到dev上,再合并到master上
- git将代码开发分成了工作区、暂存区、仓库区,为了能够交换代码还需要有服务器,一般使用github
- git四部分的交互方式如下图
创建
- 在项目开始阶段,需要由项目经理搭建项目框架,并上传到仓库
- 如下操作都由项目经理完成
创建仓库
注册github账户,登录后,点击"start a project"
在新页面中,输入项目的名称django1,勾选'readme.md',点击'create repository'
添加成功后,转到文件列表页面,点击'create new file'创建新文件
填写文件名称为'.gitignore',代码如下,表示项目中的pyc文件不需要被管理,因为这些文件代码是根据py生成的
详细的ignore文件可以参考官方Python.gitignore文件
*.pyc
.idea/
migrations/
创建完成后,文件列表如下:
添加ssh账户
- 如果某台机器需要与github上的仓库交互,那么就要把这台机器的ssh公钥添加到这个github账户上
- 点击账户头像后的下拉三角,选择'settings'
点击'SSH and GPG keys',添加ssh公钥
生成git密钥
删除~/.ssh目录,这里存储了旧的密钥,没有就不用删除
rm -r .ssh
运行如下命令生成密钥,本人没写,为默认值
- 在“图标2”处可以填写保存密钥的目录
- 在“图标3”处可以填写密码,如果填写,一般为项目的名称,后续操作时会要求填写此密码
- 公钥名称为id_rsa.pub
- 私钥名称为id_rsa
ssh-keygen -t rsa -C "Github账号,可以是用户名,也可以是邮箱地址"
ssh-keygen -t rsa -C "1273844671@qq.com"
查看公钥内容,复制此内容
cat id_rsa.pub
回到浏览器中,填写标题,粘贴公钥,点击ADD SSH KEY
公钥添加成功后,如下图
克隆项目
在浏览器中点击进入github首页,再进入项目仓库的页面
复制git地址
在命令行中复制仓库中的内容
git clone git地址 ,选择的要是httts,会要填Github的用户名和密码,要是使用SSH则不会。
cd Desktop/ mkdir jiangshi/ cd jiangshi/ git clone https://github.com/zb14755456464/django1.git cd bj_ttsx13/
有可能出现如下的错误,错误处理
- 提示错误信息如下:
sign_and_send_pubkey: signing failed: agent refused operation
- 错误原因:在ssh账户中没有加入新生成的密钥
- 解决:将密码加入ssh账户
- 逐条运行如下命令
eval "$(ssh-agent -s)"
ssh-add
创建项目分支
每个员工开发期的代码互不干扰,并行开发,则每人使用一条分支
项目开发中公用分支包括master、dev
- 分支master用于发布,默认分支,当需要发布时将dev分支合并
- 分支dev开发阶段性的代码合并,每个阶段的工作完成后需要进行一次,控制项目的进度
- 成员分支用于每个项目成员的代码开发,实现不交叉,完成阶段性的项目可以和共用的dev分支进行合并。最后经理会用master分支发布
创建分支,git branch 分支名称
git branch dev
切换分支,git checkout 分支名称
git checkout dev
将分支推送到服务器,git push origin 分支名称,选择的要是httts,会要填Github的用户名和密码,要是使用SSH则不会。
git push origin dev
将本地分支跟踪服务器分支 git branch --set-upstream-to=origin/分支名称 分支名称.
主要的作用是:可以知道本地的代码,比服务器的新,还是服务器的比本地的新,以及新几个版本。一般是员工自己的代码和本地的dev和并,在哪本地的dev分支和服务器的dev跟踪。自己写代码的分支不用跟踪。
git branch --set-upstream-to=origin/dev dev
创建并切换分支 git checkout -b 分支名称
git checkout -b itcast
查看所有分支,当前分支前标记为星*
git branch
删除分支
git branch -d 分支名称
git branch -d dev
搭建项目框架
当前项目分支一共有3个,分别为master、dev、itcast,当前在itcast分支上工作
在克隆的目录下创建项目,使用django框架
经理可以把项目共用的部分添加进去,如setting中的配置文件要链接的数据库,静态文件和上传文件的配置,把csrf注销等
将文件代码添加到暂存区
git add ./
将暂存区提交到仓储区
git commit -m '搭建框架'
以上两步运行效果如下图
上传分支
把经理的分支上传到服务器
git push origin itcast
这时候除了经理的分支,有项目框架的代码 ttsx 其余上网都没有,如下图所示
dev 分支没有项目框架的代码 ttsx
在这个阶段,经理要做的就是把itcast的分支合并到共用的dev分支,这样所有的分支就可以从dev分支上取代码.
先切换到dev分支
git checkout dev
将itcast分支的内容合并到当前的分支dev
git merge itcast
把dev分支的内容推送到服务器
git push origin dev
这时服务器的分支dev就有项目ttsx的代码了
员工-开发
项目经理创建完成仓库后,接下来项目组成员就要进行开发工作了
以下操作由每个组员独自完成
添加ssh账户
- 这一步是组员在ubuntu中生成ssh密钥,然后交给项目经理添加到github中
- 在ubuntu的命令行中,修改某台机器的git配置
修改为注册github时的邮箱,填写用户名,要求组员的用户名不能重复
生成git密钥
删除~/.ssh目录,这里存储了旧的密钥
rm -r .ssh
运行如下命令生成密钥
- 在“图标2”处可以填写保存密钥的目录
- 在“图标3”处可以填写密码,如果填写,一般为项目的名称,后续操作时会要求填写此密码
- 公钥名称为id_rsa.pub
- 私钥名称为id_rsa
ssh-keygen -t rsa -C "Github账号,可以是用户名,也可以是邮箱地址"
查看公钥内容,复制此内容
cat id_rsa.pub
将复制的公钥发给项目经理,等项目经理在github上添加后,会将项目地址下发,然后就可以参与到项目开发中进行后续操作
本地克隆
在克隆出来的目录下,隐藏目录.git存储了服务器、分支、文件变更等信息
在这里我是另外的开了一个终端模拟员工
根据项目经理提供的地址,如“git@github.com:bossliu2016/django1.git”,从github上将项目克隆到本地,默认对应的是master分支内容
克隆下来git clone 项目地址
git clone git@github.com:bossliu2016/django1.git
克隆后如下图
之所以没有ttsx的项目那是因为本地的分支默认只有一个master分支,
git branch
将github上的dev分支同步到本地,因为开发过程中,所有组员都向这个分支上提交阶段性代码,并从这个分支获取最新代码,
意思就是根据远程的dev分支创建本地的dev分支
git checkout -b dev origin/dev
员工创建一个自己的分支用于开发,这是在dev分支上创建的,他就拥有dev分支上的内容,而master分支上就没有ttsx的项目
git checkout -b zj
添加
我是在经理(jiangshi)自己用的分支上itcast做的增加,在pycharm中写一些东西如下图,查看增加的信息如下:
git checkout itcast git branch git status
把工作区增加的内容提交到缓存区,完成一个小的单元测试可以git add ./ 一次,可以多次执行 git add ./ 操作.
git add ./
把缓存区的内容提交到版本库中,这里要说明一下,不要频繁的提交,而是完成一个业务提交一次,这是因为不让版本库的日志过多,后期找的麻烦.
git commit -m '创建用户应用'
可以使用git status 命令查看状态
文件删除
首先在物理上把文件给删除了,然后执行git rm 删除文件的路径,主要是告诉版本库,最后执行 git commit -m '删除urls' 提交就行了.版本库就会保存这个操作
在pycahrm中删除urls如下图'
可以用git status 查看当前的状态
git status
版本库中不知道已经把它给删除了,从这个版本中删除
git rm ttsx/ttsx/urls.py
git status
git commit -m '删除urls'
git status
撤销
把删除的东西给恢复过来,只需要回到删除之前的版本就行了,通过 git reser HEAD 或版本号
历史版本的名称:在Git中,用HEAD表示当前版本,版本号为c27e22e,也就是最新的提交,上一个版本就是HEAD^,再上一个版本就是HEAD^^,当然往上100个版本写100个^肯定就麻烦了,提供了一种简写方式为HEAD~100
查看仓库区的历史操作,
git log
git reflog
git reset HEAD^
把仓库区的操作区的记录回到了暂存区的记录
git status
git checkout -- ttsx/ttsx/urls.py
git status
恢复成功,ru下图
对比
对比工作区和仓库区中某版本某文件的不同
git diff HEAD -- 文件名
拿当前的版本库和工作区中的urls进行对比,一致则什么都没有
git diff HEAD -- ttsx/ttsx/urls.py
在这里我删除urls的一条路径在对比
git diff HEAD -- ttsx/ttsx/urls.py
上面的红色表示当前的版本库独有这条路径,而当前的工作区没有这条路径。,白色的内容表示的是共有的
在urls中在增加一条信息如下,在进行比较,这是当前的版本库和工作区中的数据就各有各的不同
git diff HEAD -- ttsx/ttsx/urls.py
git add ./ git commit -m '创建商品应用'
#提交后在比较就一致了 git diff HEAD -- ttsx/ttsx/urls.py git reflog
拿用户的版本和商品的版本中的urls进行对比
git diff d822f0a ce0bfe3 -- ttsx/ttsx/urls.py
回退
- 回退历史版本到暂存区
回到创建用户的版本
git reset ce0bfe3 git status git checkout -- ttsx/ttsx/urls.py git status
对比的目的是为了回退,对比两个版本有什么差异,决定要不要回退.
本地与服务器
把代码提交到服务器,
git branch git push origin itcast
从本地获取服务器上的代码
git branch
git pull
当前是哪个分支,就会从服务器上去拿那个分支的代码
Debug分支
- 在项目的正常开发过程中,之前发布过的版本可能很会出bug,这时就需要停下来现在的开发任务,先去修改bug,完成后再回来继续开发任务
- git中stash提供了保存现场的功能,可以把当前工作区、暂存区中的内容不需要提交而保存下来,转而去做bug修复,完成后再恢复现场,继续开发工作
一个员工正在开发,还没完成,出现了一个bug要解决,下面模拟在开发把一条url注释
工作区并不是干净的,因为功能没做完也不能提交
git status
解决方法是:
保存现场
git stash
git status
在master分支上出bug了,切换到master分支,注意不要直接在master 分支上做修改,要基于master分支新建一个分支如but001.
git checkout master git checkout -b but001
在 but001分支上修改了README,随便写了几句话,就当BUG解决了
git status
git add ./
git commit -m '修改说明的bug'
修改好bug后,切换到master分支上合并修改bug的分支
git checkout master
执行合并前,从服务器上获取一下服务器上的master 代码有可能别人也会在上面修改bug
git pull
这个合并只在修改bug的时候用,因为git 合并的时候默认的是采用 fast forward分支,它本身的记录发生在记录在自己的生上,不会记录在合并后的分支上。
因为在开发过程中,遇到的bug多,不会保留那么多的分支,会把bug后的分支删除,所以会采用 no fast forward合并.
git merge --no-ff -m '修改说明bug' but001
推送到服务器
git push origin master
删除临时分支bug001
git branch -d but001
.
切换回工作分支itcast
git checkout itcast
恢复现场,可以继续开发.
git stash pop
切换到 itcast分支
git checkout itcast
把上面模拟的一条url注释改过来
合并员工开发的代码
这是在另一个终端上,另一个员工zj,写的是商品模块,
git add ./
git commit -m '开发商品应用'
首先把jiangshi的代码合并到dev分支上
git status git branch git checkout dev #为了保持本地的代码和服务器上的一致
git pull git merge itcast
# 看本地有没有要提交的
git status
git push origin dev
把员工zj的代码合并到dev分支上
git branch
git checkout dev # 它从服务器上获取代码,就会把员工jiangsji的代码user获取过来 git pull
合并自己的分支zj, 产生了冲突
git merge zj
上面产生的冲突的主要原因是当前的版本包括user而合并来的分支版本不包括,合并来的分支版本包括goos而当前的版本不包括。
两个员工相互协商后的解决如下:
协商后员工zj可以提交修改后的代码
git add ./ git commit -m '解决url冲突'
把最新的代码提交
git push origin dev
合并完成后每个人员工都获取最新的代码
jiangshi在dev分支上获取最新的代码
git checkout dev git pull
把最新的代码合并到自己的itcast分支
git checkout itcast git merge dev
jiangshi的最新代码既有自己的user也有zj的goods
员工zj也要获取最新的代码
git checkout dev git pull git checkout zj git merge dev
员工zj的最新代码既有自己的good也有jiangshi的users