C++ 操作Git仓库

代码
#include "common.h"
#include "args.c"
#include "common.c"enum index_mode {INDEX_NONE,INDEX_ADD
};struct index_options {int dry_run;int verbose;git_repository* repo;enum index_mode mode;int add_update;
};/* Forward declarations for helpers */
static void parse_opts(const char** repo_path, struct index_options* opts, struct args_info* args);
int print_matched_cb(const char* path, const char* matched_pathspec, void* payload);int lg2_add(git_repository* repo, int argc, char** argv)
{git_index_matched_path_cb matched_cb = NULL;git_index* index;git_strarray array = { 0 };struct index_options options = { 0 };struct args_info args = ARGS_INFO_INIT;options.mode = INDEX_ADD;/* Parse the options & arguments. */parse_opts(NULL, &options, &args);strarray_from_args(&array, &args);/* Grab the repository's index. */check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL);/* Setup a callback if the requested options need it */if (options.verbose || options.dry_run) {matched_cb = &print_matched_cb;}options.repo = repo;/* Perform the requested action with the index and files */if (options.add_update) {git_index_update_all(index, &array, matched_cb, &options);}else {git_index_add_all(index, &array, 0, matched_cb, &options);}/* Cleanup memory */git_index_write(index);git_index_free(index);return 0;
}/** This callback is called for each file under consideration by* git_index_(update|add)_all above.* It makes uses of the callback's ability to abort the action.*/
int print_matched_cb(const char* path, const char* matched_pathspec, void* payload)
{struct index_options* opts = (struct index_options*)(payload);int ret;unsigned status;(void)matched_pathspec;/* Get the file status */if (git_status_file(&status, opts->repo, path) < 0)return -1;if ((status & GIT_STATUS_WT_MODIFIED) || (status & GIT_STATUS_WT_NEW)) {printf("add '%s'\n", path);ret = 0;}else {ret = 1;}if (opts->dry_run)ret = 1;return ret;
}static void parse_opts(const char** repo_path, struct index_options* opts, struct args_info* args)
{if (args->argc <= 1)return;for (args->pos = 1; args->pos < args->argc; ++args->pos) {const char* curr = args->argv[args->pos];if (curr[0] != '-') {if (!strcmp("add", curr)) {opts->mode = INDEX_ADD;continue;}else if (opts->mode == INDEX_NONE) {fprintf(stderr, "missing command: %s", curr);break;}else {/* We might be looking at a filename */break;}}else if (match_bool_arg(&opts->verbose, args, "--verbose") ||match_bool_arg(&opts->dry_run, args, "--dry-run") ||match_str_arg(repo_path, args, "--git-dir") ||(opts->mode == INDEX_ADD && match_bool_arg(&opts->add_update, args, "--update"))) {continue;}else if (match_bool_arg(NULL, args, "--help")) {break;}else if (match_arg_separator(args)) {break;}else {fprintf(stderr, "Unsupported option %s.\n", curr);}}
}struct blame_opts {char* path;char* commitspec;int C;int M;int start_line;int end_line;int F;
};
static void parse_opts(struct blame_opts* o, int argc, char* argv[]);int lg2_blame(git_repository* repo, int argc, char* argv[])
{int line, break_on_null_hunk;git_object_size_t i, rawsize;char spec[1024] = { 0 };struct blame_opts o = { 0 };const char* rawdata;git_revspec revspec = { 0 };git_blame_options blameopts = GIT_BLAME_OPTIONS_INIT;git_blame* blame = NULL;git_blob* blob;git_object* obj;parse_opts(&o, argc, argv);if (o.M) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;if (o.C) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;if (o.F) blameopts.flags |= GIT_BLAME_FIRST_PARENT;if (o.start_line && o.end_line) {blameopts.min_line = o.start_line;blameopts.max_line = o.end_line;}/*** The commit range comes in "committish" form. Use the rev-parse API to* nail down the end points.*/if (o.commitspec) {check_lg2(git_revparse(&revspec, repo, o.commitspec), "Couldn't parse commit spec", NULL);if (revspec.flags & GIT_REVSPEC_SINGLE) {git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.from));git_object_free(revspec.from);}else {git_oid_cpy(&blameopts.oldest_commit, git_object_id(revspec.from));git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.to));git_object_free(revspec.from);git_object_free(revspec.to);}}/** Run the blame. */check_lg2(git_blame_file(&blame, repo, o.path, &blameopts), "Blame error", NULL);/*** Get the raw data inside the blob for output. We use the* `committish:path/to/file.txt` format to find it.*/if (git_oid_is_zero(&blameopts.newest_commit))strcpy(spec, "HEAD");elsegit_oid_tostr(spec, sizeof(spec), &blameopts.newest_commit);strcat(spec, ":");strcat(spec, o.path);check_lg2(git_revparse_single(&obj, repo, spec), "Object lookup error", NULL);check_lg2(git_blob_lookup(&blob, repo, git_object_id(obj)), "Blob lookup error", NULL);git_object_free(obj);rawdata = (const char*)git_blob_rawcontent(blob);rawsize = git_blob_rawsize(blob);/** Produce the output. */line = 1;i = 0;break_on_null_hunk = 0;while (i < rawsize) {const char* eol = (const char*)memchr(rawdata + i, '\n', (size_t)(rawsize - i));char oid[10] = { 0 };const git_blame_hunk* hunk = git_blame_get_hunk_byline(blame, line);if (break_on_null_hunk && !hunk)break;if (hunk) {char sig[128] = { 0 };break_on_null_hunk = 1;git_oid_tostr(oid, 10, &hunk->final_commit_id);snprintf(sig, 30, "%s <%s>", hunk->final_signature->name, hunk->final_signature->email);printf("%s ( %-30s %3d) %.*s\n",oid,sig,line,(int)(eol - rawdata - i),rawdata + i);}i = (int)(eol - rawdata + 1);line++;}/** Cleanup. */git_blob_free(blob);git_blame_free(blame);return 0;
}/** Tell the user how to make this thing work. */
static void usage(const char* msg, const char* arg)
{if (msg && arg)fprintf(stderr, "%s: %s\n", msg, arg);else if (msg)fprintf(stderr, "%s\n", msg);fprintf(stderr, "usage: blame [options] [<commit range>] <path>\n");fprintf(stderr, "\n");fprintf(stderr, "   <commit range>      example: `HEAD~10..HEAD`, or `1234abcd`\n");fprintf(stderr, "   -L <n,m>            process only line range n-m, counting from 1\n");fprintf(stderr, "   -M                  find line moves within and across files\n");fprintf(stderr, "   -C                  find line copies within and across files\n");fprintf(stderr, "   -F                  follow only the first parent commits\n");fprintf(stderr, "\n");exit(1);
}/** Parse the arguments. */
static void parse_opts(struct blame_opts* o, int argc, char* argv[])
{int i;char* bare_args[3] = { 0 };if (argc < 2) usage(NULL, NULL);for (i = 1; i < argc; i++) {char* a = argv[i];if (a[0] != '-') {int i = 0;while (bare_args[i] && i < 3) ++i;if (i >= 3)usage("Invalid argument set", NULL);bare_args[i] = a;}else if (!strcmp(a, "--"))continue;else if (!strcasecmp(a, "-M"))o->M = 1;else if (!strcasecmp(a, "-C"))o->C = 1;else if (!strcasecmp(a, "-F"))o->F = 1;else if (!strcasecmp(a, "-L")) {i++; a = argv[i];if (i >= argc) fatal("Not enough arguments to -L", NULL);check_lg2(sscanf(a, "%d,%d", &o->start_line, &o->end_line) - 2, "-L format error", NULL);}else {/* commit range */if (o->commitspec) fatal("Only one commit spec allowed", NULL);o->commitspec = a;}}/* Handle the bare arguments */if (!bare_args[0]) usage("Please specify a path", NULL);o->path = bare_args[0];if (bare_args[1]) {/* <commitspec> <path> */o->path = bare_args[1];o->commitspec = bare_args[0];}if (bare_args[2]) {/* <oldcommit> <newcommit> <path> */char spec[128] = { 0 };o->path = bare_args[2];sprintf(spec, "%s..%s", bare_args[0], bare_args[1]);o->commitspec = spec;}
}// git add调用
void testAdd(git_repository* repo) {int argc = 2;//const char** argv = { "add", "--verbose", "--dry-run", "--git-dir", "--update", NULL };char* argv1 = "add";char* argv2 = "main.cpp";char* argv[] = { argv1, argv2, NULL };lg2_add(repo, argc, argv);
}// git blame调用
void testBlame(git_repository* repo) {int argc = 2;//const char** argv = { "add", "--verbose", "--dry-run", "--git-dir", "--update", NULL };char* argv1 = "blame ";char* argv2 = "`HEAD~10..HEAD`";char* argv3 = "-F";char* argv[] = { argv1, argv2, argv3, NULL };lg2_blame(repo, argc, argv);
}void test() {git_libgit2_init();git_repository* repo;const char* repo_path = "D:\\libgit2\\.git";auto error = git_repository_open(&repo, repo_path);if (error) {printf("open git error");return;}testAdd(repo);	// git add调用testBlame(repo);	// git blame调用git_repository_free(repo);
}
输出
Blame error [-3] - the path '`HEAD~10..HEAD`' does not exist in the given tree
 参考

https://github.com/libgit2/libgit2

Libraries / libqgit2 · GitLab


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/388667.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue项目Nginx部署启动

1.vue打包 &#xff08;1&#xff09;package.json增加打包命令 "scripts": {"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 10.16.14.110","start": "npm run dev","un…

Halcon 边缘提取(亚像素)

Halcon提供多种边缘提取算法。像素提取方法有常用的边缘提取算子或深度学习分割模型等。考虑到精度问题可能需要提取亚像素边缘。当然也可以提取轮廓&#xff1a;线、圆、椭圆等。本文只讨论提取轮廓。 1 基本概念 正常情况下&#xff0c;无需特殊操作即可提取边缘轮廓。 1…

Linux-4:Shell编程——基础语法(50%-100%)

目录 前言 一、数组 1.数组定义 2.关联数组 3.数组长度 二、运算符 1.算术运算符 2.关系运算符 3.布尔运算符 4.逻辑运算符 5.字符串运算符 6.文件测试运算符 三、read命令 1.接收用户输入 2.开启转义 3. -p 输入提示 4. -s 静默模式 -t 设置超时时间 5.读取…

Fiddler学习笔记

目录 前言 简介 原理 界面 前言 测试可以使用fiddler工具&#xff0c;通过抓包的方式修改前端参数和模拟后端返回&#xff0c;快速定位缺陷。 简介 Fiddler是HTTP协议调试代理工具&#xff0c;可以记录并检查所有客户端和服务器之间的HTTP和HTTPS请求&#xff0c;允许监视…

算法训练1

01背包问题 背包状态方程----动态规划 二维dp 使用 f[i][j] max(f[i-1][j] ,f[i-1][j - w[i]] v[i]); 伪代码&#xff1a; int dp[100][100]; void test6() {int n; //装备数量int m; //背包容量int v[105], w[105]; //前面空间&#xff0c;后面价值for (int i 1; i &l…

ONLYOFFICE文档:为企业和开发者带来强大的文档编辑功能

本文给大家介绍一个开源项目&#xff1a;ONLYOFFICE文档&#xff0c;它能够为文档编辑、多人协作提供强大支持。无论你是个人使用&#xff0c;还是企业、商业开发&#xff0c;都能找到适合你的版本。 关于 ONLYOFFICE 文档 ONLYOFFICE 文档是一套功能强大的文档编辑器&#x…

微信小程序获取AppSecret的步骤

文章目录 微信小程序获取AppSecret的步骤&#xff1a;注意&#xff1a; 微信公众平台 小程序的密钥&#xff08;或称为AppSecret&#xff09;是用于加密解密、验证服务器身份等安全操作的敏感信息。不同的平台&#xff08;如微信小程序、支付宝小程序、百度智能小程序等&am…

vulhub:Apache解析漏洞apache_parsing

在Apache1.x/2.x中Apache 解析文件的规则是从右到左开始判断解析&#xff0c;如果后缀名为不可识别文件解析&#xff0c;就再往左判断。如 1.php.xxxxx 漏洞原理 Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执行不同的指令。比如如下配置文件 AddType te…

【C#】.net core 6.0 webapi 使用core版本的NPOI的Excel读取数据以及保存数据

欢迎来到《小5讲堂》 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景读取并保存NPOI信息NPOI 插件介绍基本功能示例代码写入 Excel 文件…

算法小白的进阶之路(力扣1~5)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

花几千上万学习Java,真没必要!(三十九)

1、BufferedReader的使用&#xff1a; 测试代码&#xff1a; package test.com; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class FileReadToList { pu…

使用 openai 和 langchain 调用自定义工具完成提问需求

我们提供了一个函数&#xff0c;接受传入运算的字符串&#xff0c;返回运算的结果。 现在的需求是&#xff0c;我们问 gpt 模型&#xff0c;由于模型计算能力并不好&#xff0c;他要调用计算函数&#xff0c;根据计算结果&#xff0c;回答我们的问题。 使用 openai 实现&#…

发布NPM包详细流程

制作 首先需要制作一个npm包。 按照以下步骤依次执行。 mkdir my-npm-package cd my-npm-package npm init 相信这一步不需要过多的解释&#xff0c;就是创建了一个文件夹&#xff0c;然后初始化了一下文件夹。 然后在生成的package.json文件夹中更改一下自己的配置&…

优化冗余代码:提升前端项目开发效率的实用方法

目录 前言代码复用与组件化模块化开发与代码分割工具辅助与自动化结束语 前言 在前端开发中&#xff0c;我们常常会遇到代码冗余的问题&#xff0c;这不仅增加了代码量&#xff0c;还影响了项目的可维护性和开发效率。还有就是有时候会接到紧急业务需求&#xff0c;要求立马完…

这两个大龄程序员,打算搞垮一个世界软件巨头!

大家都知道&#xff0c;Adobe是多媒体和数字内容创作者的绝对王者&#xff0c;它的旗下有众多大家耳熟能详的软件&#xff1a;Photoshop、Illustrator、Premiere Pro、After Effects、InDegign、Acrobat、Animate等等。 这些软件使用门槛很高&#xff0c;价格昂贵&#xff0c;安…

遗传算法与深度学习实战——生命模拟及其应用

遗传算法与深度学习实战——生命模拟及其应用 0. 前言1. 康威生命游戏1.1 康威生命游戏的规则1.2 实现康威生命游戏1.3 空间生命和智能体模拟 2. 实现生命模拟3. 生命模拟应用小结系列链接 0. 前言 生命模拟是进化计算的一个特定子集&#xff0c;模拟了自然界中所观察到的自然…

大模型之多模态大模型技术

本文作为大模型综述第三篇,介绍语言大模型多模态技术。 不同于语言大模型只对文本进行处理,多模态大模型将文本、语音、图像、视频等多模态数据联合起来进行学习。多模态大模型融合了多种感知途径与表达形态, 能够同时处理和理解来自不同感知通道(例如视觉、听觉、语言和触…

麒麟系统查看和修改ip

查看ip ifconfig ifconfig enp0s3 192.168.1.110

使用Echarts来实现数据可视化

目录 一.什么是ECharts? 二.如何使用Springboot来从后端给Echarts返回响应的数据&#xff1f; eg:折线图&#xff1a; ①Controller层&#xff1a; ②service层&#xff1a; 一.什么是ECharts? ECharts是一款基于JavaScript的数据可视化图标库&#xff0c;提供直观&…

javaScript中的对象

创建 this指向 命名规则 不符合变量名的命名规则和规范使用数组关联语法获取 遍历对象 使用for&#xff08;var key in 对象&#xff09; 删除属性 对象引用关系