Git
一、Git简介
1.1 Git历史
- git是目前世界上最先进的分布式版本控制系统
- 林纳斯在1991年创建了开源的Linux
- 在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给林纳斯,然后由林纳斯本人通过手工方式合并代码。(当时的版本控制系统,要么不好用,要么要钱,被林纳斯拒绝了)
- 2002年,代码库之大已经很难手工管理了,而且社区的兄弟也对这种方式不满。一个商业的版本控制系统,授权Linux社区免费使用。
- 2005年,开发Samba的Andrew试图破解BitKeeper的协议,于是授权被收回。
- 林纳斯不想道歉,花了两周用C写了一个分布式版本控制系统Git。一个月之内,Linux源码全部由Git管理。
- 2008年,GitHub上线,它为开源项目免费提供Git存储。
1.2 Git两大特点
- 版本控制: 解决多人同时开发代码问题,解决找回历史代码的问题。
- 分布式: 同一个Git仓库,可以分布到不同的机器上。先让一台电脑当服务器,24小时开机。其他人从服务器仓库克隆一份到自己的电脑上,把各自的提交推送到服务器仓库,也从服务器仓库拉取别人的提交。可以自己搭建服务器,也可以使用GitHub。
集中式与分布式的核心区别:工作电脑如果有代码的完整版本,就是分布式。如果只有要修改的那一部分代码,就是分布式。
二、安装与配置
sudo apt-get install git
- 输入git,出现git命令,表示装好了
三、Git基本操作
1. 版本创建
- 创建版本仓库:
在一个目录里输入git init
进行git初始化
之后它就会借助.git这个文件对这个文件夹进行版本控制
- 给文件设定版本:
- 先有一个需要进行版本管理的文件,比如test.py
- git add test1.py
- git commit -m ‘版本信息’
这里报错了:
解决办法:
写上自己的昵称及电子邮箱
返回上一级目录,重新添加、提交一遍
2. 版本查看
- 查看文件版本:
git log
发生了什么呢?
- 创建第一个版本时,它记录下了版本号,文件名,文件的所有内容
- 创建第二个版本时,它记录下了版本号,文件名,相对于上次内容修改的部分(以后的版本都不会全部记录)
- 查看文件版本(简短)
git log --pretty=oneline
3. 版本跳转
- 回退版本:
git reset --hard 版本指针
- 指向最新版本的指针,叫做HEAD。前一个版本就是HEAD^, 前两个版本就是HEAD^^, 以此类推。
- 前一个版本也可以写成HEAD~1, 以此类推。
- 也可以用版本号进行跳转。例如:跳转回版本2:
- 只要写版本号前几个就行,不用写全
- 查看操作记录:
前面黄色的,就是版本号前几位
4. 工作区&暂存区
- 工作区: 电脑中的目录,比如git_test。
- 版本库: .git 就是一个版本库。
git的版本库里存了很多东西。最重要的就是stage(别名index)的暂存区,还有git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
- git add把文件添加到缓存区
- git commit提交更改,把缓存区所有内容提交到当前分支。
- 查看工作状态:(显示有什么文件被修改之类的)
git status
5. 管理修改&撤销修改
- git管理文件的修改,只会提交暂存区的修改来创建版本
- 撤销修改(取消修改): git checkout – 文件名
- 撤销修改(取消添加到暂存区): git reset HEAD 文件名
6. 对比文件的不同
- 版本文件与工作区文件对比:
---
代表指针指向的文件。+++
代表工作区里的文件
+
代表这一行是工作区的文件新加的。
- 两个版本文件对比: git diff 版本A指针 版本B指针 – 文件名
---
代表HEAD指针,也就是前面那个
+++
代表HEAD^指针,也就是后面那个
7. 删除文件
- rm 文件名
- 删除文件也是工作区的改动。要真正删除,要提交(git rm或git add)。我个人还是习惯git add,删除本质上也是对文件的修改。
四、Git分支
- 分支类似流水线。假如有一个非常长的代码只完成了10%,提交会由于代码不完整让他人无法工作。不提交会面临丢失代码的风险。这时就可以使用分支,先提交到分支,工作完成再合并。
- Git把每次提交串成一条时间线。前面的代码中,只有一个主分支
master 分支
。HEAD严格来说不是指向提交,而是指向master。master才是指向提交的,HEAD指向的是当前分支。
1. 分支基本操作
- 查看有几个分支: git branch
- 创建分支: git branch 分支名
- 创建并切换分支: git checkout -b 分支名
- 切换到master: git checkout master
- 分支合并: git merge 要合并的分支名
快速合并就是,把master的指针移动一下。
- 删除分支: git branch -d 要删除的分支名
2. 分支冲突问题
- 创建一个新分支dev,对文件修改。跳回master,对同一个文件进行修改。请问?还可以快速合并嘛?怎么解决冲突?
它会同时显示两个文件的修改内容。修改再保存提交就好。
改文件相当于在工作区修改。再次提交就行。
- git log --graph --pretty=oneline
- 查看所有分支版本: git log --graph
3. 分支管理策略
3.1 操作不同文件的合并
- 通常,合并分支时,git会采取快速合并模式。但是有些快速合并不能成功,且合并时没有冲突,这时会合并之后并做一次新的提交。
- 比如:对master的文件修改,对分支的另一个文件修改。
随后,会跳转至上述界面。输入版本说明,它会自动地保存
- 输入版本信息。
Ctrl + X
- 输入Y
- 回车
3.2 禁止快速合并
- 在可以快速合并时,禁止快速合并。(此举是为了让其能帮助我们成功地去做一次新的提交。快速合并是直接移动指针,新提交意味着新的版本。)
git merge --no-ff -m “说明信息” 分支名
3.3 Bug分支与工作区储藏
- 软件开发中遇到Bug,一般来说,每一个Bug会建立一个临时分支来修复。Bug修复完,合并分支,删除分支。
- 现在有一个新BUg。如果这之前正在编写,还未提交,并且不能提交时。Git还提供了
stash
功能,可以把当前工作现场“储藏”起来,等以后恢复现场再继续工作。 - 工作区储藏: git stash
- 工作区储藏列表: git stash list
- 工作区弹出储藏: git stash pop
- 需求: 现在在master下,我们正在编辑test.txt文件,可是print_hello.py文件出现了Bug,需要先修复。
先储藏进度,然后切换到出了BUG的分支
注意: 要取消快速合并模式,以反映Bug修复的情况。
五、GitHub
1. 创建GitHub
git会想管理自动创建的文件。因为我们不想让它管理,所以要选择上面的Python。
gitignore里面可以进行修改,以管理想要的文件。
2. 添加ssh
- 添加ssh是为了让机器能与Github上面的仓库交互。
- 右上角头像-settings-ssh
- 打开机器,获取公钥,如图操作:
3. 克隆项目
- 就是从互联网上取项目进行开发
- 先克隆地址
- 在电脑建一个仓库文件夹,cd进去
- git clone 地址
如果克隆出错:(按以下操作)
eval “$(ssh-agent -s)”
ssh-add
4. 推送分支
- 本地上创建分支,本地提交后。
- git push origin 分支名称
- GitHub上如果没有该分支会自动创建
origin指的是远程GitHub服务器
5. 跟踪分支
- 让本地的dev分支跟踪远程的dev分支
- git branch --set-upstream-to=origin/dev dev
- 当分支的本地版本领先于分支的远程版本,可使用git push直接提交
6. 从远程分支上拉取代码
- git pull orgin 分支名
7. 工作中Git职责
- master分支:用户保存发布的项目代码。
- dev分支:保存开发过程中的代码。项目经理一般会给一个时限,在时限结束时,若开发完成,并且跑得起来后,才能上传到服务器中(项目经理控制的)。
1. 项目经理
- 搭建项目框架
- 把项目框架代码放到服务器
2. 普通员工
- 在自己的电脑上,生成ssh公钥。把公钥给项目经理,项目经理把它添加到服务器上面。
- 项目经理给每个组员项目代码的地址,组员把代码下载到自己的电脑上。
- 创建本地分支dev,在dev分支中进行每天的开发。
- 每一个员工开发完自己的代码后,都需要将代码发布在远程的dev分支上。