Git简介
Git是目前世界上最先进的分布式版本控制系统
git的两大特点:
- 版本控制:可以解决多人同时开发的代码问题,也可以解决找回历史代码的问题
- 分布式:Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。首先找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。可以自己搭建这台服务器,也可以使用GitHub网站
- git中存储是变更信息,而不是整个文件
- 点击查看
- 点击查看
- 更多git命令参见
安装
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文件可以参考
*.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.gitcd 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 itcastgit branchgit 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 loggit 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.pygit reflog
拿用户的版本和商品的版本中的urls进行对比
git diff d822f0a ce0bfe3 -- ttsx/ttsx/urls.py
回退
- 回退历史版本到暂存区
回到创建用户的版本
git reset ce0bfe3 git status git checkout -- ttsx/ttsx/urls.pygit status
对比的目的是为了回退,对比两个版本有什么差异,决定要不要回退.
本地与服务器
把代码提交到服务器,
git branch git push origin itcast
从本地获取服务器上的代码
git branchgit pull
当前是哪个分支,就会从服务器上去拿那个分支的代码
Debug分支
- 在项目的正常开发过程中,之前发布过的版本可能很会出bug,这时就需要停下来现在的开发任务,先去修改bug,完成后再回来继续开发任务
- git中stash提供了保存现场的功能,可以把当前工作区、暂存区中的内容不需要提交而保存下来,转而去做bug修复,完成后再恢复现场,继续开发工作
一个员工正在开发,还没完成,出现了一个bug要解决,下面模拟在开发把一条url注释
工作区并不是干净的,因为功能没做完也不能提交
git status
解决方法是:
保存现场
git stashgit 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 statusgit branchgit checkout dev #为了保持本地的代码和服务器上的一致git pullgit 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 devgit pull
把最新的代码合并到自己的itcast分支
git checkout itcastgit merge dev
jiangshi的最新代码既有自己的user也有zj的goods
员工zj也要获取最新的代码
git checkout devgit pullgit checkout zjgit merge dev
员工zj的最新代码既有自己的good也有jiangshi的users