哈喽 大叫好,我叫人宅 很高兴和大家分享一下 我自己写的git小程序。
这个是人宅版本的git 实例 ,我把它放在了OSS服务器上 (如果对OSS服务器感兴趣的小伙伴可以点击 阿里云OSS服务器课程)
源码版本需要额外购买(如何购买过手把手入门c语言的 的同学请联系人宅帮您免费开通git),但是发布的实例是免费的:
https://renzhai.net/262.htmlrenzhai.net![bc2588bb570ed030a2aa415e1b1e7773.png](https://i-blog.csdnimg.cn/blog_migrate/63aba8067f971e234ab7d9679f75e496.png)
如下:
![3b9371836b09932ee317e9fa0faf1160.png](https://i-blog.csdnimg.cn/blog_migrate/b6d276aa3bdf9d55244d6df370cf4f50.jpeg)
下载成功后,解压打开git 可以看到如下文件
![3a3619cfc2a047e331bab11c6376861c.png](https://i-blog.csdnimg.cn/blog_migrate/b164671e9517cf1b5e11016c35b493a9.png)
这个程序比较小众,估计也没多少人看~_~
不管怎么样 还是要解释一下如何测试这个程序,因为这个renzhai版本的git版本控制还有很多可以学习的内容。
1.install.bat :安装的意思是模仿git 的安装点击后会自动安在菜单上,如下:
![0b1aea3d1a383614aac4f1a1d6e46007.png](https://i-blog.csdnimg.cn/blog_migrate/f5ca9a689d388f9f560412a306e8b254.png)
2.uninstall.bat 直接可以从菜单上移除掉。
3.这里我建立了三个文件
![259d017658cb0e991501f882135d5098.png](https://i-blog.csdnimg.cn/blog_migrate/029f6c138b342af11938502c10ff1dad.png)
client1 //用户2
client2 //用户1
server //git 服务器存储的位置
4.先启动服务器,服务器的启动非常简单,只需要将图中的gitrenzhai_server.exe拷贝到你的server文件里面 作为仓库;
![eeaa5bed0f6c40588a4fd2d17a7751db.png](https://i-blog.csdnimg.cn/blog_migrate/d0ef2199404e08018260f15dd228073f.png)
![03246efa9fe43bf949deba0dd8001a88.png](https://i-blog.csdnimg.cn/blog_migrate/45f7fbd34fce7554152a0ccd3bf9caed.png)
5.双击运行,服务器就算是启动了,非常简单。
![4893bf9a45a90950d7f5143d8b608bd8.png](https://i-blog.csdnimg.cn/blog_migrate/6ab804cef2ac2502500f4b3ce14c762a.png)
6.启动后会自动生成以下文件:
![8819377c00cdc4ce01783491e3fe8d81.png](https://i-blog.csdnimg.cn/blog_migrate/0c908f96637a73b9d4fb852cd90b05fd.png)
其中:
.git //里面存储着git相关信息,比如用户提交信息,用户各个版本信息,用户具体版本等,我们稍后会分析
git_server //
log //服务器本地日志
README.txt //基础操作
打开.git
![c42d3312c61c66c835010c65d7022d53.png](https://i-blog.csdnimg.cn/blog_migrate/0701ddfd2a4e4bd83f6918cdcb6c4383.png)
其中有以下信息
- version 这里面存放着各个上传版本的具体内容
- DO8D1043....CD.... 这个是上传具体版本里面的文件列表
![226eb145b72a6e1e9ebef82a373be0b2.png](https://i-blog.csdnimg.cn/blog_migrate/eeebecf527ba71b75d5cc72f28112d70.png)
第一个是上传的类型 是覆盖还是删除还是添加
第二个是filename
第三个是crc 校验码
第四个是文件大小 以字节为单位
- file_list.file //当前文件的文件列表
- ignorepath.ig //忽略的路径
- igore_suffix.ig //忽略的后缀
- version.list //各个版本的列表
服务器启动完毕后就可以启动客户端
![308188fbc9ebc44dad85d629ad112413.png](https://i-blog.csdnimg.cn/blog_migrate/cc69e2e73cebd35b620a0fdfe97389c2.png)
7.先进入client1
![1a3301b6e88f60c227a31153046e6ee8.png](https://i-blog.csdnimg.cn/blog_migrate/2ac5cb7678e272564ea556e671f888c6.png)
8.鼠标右键启动客户端
![47bb0c1baf4c1c28e00b76c931e5141c.png](https://i-blog.csdnimg.cn/blog_migrate/b7e81dc761d681b06ac910141ed1e5d0.png)
9.我们现在启动了一个客户端,通过git init 命令初始化一个仓库:
![fb7461cc0d00cdc9cef0e7d2aeba3867.png](https://i-blog.csdnimg.cn/blog_migrate/004182354c10a7bdc763fa8452d607b2.png)
此时客户端会生成如下内容:
![461881ba62cfea8b24914d500a78eef6.png](https://i-blog.csdnimg.cn/blog_migrate/ec86fdb545ff4812e9701e1ac3e314f0.png)
.git //记录着客户端本地信息
git_client //
log //客户端本地日志
10.打开客户端.git
![dfc5b03320f2dbe96df7c617b6a6abd2.png](https://i-blog.csdnimg.cn/blog_migrate/95d4d1b880936986551dcfd1635059a7.png)
里面生成了三个文件
git.txt //为git 进行git定位
ignore_path.ig // 本地忽略的路径,防止上传不合法的内容
ignore_suffix.ig //忽略的文件的后缀
11.我们可以通过git --help的命令了解更多命令
![054958fa8421782f5f96c26a0311ae23.png](https://i-blog.csdnimg.cn/blog_migrate/f3377cb58e12e5932950d557cb15548d.jpeg)
12 我们可以通过git --global user.name 来注册一个用户的名称这里以人宅为例子:
![199f7200b1079f87fa6daa837493ee2d.png](https://i-blog.csdnimg.cn/blog_migrate/a20a211c414b70e869c4736c907f8d8e.png)
13 我们可以通过git --global user.email 来注册一个用户的邮箱:
![fd56ccd38cdeebc70bd9f5453d28fdb1.png](https://i-blog.csdnimg.cn/blog_migrate/0e5106aa85658f3da261147c2d4c1e98.png)
14 然后就是拉去服务器的数据版本,这里我推荐两种方法,这两种方法都可以实现拉取~
方法一:
![3602b637574346ec8380d22bb05b740b.png](https://i-blog.csdnimg.cn/blog_migrate/9404511980250f2efe9437e633798bc1.png)
git remote add origin 【 URL】 // 这里的URL是服务器的路径 URL = M:Server
git pull // 拉版本
![7d935e6f6ff71406b76c4db7147687f4.png](https://i-blog.csdnimg.cn/blog_migrate/31d19f1badd2b8c94f660ed9982ef2dd.jpeg)
方法二
git clone【 URL】 // 这里的URL是服务器的路径 URL = M:Server
![0a2e6c9fb4e5e83baf354e336fceacbb.png](https://i-blog.csdnimg.cn/blog_migrate/0518b03bc94b67683f30ceeef18df7da.jpeg)
当我们进行更新后 我们可以看到客户端文件的变化:
![509142ec66106f085dadaafe0c30b1e3.png](https://i-blog.csdnimg.cn/blog_migrate/7e3fdfe885b2a20a14bacab7605fb966.png)
成功的拉取了服务的README.txt,并且在.git里面多了如下的内容:
![bae19181724bc46c373955f602a4ef73.png](https://i-blog.csdnimg.cn/blog_migrate/e7bd02f23171114c529da2d5525ff19f.png)
git_user.ini 里面存储着当前客户端账户信息:
![28bce259f3c5c2bac150ae885903b558.png](https://i-blog.csdnimg.cn/blog_migrate/cb612870674dc0bd0c932eee297b798f.png)
version.info 里面存储着当前最新版本提交的信息:
![68af1b288f4c2db7749c251798e906f4.png](https://i-blog.csdnimg.cn/blog_migrate/83f0947e7dbf0f46b0906e7884c8ef4a.png)
里面存储着当前最新版本列表 因为我们只拉去了服务器的一条数据 README.txt,如果有多条,这里面将显示多条数据:
![6fd18712ac947b0185ef01805ca0188c.png](https://i-blog.csdnimg.cn/blog_migrate/c6d72fe15f047854d11d4c47027a3c73.png)
现在 我们在客户端放置一个测试文件 这个文件是SimpleThread UE4插件的源码:
![0994734cb8a03fcbf2fdccf07b8b0886.png](https://i-blog.csdnimg.cn/blog_migrate/95178fb8593a25765dc5b9b9f830798d.png)
15我们需要将数据发送到服务的,作为一个新的版本,其他用户会更新你上传的这个版本。你可以通过git add Source 和 git add . 这两种命令进行添加:
方法一:
![a4e6f60f4e83fd8f869c750aa6205e6e.png](https://i-blog.csdnimg.cn/blog_migrate/21a83fd0e474cc1e7765ab9ff61efb43.png)
方法二:
![820d7dddda1e8c00be1fde7950bd4a4f.png](https://i-blog.csdnimg.cn/blog_migrate/00320520839cc3e97ab2aa1392b15581.png)
git add [文件名称] //添加文件下所以子文件的子文件
git add .// 添加当前目录下的所有文件
16 添加好后我们可以通过git commit -m "你提交的内容" 描述你提交此次版本的内容;
![cf9c10ea4289dae16d039a453a3bab5b.png](https://i-blog.csdnimg.cn/blog_migrate/c7a2e5fea018687453ac93ee6a432970.png)
这一步很关键,如果没有这一步 后面的提交将是失败的。
17 最后我们通过git push 将数据发送到远端的服务器;
![ca8926ce7e361bb95e811920fb95951b.png](https://i-blog.csdnimg.cn/blog_migrate/2351f79871352764c0804e7a31ae17ba.jpeg)
你也可以通过git push -u origin master 这个命令来完成推送,当前的小程序暂时不考虑分支方面的操作;
![e207f31fb9cf5ff7c8dd92232eadb091.png](https://i-blog.csdnimg.cn/blog_migrate/99a6630fdf56523c0427acf31be8b9fb.jpeg)
现在我们来看看服务的,是不是多了一个Source ?我们已经完成了一个文件的推送;
![7aec72f44088f344dbe7bb54d1a5ba81.png](https://i-blog.csdnimg.cn/blog_migrate/cc3d32205c5191c609ce0f2c9c46ca02.png)
18 我们可以通过git status 来查看客户端当前版本文件的变动情况:
![d0d71efa95c1877956c689ced9d58fa6.png](https://i-blog.csdnimg.cn/blog_migrate/1bc2d0c6843c3b9f9ecdb53186aacb2b.jpeg)
![4eef8d52cab60ae372688ab7b8d0003a.png](https://i-blog.csdnimg.cn/blog_migrate/0370ce7946b5a764af3bc2943215d7f1.jpeg)
19 测试一下 删除和更新 观察服务的变化,这里我删除该文件内的Coroutnes和Runnable 并且将ThreadManage.h的大小进行改变:
![24bcf4fbbdc2c0888a723e052386208e.png](https://i-blog.csdnimg.cn/blog_migrate/ea3c0898cc55a82306345c4ea5132905.png)
我们现在对Source里面的内容进行提交 查看变化情况;
![52256e204d98500b0ed78deacf4e3be7.png](https://i-blog.csdnimg.cn/blog_migrate/d7f4be03c9f1f89b8cdb76ed110aa617.png)
我们现在已经对服务器上的数据进行了修改。从表中我们可以看到我们已经移除了服务器指定的数据,并且我们的git也成功的检测出文件的变化,只更新有变化的文件;
![e12041d53c5722327435af9d35b21428.png](https://i-blog.csdnimg.cn/blog_migrate/24f689f68784961ed66eb332a7e37e39.jpeg)
现在,我们通过git status 来查看当前版本的文件变化:
![3510a1cb8f0de71d46d484bbbd8d889f.png](https://i-blog.csdnimg.cn/blog_migrate/ed9b225526e5ef2588c779510cbb382a.png)
这个小程序 我做了特殊处理,覆盖用灰色,红色代表移除 蓝色代表添加;
我们先看看版本提交的情况,我们可以通过git log来查看 历史提交情况;
![0a33b5bc69a7a4b7906e4bd62cfe433c.png](https://i-blog.csdnimg.cn/blog_migrate/c5422b2ba4aae8258b1680d7e3ce7bd9.jpeg)
我一共提交了两次,可以清晰的看到提交人和提交信息 以及提交的日期;第一个提交是服务器提交的,这个是默认提交内容,只要开启服务器 会自动生成一个。
现在,我们按照这种方法试一下另外一个客户端,看看它们是否可以协调工作。
打开客户端2,我们能清楚的看到这个客户端:
![a27faf6050431a4cc8c19388416e8e72.png](https://i-blog.csdnimg.cn/blog_migrate/48119304b3457f3aa88cbac3ebacffdc.png)
先git init 初始化一个仓库;
再通过 git --global user.name 注册一个名字
最后用git clone 拉取服务端的数据内容。
![695ac7aba6cb482851f117d6ae408d7b.png](https://i-blog.csdnimg.cn/blog_migrate/ca8fa3bac878414e5a8ca98764a5cb91.jpeg)
client2已经成功的将数据从服务器拉去到了
![4c0976c449b00229a1b14c9227aa0870.png](https://i-blog.csdnimg.cn/blog_migrate/c1db303d297a819d2a30ea28705f34f9.png)
我们现在有两个客户端 一个是人宅 一个是小白;
![8f7dcdffccf3ea4e9ee7c9f7abc15a74.png](https://i-blog.csdnimg.cn/blog_migrate/51934f2333bc917748a9c1d12fea8938.jpeg)
正常操作中 我们需要这两个客户端不停提交版本,更新版本,方便工作中相互协作,相互合作,那么我们来测试一下迭代更新。
现在小白完成了他的模块 需要提交文件,我们来看看他的操作;
20 我们复制了一份 public 并且 把 Private整体删除;
![0460fd209f46d256c4f7c2ffc0e2fa41.png](https://i-blog.csdnimg.cn/blog_migrate/2bc7b57fdbdd38f51b9561866fa9eab1.png)
最后我们进行提交;
![ffb85f69ff7861ef428c05ef60def238.png](https://i-blog.csdnimg.cn/blog_migrate/5ce344b75d5781f569c1084a390060d6.jpeg)
21 因为数据太多,我们可以通过git status 来查看上传版本的文件具体行为。
![8636647141c5dd34350c086427f8ad54.png](https://i-blog.csdnimg.cn/blog_migrate/ab81f8cb56854328ca881bf03af3cb03.jpeg)
可以看到我们删除了Private 上传了 Public - 副本;
可以看看我们的服务端情况:
![1f6021cc9b3cdb6c398a70badd86b56c.png](https://i-blog.csdnimg.cn/blog_migrate/625648450eb9cfc273cf70be437916a5.png)
和客户端2的结构吻合。
现在我们来到客户端1(人宅) 进行更新。
![abec8477c9761ab1114a43bf38a27fb2.png](https://i-blog.csdnimg.cn/blog_migrate/ac00bde8caa2d0ee2c549a8130870fb4.jpeg)
客户端本地数据信息:
![403481cf626f81837d85240238806fa3.png](https://i-blog.csdnimg.cn/blog_migrate/17062a5c3b6b13a0d690cbcda14eede0.png)
22.最后 我们还剩下一个冲突的测试 如果客户端一提交了版本数据 ,而客户端2修改了本地文件,这个时候客户端2进行更新,更新的文件刚好是客户端1提交的内容,这样就报错了,这个就是一个冲突,我们的git经常有这方面的错误提示,现在我们来测试一下:
还是原来的文件,我们对SimpleThread.build.cs这个文件做一些操作,把它变大;
![4abdc1d3147d68624f9a39ef22883c47.png](https://i-blog.csdnimg.cn/blog_migrate/4c6cfa7aae8ba888466329f98d4a1671.png)
3 KB - 11KB
![55a6a7812c06b02ddc71befcfe64f0f7.png](https://i-blog.csdnimg.cn/blog_migrate/c44088dd5225078b3e37335f06713d95.png)
现在我们来提交 客户端1的内容:
提交的信息如下:
![c62f988d904863f0f7754a10c37f8db8.png](https://i-blog.csdnimg.cn/blog_migrate/1b576edec53ec6ee7ec270d710583ea7.jpeg)
我们现在对客户端2内容进行修改 :
![103f6edca8282f7a21028b837eb8efd1.png](https://i-blog.csdnimg.cn/blog_migrate/dfd8dd44648edb7fbfd56fa573ba1d24.png)
我们现在更新客户端2
![f56b2b9ab744b26c8fc97f67b914aa19.png](https://i-blog.csdnimg.cn/blog_migrate/477d431c79e04273f0e4844f23708eaf.png)
显示我们的客户端2其中SimpleThread.build.cs发生了错误,本地和服务端产生冲突 需要解决。
![8cf8c7392688201bf025cfc4252d9070.png](https://i-blog.csdnimg.cn/blog_migrate/5d804667fe99a3e7a644a2382219069c.png)
解决方法很简单 备份本地数据 重新拉去服务器最新数据 ,将修改的数据复制到服务器最新版本,提交即可,这个是git传统的操作方案。git并不像SVN那样可以进行代码行的合并。
现在我们来删除这个文件,这样,就可以获取服务器更新的数据,冲突也就解决了。
![86ba831daaf3e74d896784ef3d3b06cc.png](https://i-blog.csdnimg.cn/blog_migrate/1242009d5f8e64f7286c999b01b3e4fc.png)
拉取版本:
![d4b9ff58b23e1f186bd00a65dbb6b029.png](https://i-blog.csdnimg.cn/blog_migrate/ed91a0eaadf87637f107cc1c68ce5107.jpeg)
解决了冲突:
![ed9158fb7d377d0348ac862a73bbc84d.png](https://i-blog.csdnimg.cn/blog_migrate/96395c91b73d36b9a4a287eb8bba8ffa.png)
我们来查看一下提交信息;
![62b2d9d1e5c288ff16b3343893e6b00f.png](https://i-blog.csdnimg.cn/blog_migrate/1758c02989a227467de7ad90881af41d.jpeg)
具体提交的状态:
![48ce09381248cb37001b099161934880.png](https://i-blog.csdnimg.cn/blog_migrate/3683d006c7697964bd2c52c358d312b5.png)
现在我们把问题搞的复杂一些 来全面测试该程序
现在我们对客户端1 的SimpleThreadPlatform.h和ThreadManage.h进行删除 并且修改了文件SimpleThread.h
![09e88a42434ca4e272e3cb9515bdf420.png](https://i-blog.csdnimg.cn/blog_migrate/fff464bb41279d3536c1d9af96fef799.png)
整个文件修改后变成了这样~
![e3dfa91e446912535ec1031bb00d1e3d.png](https://i-blog.csdnimg.cn/blog_migrate/0951e2c5c6229d1ad1b2b6153f74b5f3.png)
现在我们提交一下客户端1
![7603b63f8e6d55ab17d7f550079e67b3.png](https://i-blog.csdnimg.cn/blog_migrate/480fcae4be1ee6597083e7f46268586d.jpeg)
现在我们再添加再删除,准备一个版本;
![61d1f1afa649dd6af6024df07f1feb2d.png](https://i-blog.csdnimg.cn/blog_migrate/2613d3f56a85258fc6a2e4cc85f15d98.png)
再上传
![68a474ec67eb07d047b76797bfd666fc.png](https://i-blog.csdnimg.cn/blog_migrate/aa9d8eb062a82c12e88a3266aa83757a.jpeg)
最后我们移除这些文件
![bee0236b54a705cc275747a6e765a40b.png](https://i-blog.csdnimg.cn/blog_migrate/8ca8fc6eb46aaba496f2d258f0305160.png)
客户端1再上传
![ff5ed5133d8e3f71da69016a4bdd8c67.png](https://i-blog.csdnimg.cn/blog_migrate/489701015d1b45427575770818c50e8a.jpeg)
人宅客户端1上传了 好几个版本,现在我们来看看客户端2小白的更新情况。因为实际项目中比这个更复杂,这种测试是必要的。
大家应该按照操作,可以看到相应的结果,感谢抽时间看到这么远;
服务器源码.h:
#pragma once
//Copyright (C) RenZhai.2019.All Rights Reserved.
//作者 人宅
//该c库的详细源码讲解在AboutCG 《手把手入门硬核c语言》视频工程里面:
//https://www.aboutcg.org/courseDetails/902/introduce
//希望学习其他方面技术 比如做UE4游戏, 可以访问下列网址:
//https://zhuanlan.zhihu.com/p/60117613
//
//bibi可以看到各个人宅系列教程介绍:
//https://space.bilibili.com/29544409
//
//个人博客网站
//http://renzhai.net
//
//关于本套案例的详细操作 :
//文字版本(详细):
//https://zhuanlan.zhihu.com/p/144558934
//视频版本:
//https://www.bilibili.com/video/BV1x5411s7s3
#include "protocal_type.h"
char git_project_path[MAX_PATH] = { 0 };
char git_version_list_filename[MAX_PATH] = { 0 };
char git_version_filename[MAX_PATH] = { 0 };
char git_server_cache_path[MAX_PATH] = { 0 };
char git_path[MAX_PATH] = { 0 };
char git_version_path[MAX_PATH] = { 0 };
char version_tmp[MAX_PATH] = { 0 };
//具体文件在服务器的状态
typedef struct
{
bool b_exit;
char filename[MAX_PATH];
simple_c_guid crc;
unsigned int filesize;
}ffile_info;
//文件列表
typedef struct
{
int size;
ffile_info data[8196];
}ffile_list;
ffile_list file_list;
typedef struct
{
int size;
char data[MAX_PATH][1024];
}fpath;
fpath ignore_path,ignore_suffix;
//提交版本的信息
typedef struct
{
char name[MAX_PATH];
char commit[MAX_PATH];
char date[MAX_PATH];
simple_c_guid guid;
}fgit_commit;
typedef struct
{
unsigned int size;
fgit_commit commits[1024];
}fgit_commits;
fgit_commits commits;
//文件版本操作类型
typedef enum
{
NONE_File,
ADD_FILE,
SUBTRACT_FILE,
OVERLAP_FILE,
}eversion_operation_type;
//单个文件的版本
typedef struct
{
eversion_operation_type operation_type;
unsigned int file_size;
char file_name[MAX_PATH];//
simple_c_guid crc;
}fgit_version;
//整体文件的版本
typedef struct
{
unsigned int size;
fgit_version paths[2048];
simple_c_guid crc;
}fgit_versions;
//整体文件版本列表
typedef struct
{
unsigned int size;
fgit_versions paths[1024];
}fgit_versions_list;
fgit_versions_list versions_list;
void init_path(fpath* p);
void string_to_path(const char* data, fpath* p);
void path_to_string(char* data, const fpath* p);
void init_commit(fgit_commit *out_commit);
void init_versions(fgit_versions *in_versions);
int get_index_by_commit(const char* client_crc, fgit_commit** out_commit);
int get_nest_index_by_commit(const char* client_crc, fgit_commit** out_commit);
const char *get_git_version_path();
const char *get_git_version_crc_path(const char *crc);
void compare_list_v(const fgit_versions* in_versions_a, const fgit_versions* in_versions_b, fgit_versions* out_versions_add, fgit_versions* out_versions_remove);
void compare_list(const fgit_versions* client_version_list, const def_c_paths* local_paths, def_c_paths* out_paths);
fgit_versions* find_versions(const simple_c_guid *crc);
fgit_versions* get_newest_versions();
void save_newest_versions(const char *crc_buf);
const fgit_commit* get_newest_commit();
char *git_commit_to_string(const fgit_commit *git_commit, char *buf);
void string_to_git_commit(fgit_commit *git_commit, const char *buf);
void string_to_git_commits(fgit_commits *git_commit, const char *buf);
void commits_to_string(const fgit_commits *git_commit, char *buf);
void string_to_ignore_path(const char *buf);
void string_to_ignore_suffix(const char *buf);
void def_c_paths_to_versions(const def_c_paths * c_paths, fgit_versions *v_version);
void versions_to_string(char *buf, const fgit_versions *in_versions);
void string_to_versions(const char *buf, fgit_versions *in_versions);
void commits_to_versions(const fgit_commits *git_commit, fgit_versions_list *in_versions);
const struct simple_c_guid *find_file_list_crc(const char *fliename);
unsigned int find_file_list_filesize(const simple_c_guid *crc);
const char* find_file_list_filename(const simple_c_guid* crc);
ffile_info* find_file_list_version_crc(const simple_c_guid* crc);
ffile_info* find_file_list_version_by_filename(const char* fliename);
int find_file_list_version_by_index(const char* fliename);
bool is_exit_filename_in_filelist_by_filename(const char* fliename);
bool is_exit_filename_in_filelist_by_crc(const simple_c_guid* crc);
void init_file_info(ffile_info* info);
void init_file_list();
void save_file_list();
void read_file_list();
void add_files_list_unique(const fgit_versions *v);
void add_file_list_unique(const fgit_version* git_version);
void remove_file_list_unique(const ffile_info* fi);
void add_file_list(const fgit_version * git_version);
void replace_file_list(int index ,const fgit_version* git_version);
void replace_file_list_s(ffile_info *info, const fgit_version* git_version);
bool add_file_list_check(const fgit_version* git_version);
//将相同版本和不同版本合并为一个具有相同和不同的版本
void compare_list_combine(const fgit_versions *in_versions_a, const fgit_versions *in_versions_b, fgit_versions *out_versions);
//寻找两个版本中 不存在的版本
void compare_list_exit(const fgit_versions *in_versions_a, const fgit_versions *in_versions_b, fgit_versions *out_versions);
const char *get_git_project_path();
const char *get_git_server_cache_path();
const char *get_git_version_filename();
const char *get_git_current_version_filename();
const char *get_git_path();
void init_server(int argc, char *argv[]);
void listening_clients();
void close_server();
bool is_exit_ignore(const char *path);
unsigned char get_protocal(); // 定义255个协议
void get_protocal_content(char *buf);
客户端源码.h
// Copyright (C) RenZhai.2019.All Rights Reserved.
/*
下面的网址讲解了如何使用git renzhai 的版本控制
DocURL: https://www.bilibili.com/video/BV1x5411s7s3
下面的网址讲解如何入门c语言
MarketplaceURL : https://www.aboutcg.org/courseDetails/902/introduce
如果想了解更多关于UE4教程请参考:
URL : https://zhuanlan.zhihu.com/p/60117613
如果想系统了解人宅系列教程以及相关插件迭代更新 可以关注我的博客
URL : http://renzhai.net/
如果想了解我们下一节的课程安排可以 可以在微信公众号搜所 人宅 关注即可 我们会推送很多富有技术的文章
新浪博客 https://weibo.com/BZRZ/profile?s=6cm7D0 //这个博客从16年到现在 有三四年没怎么用过 以后说不定可以重新启用 先发个连接
*/
#pragma once
#include "protocal.h"
char project_name[MAX_PATH] = { 0 };
char git_current_version_filename[MAX_PATH] = { 0 };
char git_version_filename[MAX_PATH] = { 0 };
char git_path[MAX_PATH] = { 0 };
char git_client_cache_path[MAX_PATH] = { 0 };
char git_project_remote_url[MAX_PATH] = { 0 };// 远端仓库
char git_project_path[MAX_PATH] = { 0 };//git路径 .git
char git_remote_origin[MAX_PATH] = { 0 };//远端路径 url
char git_local_cofg_filename[MAX_PATH] = { 0 };//用户配置信息
const char git_local_cofg_file[] = "..git";//本地配置的目录
int b_exit = false;
//
typedef struct
{
int size;
char data[8196][1024];
}fpath;
fpath server_list, ignore_path, ignore_suffix;
//用户信息
typedef struct fgit_user
{
char name[MAX_PATH];
char password[MAX_PATH];
char email[MAX_PATH];
};
struct fgit_user user;
//提交版本的信息
typedef struct
{
char name[MAX_PATH];
char commit[MAX_PATH];
char date[MAX_PATH];
simple_c_guid guid;
}fgit_commit;
fgit_commit commit;
//fgit_commit Last_commit;
typedef struct
{
unsigned int size;
fgit_commit commits[1024];
}fgit_commits;
//git 的路径
typedef struct
{
char path_src[MAX_PATH];
char path_dis[MAX_PATH];
}fgit_path_2d;
//git 所有提交的所有路径
typedef struct
{
int size;
fgit_path_2d paths[MAX_PATH * 2];
}fgit_path_2ds;
fgit_path_2ds git_path_2ds;
//文件版本操作类型
typedef enum
{
NONE_File,
ADD_FILE,
SUBTRACT_FILE,
OVERLAP_FILE,
}eversion_operation_type;
//单个文件的版本
typedef struct
{
eversion_operation_type operation_type;
unsigned int file_size;
char file_name[MAX_PATH];//
simple_c_guid crc;
}fgit_version;
//整体文件的版本
typedef struct
{
unsigned int size;
fgit_version paths[1024];
}fgit_versions;
fgit_versions versions;
//整体文件版本列表
typedef struct
{
unsigned int size;
fgit_versions paths[1024];
}fgit_versions_list;
//Engine core
//
void init_path(fpath *p);
void init_git_commits(fgit_commits *git_commits);
void git_clone_funcation();
void version_iteration_update();
void string_to_path(const char *data,fpath* p);
void path_to_string( char* data,const fpath* p);
char *get_git_commit(fgit_commit *git_commit);
char *git_commit_to_string(const fgit_commit *git_commit,char *buf);
void string_to_git_commit(fgit_commit *git_commit,const char *buf);
void string_to_git_commits(fgit_commits *git_commit, const char *buf);
void string_to_ignore_path(const char *buf);
void string_to_ignore_suffix(const char *buf);
void compare_list(const fgit_versions* server_version_list, const def_c_paths* local_paths, def_c_paths* out_paths);
void init_versions(fgit_versions *in_versions);
void init_commit(fgit_commit *out_commit);
void init_git_path_2ds(fgit_path_2ds *path_2ds);
void add_git_versions(const char *int_path,eversion_operation_type type, fgit_versions *out_versions);
void versions_to_string(char *buf,const fgit_versions *in_versions);
void string_to_versions(const char *buf,fgit_versions *in_versions);
//core
void init_engine(int argc, char *argv[]);
void engine_loop();
void exit_engine();
//
void read_user();
//
void save_user();
//get
const char *get_git_version_filename();
const char *get_git_current_version_filename();
const char *get_git_path();
char *get_git_client_cache_path();
char *get_git_project_remote_url();
char *get_current_time();
char *get_git_project_path();
char *get_git_local_user_filename();
unsigned char get_protocal();
bool is_exit_ignore(const char *path);
//log
//
协议号
#pragma once
//Copyright (C) RenZhai.2019.All Rights Reserved.
//作者 人宅
//该c库的详细源码讲解在AboutCG 《手把手入门硬核c语言》视频工程里面:
//https://www.aboutcg.org/courseDetails/902/introduce
//希望学习其他方面技术 比如做UE4游戏, 可以访问下列网址:
//https://zhuanlan.zhihu.com/p/60117613
//
//bibi可以看到各个人宅系列教程介绍:
//https://space.bilibili.com/29544409
//
//个人博客网站
//http://renzhai.net
//
//关于本套案例的详细操作 :
//文字版本(详细):
//https://zhuanlan.zhihu.com/p/144558934
//视频版本:
//https://www.bilibili.com/video/BV1x5411s7s3
#include "git.h"
_CRT_BEGIN_C_HEADER
typedef enum
{
NONE = 0, //什么都不发生
HELLO, //客户端 向服务器 发送 确认 用于链接
HEI, //服务器反馈
COMMIT, //提交信息
COMMIT_VERSION_LIST, //提交版本列表
VERSION_LOG, //请求服务端 版本提交日志
VERSION_STATUS, //版本修改内容 本次版本状态
PROTOCAL_ERROR, //在服务器发生的错误信息
VERSION_PROTOCAL, //获取最新服务器版本信息
VERSION_LIST, //获取最新服务器版本列表
VERSION_NEST, //获取在本版本号的基础上的下一个版本号
VERSION_NEST_COMPLETE, //服务器版本列表发送成功
VERSION_CLASH, //检测 冲突
CLASH_CONTENT, //获取 冲突 内容
NO_CLASH, //无冲突
CHECK_REMOVE_FILENAME, //检查有没有存在客户端删除的副本 有就通知服务端删除该数据
REMOVE_CONTENT, //提交移除的内容
GIT_CLONE, //克隆服务端数据
FILE_EXIT, //文件是否存在
FIND_VERSION_LIST, //根据版本路径寻找数据对应版本内容
CONNECT_TIME_OUT, //连接超时
REMOVE_LOCAL_REQUEST, //发送客户端移除 协议
SAVE_VERSION_REQUEST, //通知服务器 存储当前版本
GIT_RESET_VERSION, //还原版本
}egit_protocal_type;
_CRT_END_C_HEADER
特别提示
本git小程序的内存管理非动态内存,是固定分配一定份额的内存,如果用完就会产生奔溃,支持的项目为小型项目,
比如c或者c++源码等内容版本更新迭代,以后可以考虑扩展为动态内存。
本程序仅仅提供学习,在学习本程序请结合源码学习,源码在AboutCG视频工程里面:
手把手入门硬核C语言www.aboutcg.org![49862ffa78743172757ffd93b6b6f912.png](https://i-blog.csdnimg.cn/blog_migrate/2254bfdc50b3d0f2296155cf722123ee.jpeg)
希望学习其他方面技术 比如做UE4游戏,可以访问下列网址:
人宅:UE4精品课程zhuanlan.zhihu.com![fa839d9dc2e2a4c9ec4cc0dfe1059603.png](https://i-blog.csdnimg.cn/blog_migrate/733e9f82e93df8438c6d6bcc0fd80881.jpeg)
bibi可以看到各个视频介绍:
哔哩哔哩 ( ゜- ゜)つロ 乾杯~ Bilibilispace.bilibili.com个人博客网站(目前在抽时间搭建中...)
UnrealEngine大学 - 除了努力 别无选择renzhai.net![bd13cc21dbd048f745c48e6380921a1a.png](https://i-blog.csdnimg.cn/blog_migrate/4668ed278d5e6babd5768ff5536ba6d0.png)
关于本套案例的详细操作:
视频版本:
如何编写一个git版本控制系统_哔哩哔哩 (゜-゜)つロ 干杯~-bilibiliwww.bilibili.com![44c7d9f3e52542c4793eb263cd334649.png](https://i-blog.csdnimg.cn/blog_migrate/01350f46b6a3d87b72378c3b7f267f9c.jpeg)