1 安装Git
在linux上我们建议你用二进制的方式来安装git,可以使用发行版包含的基础软件包管理工具来安装,如果你是
是CentOS或者Fedora的操作系统,可以使用yum命令来安装git:
$ sudo yum install git
如果你是ubuntu或者是Debian可以使用apt-get的命令来安装git:
$ sudo apt-get install git
Windows上安装
在 Windows 上安装 Git 也有几种安装方法。 官方版本可以在 Git 官方网站下载。 打开
http://git-scm.com/download/win,会检查你的操作系统是32位的还是64位的,并自动开始下载对应的安装包。
另一个简单的方法是安装 GitHub for Windows。 该安装程序包含图形化和命令行版本的 Git。 它也能支持Powershell,提供了稳定的凭证缓存和健全的换行设置。 你可以在 GitHub for Windows 网站下载,网址为http://windows.github.com。
2 为什么用Git
1.版本管理有一个中央服务器,可以保存所有代码、文档
2.每一次的修改都可以提交到版本库,修改有记录,可追踪
3.不害怕某个同事离职了,代码没有入库
4.本地的代码流失后,可以从版本库检出
5.多人协作,每个同事完成的工作提交到版本库,方便进行集成
6.当我们要开发需求或修复PR时,可以从版本库上拉出分支管理
7.在大的企业,每次提交都可能触发一次构建,实时检查代码的质量
8.如果构建失败了,可以自动revert掉某次提交
分布式与集中式的对比
3. 远程仓库
我们现在远端服务器中初始化一个空的裸的仓库。
mkdir mathlib
cd mathlib
git init --bare
然后我们让本地仓库和远端仓库进行交互。然后我们再Windows创建一个本地仓库。
我们远端的地址就是该服务器的ip地址。这里我的是10.150.132.253
本地仓库和远端仓库进行交互需要一个协议。我们通常用的是ssh
协议。
SSH协议是一个验证授权的网络协议;
我们将公钥放在服务器,然后每次发送内容的时候以私钥去验证他。
3.1 使用ssh公钥登录git服务器
- 生成公钥和私钥(ssh-keygen -t rsa)
回车
输入y,回车,然后还有一个回车
然后我们再Windows中C盘的用户文件夹中的.ssh
文件夹中,就生成了公钥和私钥。
然后进入linux中,同样运行
cd ~
cd .ssh
ssh-keygen -t rsa
复制公钥内容到远端服务器.ssh/authorized_keys
然后touch authorized_keys
然后vi authorized_keys
,然后将windows中的id_rsa.pub
复制到linux中。
然后本地仓库就可以免密登录那个远程服务器仓库了。
git clone ssh://用户名@ip地址:仓库的地址
如果不知道用户名的话,用命令whoami
ip地址可以用ifconfig
目录的话可以用pwd
git clone ssh://root@10.150.132.253:/usr/src/mathlab
注意第一次免密登录的话,需要输入yes。如果不行的话,可以尝试将windows中的.ssh
删掉,重新生成。
我们可以将这个文件改个名字
然后我们给这个文件夹设置名字和邮箱。
git config user.name lipu123
git config user.email lipu123@qq.com
为了做对比,我们再申请一个。
git clone ssh://root@10.150.132.253:/usr/src/mathlab mathlab_lipu
cd mathlab_lipu/
git config user.name lipu
git config user.email lipu@qq.com
这里要注意我们上面都是设置的局部的,如果想要设置全局的话:
局部
git config user.name lipu123
git config user.email lipu123@qq.com
//下面可以查看
git config --local -l
//配置再这个文件夹中
.git/config
全局
git config --global user.name lipu123
git config --global user.email lipu123@qq.com
git的原理
git的原理 - git的四个区域
Workspace: 工作区,就是你平时存放项目代码的地方
Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
git原理 – 工作流程
git的工作流程一般是这样的:
1、在工作目录中添加、修改文件;
2、将需要进行版本管理的文件add到暂存区域;
3、将暂存区域的文件commit到git仓库;
4、本地的修改push到远程仓库,如果失败则执行第5步
5、git pull将远程仓库的修改拉取到本地,如果有冲突需要修改冲突。回到第三步
因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)
git原理 – 文件的四种状态
Untracked: 未跟踪, 此文件在文件夹中,但并没有加入到git库,不参与版本控制, 通过git add 状态变为Staged。
Unmodify: 文件已经入库且未修改, 即版本库中的文件快照内容与文件夹中完全一致,这种类型的文件有两种去处,如果它被修改, 而变为Modified,如果使用git rm移出版本库, 则成为Untracked文件。
Modified:文件已修改,仅仅是修改,并没有进行其他的操作,这个文件也有两个去处,通过git add可进入暂存staged状态,使用git checkout 则丢弃修改,返回到unmodify状态, 这个git checkout即从库中取出文件,覆盖当前修改
Staged:暂存状态,执行git commit则将修改同步到库中,这时库中的文件和本地文件又变为一致,文件为Unmodify状态。
提交一个修改
首先建立一个api.h
vi api.h
里面的内容是:
#pragma once
int add(int a,int b);
这时候我们再工作区修改了一个文件。然后我们先把他送到暂存区。
这时候我们可以看看他的状态
git status
这时候这个文件是Untracked(未追踪)的状态。然后我们将这个文件送到暂存区
git add api.h
git status
然后假设我们还要修改一个文件。
vi add.cc
里面内容
#include "api.h"
int add(int a,int b){
return a+b;
}
然后将add.cc提交,这时候暂存区就有两个文件。
git add add.ccc
git status
然后我们提交到仓库中:
git commit file1.name file2.name file3.name … –m “commit messages”
commit指提交修改到本地的仓库里,file*.name指的是带commit的文件 –m后面的内容指提交的信息,即备注,也就是说日志
注意我们不加文件名字,只加一个点的话,是提交所有文件
git commit . -m “commit messages”
这里我们用的命令是这个
git commit add.cc api.h -m "lipu:add func"
然后我们再git status发现没有什么需要提交的了。
这时候的那两个文件存在本地服务器中,也就是这张图的Repository,我们需要将文件存到远端服务器中,也就是Remote中。
git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相仿。
git push <远程主机名> <本地分支名>:<远程分支名>
注意,分支推送顺序的写法是<来源地>:<目的地>,所以git pull是<远程分支>:<本地分支>,而git push是<本地分支>:<远程分支>。例如:
git push origin master:refs/for/master
如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。
git push origin master
上面命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
git push origin :master # 等同于 git push origin --delete master
上面命令表示删除origin主机的master分支
如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。
git push origin
上面命令表示,将当前分支推送到origin主机的对应分支。
如果当前分支只有一个追踪分支,那么主机名都可以省略。
git push
git push origin master
然后我们验证一下,进入/mathlab_lipu123,然后我们将远端服务器中的数据拉出来
cd ../mathlab-lipu123/
git pull
然后我们可以通过git log
查看提交日志。
这个
总结
这就是我们一个完整的提交流程。我们再工作区写代码,然后我们可以通过git.add将修改的代码提交到暂存区,然后,通过git.commit将暂存区的东西提交到本地仓库,然后,通过git.push将本地仓库里的东西提交到远端仓库。
操作
基本操作
- 暂存(git add)
- 提交(git commit):区分不同类别的修改
- 推送(git push)
- 拉取(git fetch):将远程仓库所包含分支的最新commit-id记录到本地文件
- 拉取合并(git pull)
- git fetch
- git merge
- 查看状态(git status)
- 查看历史(git log)
- git reflog
逆向操作
index -> workspace
git restore -S
我们需要新增加一个文件,vi api.h
#pragma once
int add(int a,int b);
int sub(int a,int b);
然后vi sub.cc
#include "api.h"
int sub(int a,int b){
printf("a-b=%d",a-b);
return a-b;
}
然后我们将这两个修改的问价放在暂存区
git add api.h sub.cc
git status
这时候我们发现这个文件里面有一处错误,我们需要回退
git restore -S 文件
git restore -S sub.cc
git status
vi sub.cc
#include "api.h"
#include<iostream>
using namespace std;
int sub(int a,int b){
cout<<"a-b="<<a-b<<endl;
return a-b;
}
git add sub.cc
git status
本地仓库-> index,workspace,null
退到index
git reset --soft head^
退到workspace
git reset --mixed head^
直接删掉
git reset --hard head^
这个日志号可以通过
git reflog查看
我们先将上面两个文件提交到本地仓库
git commit api.h sub.cc -m "feat:sub func"
git status
git reflog
git reset --soft head^
git status
workspace->null
git checkout .
git checkout – file .
git checkout -f .
本地仓库整理操作
整理上一次提交
git commit --amend
相同功能多次提交复用上次提交信息
vi api.h
:
#pragma once
int add(int a,int b);
int sub(int a,int b);
vi sub.cc
#include "api.h"
int sub(int a,int b){
return a-b;
}
提交
git add sub.cc api.h
git commit . -m "feat:sub func"
然后我们再加一个接口vi api.h
:
#pragma once
int add(int a,int b);
int sub(int a,int b);
int mul(int a,int b);
vi mul.cc
#include "api.h"
int mul(int a,int b){
return a*b;
}
然后再提交
git add api.h mul.cc
git commit . -m "feat:mul func"
git log
假如说我们要修改上一次并复用上一次提交。
vi mul.cc
#include "api.h"
using namespace std;
int mul(int a,int b){
cout<<"a*b="<<a*b<<endl;
return a*b;
}
然后提交复用上次提交的记录
git add mul.cc
git commit --amend
后面那个命令需要:wq
整理多次提交(重要)
git rebase -i h1 h2
-i 什么都写就是最近的两次提交
左开右闭
假如说我们需要修改倒数第二次提交。也就是
git rebase -i
然后:x
这时候我们就进入了这个rebase
这时候我们修改vi sub.cc
#include "api.h"
using namespace std;
int sub(int a,int b){
cout<<"a-b="<<a-b<<endl;
return a-b;
}
然后提交
git add sub.cc
git commit --amend
也就是我们复用这一次提交,直接保存就行
然后我们需要退出rebase
因为我们有两部,第一步是e
修改,第二步是p
选择。
然后我们git log
看一下
然后我们在实现一个,我们想将最后两次提交合并成一个次提交。
git rebase -i
然后我们修改
这时候需要让我们重新写这个提交记录
之后我们再git log
分支操作
查看分支
git branch
创建分支
git branch develop
这个develop是一个分支名字
git checkout -b develop
这个也是创建一个分支,并且切换到那个分支中去
切换分支
git checkout develop
develop是分支名字
git switch develop
这个也可以
合并操作
git merge
我们之前都是再lipu123,然后我们进入lipu拉取全部代码
git pull
这时候我们再master分支操作的。我们将master进行操作一步,然后我们合并另一个develop分支。然后我们再lipu中vi api.h
#pragma once
int add(int a,int b);
int sub(int a,int b);
int mul(int a,int b);
double div(int a,int b);
然后再vi div.cc
#include "api.h"
double div(double a,double b){
return a/b;
}
然后提交
git api.h div.cc
git commit . -m "feat:div func"
git push origin master
然后我们再另一个develop分支中:
vi api.h
#pragma once
int add(int a,int b);
int sub(int a,int b);
int mul(int a,int b);
int mod(int a,int b);
vi mod.cc
#include "api.h"
using namespace std;
int mod(int a,int b){
cout<<"a%b="<<a%b<<endl;
return a%b;
}
然后提交
git add api.h mod.cc
git commit . -m "feat:mod func"
git push origin develop
这个develop只是一个开发分支,然后我们需要合并到master分支中去
这时候我们需要回到master分支中去然后拉一个最新的,然后再合并
git checkout master
git pull
然后合并,但是会产生冲突
git checkout develop
git merge master
vi api.h
这个就是api.h中的冲突
很明显我们这两个都要要的,所以我们直接删一些东西就行。
但是现在我们还是一个合并的状态
git add api.h
git commit -a -m "merge:fix conflict:x"
总共的步骤:
git rebase(不建议使用)
删除分支
git branch -d develop1
解决冲突
总的
在这里插入图片描述