当前位置:   article > 正文

分布式版本控制工具git

分布式版本控制工具git

1 安装Git

linux上我们建议你用二进制的方式来安装git,可以使用发行版包含的基础软件包管理工具来安装,如果你是
是CentOS或者Fedora的操作系统,可以使用yum命令来安装git

$ sudo yum install git
  • 1

如果你是ubuntu或者是Debian可以使用apt-get的命令来安装git:

$ sudo apt-get install git
  • 1

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
  • 1
  • 2
  • 3

在这里插入图片描述
然后我们让本地仓库和远端仓库进行交互。然后我们再Windows创建一个本地仓库。
在这里插入图片描述
我们远端的地址就是该服务器的ip地址。这里我的是10.150.132.253
本地仓库和远端仓库进行交互需要一个协议。我们通常用的是ssh协议。
SSH协议是一个验证授权的网络协议;
我们将公钥放在服务器,然后每次发送内容的时候以私钥去验证他。

3.1 使用ssh公钥登录git服务器

  1. 生成公钥和私钥(ssh-keygen -t rsa)
    在这里插入图片描述
    回车
    在这里插入图片描述
    输入y,回车,然后还有一个回车
    在这里插入图片描述
    然后我们再Windows中C盘的用户文件夹中的.ssh文件夹中,就生成了公钥和私钥。
    在这里插入图片描述
    然后进入linux中,同样运行
cd ~
cd .ssh
ssh-keygen -t rsa
  • 1
  • 2
  • 3

在这里插入图片描述
复制公钥内容到远端服务器.ssh/authorized_keys
然后touch authorized_keys然后vi authorized_keys,然后将windows中的id_rsa.pub复制到linux中。
在这里插入图片描述
在这里插入图片描述
然后本地仓库就可以免密登录那个远程服务器仓库了。

git clone ssh://用户名@ip地址:仓库的地址
  • 1

如果不知道用户名的话,用命令whoami
在这里插入图片描述
ip地址可以用ifconfig
在这里插入图片描述
目录的话可以用pwd
在这里插入图片描述

git clone ssh://root@10.150.132.253:/usr/src/mathlab
  • 1

在这里插入图片描述
在这里插入图片描述
注意第一次免密登录的话,需要输入yes。如果不行的话,可以尝试将windows中的.ssh删掉,重新生成。
在这里插入图片描述

我们可以将这个文件改个名字在这里插入图片描述
然后我们给这个文件夹设置名字和邮箱。
在这里插入图片描述

 git config user.name lipu123
 git config user.email lipu123@qq.com
  • 1
  • 2

在这里插入图片描述
为了做对比,我们再申请一个。

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
  • 1
  • 2
  • 3
  • 4

这里要注意我们上面都是设置的局部的,如果想要设置全局的话:
局部

git config user.name lipu123
git config user.email lipu123@qq.com
  • 1
  • 2
//下面可以查看
git config --local -l
//配置再这个文件夹中 
.git/config
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

全局

git config --global user.name lipu123
git config --global user.email lipu123@qq.com
  • 1
  • 2

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
  • 1

里面的内容是:

#pragma once

int add(int a,int b);
  • 1
  • 2
  • 3

这时候我们再工作区修改了一个文件。然后我们先把他送到暂存区。
这时候我们可以看看他的状态

git status
  • 1

在这里插入图片描述
这时候这个文件是Untracked(未追踪)的状态。然后我们将这个文件送到暂存区

git add api.h

git status
  • 1
  • 2
  • 3

在这里插入图片描述
然后假设我们还要修改一个文件。

vi add.cc
  • 1

里面内容

#include "api.h"
int add(int a,int b){
	return a+b;
}
  • 1
  • 2
  • 3
  • 4

然后将add.cc提交,这时候暂存区就有两个文件。

git add add.ccc
git status
  • 1
  • 2

在这里插入图片描述
然后我们提交到仓库中:

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"
  • 1

在这里插入图片描述
然后我们再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
  • 1

在这里插入图片描述
然后我们验证一下,进入/mathlab_lipu123,然后我们将远端服务器中的数据拉出来

 cd ../mathlab-lipu123/
 git pull
  • 1
  • 2

在这里插入图片描述
然后我们可以通过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);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然后vi sub.cc

#include "api.h"

int sub(int a,int b){
        printf("a-b=%d",a-b);
        return a-b;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然后我们将这两个修改的问价放在暂存区

git add api.h sub.cc
git status
  • 1
  • 2

这时候我们发现这个文件里面有一处错误,我们需要回退

git restore -S 文件

git restore -S sub.cc

git status
  • 1
  • 2
  • 3

在这里插入图片描述
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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
git add sub.cc
git status
  • 1
  • 2

在这里插入图片描述

本地仓库-> 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
  • 1
  • 2

在这里插入图片描述

git reflog

git reset --soft head^

git status
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

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);
  • 1
  • 2
  • 3
  • 4
  • 5

vi sub.cc

#include "api.h"
int sub(int a,int b){
        return a-b;
}
  • 1
  • 2
  • 3
  • 4

提交

git add sub.cc api.h

git commit . -m "feat:sub func"
  • 1
  • 2
  • 3

然后我们再加一个接口vi api.h

#pragma once

int add(int a,int b);

int sub(int a,int b);

int mul(int a,int b);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

vi mul.cc

#include "api.h"
int mul(int a,int b){
        return a*b;
}
  • 1
  • 2
  • 3
  • 4

然后再提交

git add api.h mul.cc

git commit . -m "feat:mul func"

git log
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
假如说我们要修改上一次并复用上一次提交。
vi mul.cc

#include "api.h"
using namespace std;
int mul(int a,int b){
        cout<<"a*b="<<a*b<<endl;
        return a*b;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后提交复用上次提交的记录

git add mul.cc
git commit --amend
  • 1
  • 2

后面那个命令需要:wq
在这里插入图片描述在这里插入图片描述

整理多次提交(重要)

git rebase -i h1 h2
-i 什么都写就是最近的两次提交
左开右闭

假如说我们需要修改倒数第二次提交。也就是
在这里插入图片描述

 git rebase -i
  • 1

在这里插入图片描述
然后: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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然后提交

git add sub.cc

git commit --amend
  • 1
  • 2
  • 3

也就是我们复用这一次提交,直接保存就行
在这里插入图片描述
然后我们需要退出rebase
因为我们有两部,第一步是e修改,第二步是p选择。
在这里插入图片描述
然后我们git log看一下
在这里插入图片描述
然后我们在实现一个,我们想将最后两次提交合并成一个次提交。
在这里插入图片描述

git rebase -i
  • 1

在这里插入图片描述
然后我们修改
在这里插入图片描述
这时候需要让我们重新写这个提交记录
在这里插入图片描述
之后我们再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
  • 1

在这里插入图片描述
在这里插入图片描述
这时候我们再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);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后再vi div.cc

#include "api.h"
double div(double a,double b){
        return a/b;
}

  • 1
  • 2
  • 3
  • 4
  • 5

然后提交

git api.h div.cc

git commit  . -m "feat:div func"

git push origin master

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
然后我们再另一个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);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

vi mod.cc

#include "api.h"
using namespace std;
int mod(int a,int b){
        cout<<"a%b="<<a%b<<endl;
        return a%b;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后提交

git add api.h mod.cc

git commit . -m "feat:mod func"

git push origin develop
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
这个develop只是一个开发分支,然后我们需要合并到master分支中去
这时候我们需要回到master分支中去然后拉一个最新的,然后再合并

git checkout master

git pull
  • 1
  • 2
  • 3

在这里插入图片描述

然后合并,但是会产生冲突

git checkout develop
git merge master
  • 1
  • 2

在这里插入图片描述
vi api.h这个就是api.h中的冲突
在这里插入图片描述
很明显我们这两个都要要的,所以我们直接删一些东西就行。
在这里插入图片描述
但是现在我们还是一个合并的状态
在这里插入图片描述

git add api.h

git commit -a -m "merge:fix conflict:x"
  • 1
  • 2
  • 3

在这里插入图片描述

总共的步骤:
在这里插入图片描述

git rebase(不建议使用)

删除分支

git branch -d develop1

在这里插入图片描述

解决冲突

在这里插入图片描述
总的
在这里插入图片描述在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/730546
推荐阅读
相关标签
  

闽ICP备14008679号