05d292b2 (kx 2023-03-24 03:51:10 +0300 1)
05d292b2 (kx 2023-03-24 03:51:10 +0300 2) #ifdef HAVE_CONFIG_H
05d292b2 (kx 2023-03-24 03:51:10 +0300 3) #include <config.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 4) #endif
05d292b2 (kx 2023-03-24 03:51:10 +0300 5)
05d292b2 (kx 2023-03-24 03:51:10 +0300 6) #include <stdlib.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 7) #include <stdio.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 8) #include <sys/sysinfo.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 9) #include <sys/types.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 10) #include <stdint.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 11) #include <dirent.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 12) #include <sys/stat.h> /* chmod(2) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 13) #include <sys/file.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 14) #include <sys/mman.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 15) #include <fcntl.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 16) #include <limits.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 17) #include <string.h> /* strdup(3) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 18) #include <libgen.h> /* basename(3) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 19) #include <ctype.h> /* tolower(3) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 20) #include <errno.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 21) #include <time.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 22) #include <sys/time.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 23) #include <pwd.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 24) #include <grp.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 25) #include <stdarg.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 26) #include <unistd.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 27) #include <magic.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 28)
05d292b2 (kx 2023-03-24 03:51:10 +0300 29) #include <git2.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 30)
05d292b2 (kx 2023-03-24 03:51:10 +0300 31) #include <nls.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 32)
05d292b2 (kx 2023-03-24 03:51:10 +0300 33) #include <defs.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 34) #include <fatal.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 35) #include <http.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 36) #include <html.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 37) #include <strbuf.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 38) #include <wrapper.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 39) #include <system.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 40)
05d292b2 (kx 2023-03-24 03:51:10 +0300 41) #include <ctx.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 42) #include <git-shared.h>
05d292b2 (kx 2023-03-24 03:51:10 +0300 43)
05d292b2 (kx 2023-03-24 03:51:10 +0300 44)
05d292b2 (kx 2023-03-24 03:51:10 +0300 45) #define CGIT_ERRMSG_SIZE 4096
05d292b2 (kx 2023-03-24 03:51:10 +0300 46)
05d292b2 (kx 2023-03-24 03:51:10 +0300 47) void cgit_error( const char *fmt, ... )
05d292b2 (kx 2023-03-24 03:51:10 +0300 48) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 49) va_list arg_ptr;
05d292b2 (kx 2023-03-24 03:51:10 +0300 50) char buf[CGIT_ERRMSG_SIZE];
05d292b2 (kx 2023-03-24 03:51:10 +0300 51) char msg[CGIT_ERRMSG_SIZE];
05d292b2 (kx 2023-03-24 03:51:10 +0300 52) char *format = "%s: %s\n";
05d292b2 (kx 2023-03-24 03:51:10 +0300 53)
05d292b2 (kx 2023-03-24 03:51:10 +0300 54) va_start( arg_ptr, fmt );
05d292b2 (kx 2023-03-24 03:51:10 +0300 55)
05d292b2 (kx 2023-03-24 03:51:10 +0300 56) vsnprintf( msg, CGIT_ERRMSG_SIZE, (const void *)fmt, arg_ptr );
05d292b2 (kx 2023-03-24 03:51:10 +0300 57)
05d292b2 (kx 2023-03-24 03:51:10 +0300 58) va_end( arg_ptr ); /* Reset variable arguments. */
05d292b2 (kx 2023-03-24 03:51:10 +0300 59)
05d292b2 (kx 2023-03-24 03:51:10 +0300 60) snprintf( buf, CGIT_ERRMSG_SIZE, format, "cgit", msg );
05d292b2 (kx 2023-03-24 03:51:10 +0300 61)
05d292b2 (kx 2023-03-24 03:51:10 +0300 62) (void)write( STDERR_FILENO, buf, strlen( buf ) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 63)
05d292b2 (kx 2023-03-24 03:51:10 +0300 64) exit( 1 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 65) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 66)
05d292b2 (kx 2023-03-24 03:51:10 +0300 67) cgit_errfunc cgit_fatal = cgit_error;
05d292b2 (kx 2023-03-24 03:51:10 +0300 68)
05d292b2 (kx 2023-03-24 03:51:10 +0300 69)
05d292b2 (kx 2023-03-24 03:51:10 +0300 70)
05d292b2 (kx 2023-03-24 03:51:10 +0300 71) int is_bare( const char *path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 72) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 73) char *p = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 74) int ret = -1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 75)
05d292b2 (kx 2023-03-24 03:51:10 +0300 76) if( !path || !*path ) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 77)
05d292b2 (kx 2023-03-24 03:51:10 +0300 78) p = rindex( path, '.' );
05d292b2 (kx 2023-03-24 03:51:10 +0300 79) if( !p )
05d292b2 (kx 2023-03-24 03:51:10 +0300 80) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 81) ret = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 82) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 83) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 84) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 85) if( !strncmp( p, ".git", 4 ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 86) ret = 1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 87) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 88) ret = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 89) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 90)
05d292b2 (kx 2023-03-24 03:51:10 +0300 91) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 92) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 93)
05d292b2 (kx 2023-03-24 03:51:10 +0300 94) git_repository *open_repository( const char *path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 95) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 96) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 97) int bare = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 98)
05d292b2 (kx 2023-03-24 03:51:10 +0300 99) if( (bare = is_bare( path )) < 0 ) return repo;
05d292b2 (kx 2023-03-24 03:51:10 +0300 100)
05d292b2 (kx 2023-03-24 03:51:10 +0300 101) if( bare )
05d292b2 (kx 2023-03-24 03:51:10 +0300 102) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 103) if( git_repository_open_bare( &repo, path ) < 0 ) return repo;
05d292b2 (kx 2023-03-24 03:51:10 +0300 104) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 105) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 106) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 107) if( git_repository_open( &repo, path ) < 0 ) return repo;
05d292b2 (kx 2023-03-24 03:51:10 +0300 108) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 109)
05d292b2 (kx 2023-03-24 03:51:10 +0300 110) return repo;
05d292b2 (kx 2023-03-24 03:51:10 +0300 111) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 112)
05d292b2 (kx 2023-03-24 03:51:10 +0300 113) void close_repository( git_repository *repo )
05d292b2 (kx 2023-03-24 03:51:10 +0300 114) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 115) if( !repo ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 116) git_repository_free( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 117) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 118)
05d292b2 (kx 2023-03-24 03:51:10 +0300 119) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 120) Get Last Commit:
05d292b2 (kx 2023-03-24 03:51:10 +0300 121) (Only commit-ish refs are permitted)
05d292b2 (kx 2023-03-24 03:51:10 +0300 122) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 123) git_commit *get_commit_by_ref( git_repository *repo, const char *ref )
05d292b2 (kx 2023-03-24 03:51:10 +0300 124) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 125) int error = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 126) git_object *obj = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 127) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 128)
05d292b2 (kx 2023-03-24 03:51:10 +0300 129) char reference[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 130)
05d292b2 (kx 2023-03-24 03:51:10 +0300 131) if( !repo ) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 132) if( !ref ) ref = "HEAD^{commit}";
05d292b2 (kx 2023-03-24 03:51:10 +0300 133)
05d292b2 (kx 2023-03-24 03:51:10 +0300 134) sprintf( (char *)&reference[0], "%s^{commit}", ref );
05d292b2 (kx 2023-03-24 03:51:10 +0300 135)
05d292b2 (kx 2023-03-24 03:51:10 +0300 136) error = git_revparse_single( &obj, repo, (const char *)&reference[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 137) if( error < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 138) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 139) git_error_clear();
05d292b2 (kx 2023-03-24 03:51:10 +0300 140) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 141) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 142)
05d292b2 (kx 2023-03-24 03:51:10 +0300 143) if( git_object_type(obj) != GIT_OBJECT_COMMIT )
05d292b2 (kx 2023-03-24 03:51:10 +0300 144) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 145) git_object_free( obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 146) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 147) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 148)
05d292b2 (kx 2023-03-24 03:51:10 +0300 149) error = git_commit_lookup( &commit, repo, git_object_id( obj ) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 150) if( error < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 151) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 152) git_error_clear();
05d292b2 (kx 2023-03-24 03:51:10 +0300 153) git_object_free( obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 154) return NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 155) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 156)
05d292b2 (kx 2023-03-24 03:51:10 +0300 157) git_object_free( obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 158)
05d292b2 (kx 2023-03-24 03:51:10 +0300 159) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 160) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 161)
05d292b2 (kx 2023-03-24 03:51:10 +0300 162) git_commit *get_commit_by_hex( git_repository *repo, const char *hex )
05d292b2 (kx 2023-03-24 03:51:10 +0300 163) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 164) git_oid cid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 165) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 166)
05d292b2 (kx 2023-03-24 03:51:10 +0300 167) if( !repo || !hex ) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 168) if( git_oid_fromstr( &cid, hex ) < 0 ) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 169)
05d292b2 (kx 2023-03-24 03:51:10 +0300 170) if( git_commit_lookup( &commit, repo, &cid ) < 0 ) return NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 171) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 172) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 173)
05d292b2 (kx 2023-03-24 03:51:10 +0300 174)
05d292b2 (kx 2023-03-24 03:51:10 +0300 175) void fill_short_commit_info( struct short_commit_info *info, const char *path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 176) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 177) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 178) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 179)
05d292b2 (kx 2023-03-24 03:51:10 +0300 180) if( !info || !path ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 181)
05d292b2 (kx 2023-03-24 03:51:10 +0300 182) if( !(repo = open_repository( path )) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 183)
05d292b2 (kx 2023-03-24 03:51:10 +0300 184) if( !(commit = get_commit_by_ref( repo, NULL )) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 185) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 186) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 187) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 188) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 189)
05d292b2 (kx 2023-03-24 03:51:10 +0300 190) git_oid_tostr( info->rev, GIT_OID_HEXSZ+1, git_commit_id( commit ) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 191) info->date = git_commit_time( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 192) info->offset = git_commit_time_offset( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 193)
05d292b2 (kx 2023-03-24 03:51:10 +0300 194) info->offset = (info->offset % 60) + ((info->offset / 60) * 100);
05d292b2 (kx 2023-03-24 03:51:10 +0300 195)
05d292b2 (kx 2023-03-24 03:51:10 +0300 196) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 197)
05d292b2 (kx 2023-03-24 03:51:10 +0300 198) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 199) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 200)
05d292b2 (kx 2023-03-24 03:51:10 +0300 201) struct found {
05d292b2 (kx 2023-03-24 03:51:10 +0300 202) git_object_t kind;
05d292b2 (kx 2023-03-24 03:51:10 +0300 203) git_filemode_t mode;
05d292b2 (kx 2023-03-24 03:51:10 +0300 204) const git_oid *oid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 205) git_object *obj;
05d292b2 (kx 2023-03-24 03:51:10 +0300 206) };
05d292b2 (kx 2023-03-24 03:51:10 +0300 207)
05d292b2 (kx 2023-03-24 03:51:10 +0300 208) static void find_entry( struct found *ret, git_repository *repo, git_tree *tree, char *path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 209) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 210) git_tree *ntree = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 211) int i, cnt;
05d292b2 (kx 2023-03-24 03:51:10 +0300 212) char *s, *p = NULL, *n;
05d292b2 (kx 2023-03-24 03:51:10 +0300 213)
05d292b2 (kx 2023-03-24 03:51:10 +0300 214) if( !ret || !repo || !tree ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 215)
05d292b2 (kx 2023-03-24 03:51:10 +0300 216) if( path && *path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 217) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 218) s = path;
05d292b2 (kx 2023-03-24 03:51:10 +0300 219)
05d292b2 (kx 2023-03-24 03:51:10 +0300 220) while( *s && *s == '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 221) ++s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 222) n = p = s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 223)
05d292b2 (kx 2023-03-24 03:51:10 +0300 224) while( *p && *p != '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 225) ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 226) if( *p )
05d292b2 (kx 2023-03-24 03:51:10 +0300 227) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 228) *p = '\0'; s = ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 229) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 230) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 231) s = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 232)
05d292b2 (kx 2023-03-24 03:51:10 +0300 233) git_tree_dup( &ntree, tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 234) cnt = git_tree_entrycount( ntree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 235)
05d292b2 (kx 2023-03-24 03:51:10 +0300 236) for( i = 0; i < cnt; ++i )
05d292b2 (kx 2023-03-24 03:51:10 +0300 237) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 238) const git_tree_entry *entry;
05d292b2 (kx 2023-03-24 03:51:10 +0300 239) entry = git_tree_entry_byindex( ntree, i );
05d292b2 (kx 2023-03-24 03:51:10 +0300 240)
05d292b2 (kx 2023-03-24 03:51:10 +0300 241) if( !strcmp( git_tree_entry_name( entry ), n ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 242) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 243) ret->kind = git_tree_entry_type( entry );
05d292b2 (kx 2023-03-24 03:51:10 +0300 244) ret->mode = git_tree_entry_filemode( entry );
05d292b2 (kx 2023-03-24 03:51:10 +0300 245) git_tree_entry_to_object( &ret->obj, repo, entry );
05d292b2 (kx 2023-03-24 03:51:10 +0300 246) ret->oid = git_object_id( (const git_object *)ret->obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 247)
05d292b2 (kx 2023-03-24 03:51:10 +0300 248) if( ret->kind == GIT_OBJECT_TREE && s && *s )
05d292b2 (kx 2023-03-24 03:51:10 +0300 249) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 250) git_object *obj;
05d292b2 (kx 2023-03-24 03:51:10 +0300 251) git_tree_entry_to_object( &obj, repo, entry );
05d292b2 (kx 2023-03-24 03:51:10 +0300 252) find_entry( ret, repo, (git_tree *)obj, s );
05d292b2 (kx 2023-03-24 03:51:10 +0300 253) git_object_free( obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 254) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 255) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 256) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 257) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 258) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 259) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 260) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 261)
05d292b2 (kx 2023-03-24 03:51:10 +0300 262) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 263) git_tree_free( ntree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 264) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 265)
05d292b2 (kx 2023-03-24 03:51:10 +0300 266) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 267) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 268)
05d292b2 (kx 2023-03-24 03:51:10 +0300 269)
05d292b2 (kx 2023-03-24 03:51:10 +0300 270) void fill_commit_info( struct cgit_info *info, const char *path, const char *rpath )
05d292b2 (kx 2023-03-24 03:51:10 +0300 271) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 272) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 273) git_oid cid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 274) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 275) git_tree *tree = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 276) const git_oid *oid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 277) const git_signature *sign = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 278)
05d292b2 (kx 2023-03-24 03:51:10 +0300 279) char *author;
05d292b2 (kx 2023-03-24 03:51:10 +0300 280) int len;
05d292b2 (kx 2023-03-24 03:51:10 +0300 281)
05d292b2 (kx 2023-03-24 03:51:10 +0300 282) if( !info || !path || !info->revision[0] ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 283) if( git_oid_fromstr( &cid, (const char *)&info->revision[0] ) < 0 ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 284) if( !(repo = open_repository( path )) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 285)
05d292b2 (kx 2023-03-24 03:51:10 +0300 286) git_commit_lookup( &commit, repo, &cid );
05d292b2 (kx 2023-03-24 03:51:10 +0300 287) git_commit_tree( &tree, commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 288)
05d292b2 (kx 2023-03-24 03:51:10 +0300 289) info->kind = git_object_type( (const git_object *)tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 290) oid = git_tree_id( (const git_tree *)tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 291) git_oid_fmt( (char *)&info->oid[0], oid );
05d292b2 (kx 2023-03-24 03:51:10 +0300 292)
05d292b2 (kx 2023-03-24 03:51:10 +0300 293) if( rpath && *rpath )
05d292b2 (kx 2023-03-24 03:51:10 +0300 294) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 295) struct found ret = { .kind = GIT_OBJECT_TREE, .oid = NULL, .obj = NULL };
05d292b2 (kx 2023-03-24 03:51:10 +0300 296) char relative_path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 297) sprintf( (char *)&relative_path[0], rpath );
05d292b2 (kx 2023-03-24 03:51:10 +0300 298) find_entry( &ret, repo, tree, (char *)&relative_path[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 299) info->kind = ret.kind;
05d292b2 (kx 2023-03-24 03:51:10 +0300 300) info->mode = ret.mode;
05d292b2 (kx 2023-03-24 03:51:10 +0300 301) git_oid_fmt( (char *)&info->oid[0], ret.oid );
05d292b2 (kx 2023-03-24 03:51:10 +0300 302) git_object_free( ret.obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 303) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 304)
05d292b2 (kx 2023-03-24 03:51:10 +0300 305) git_tree_free( tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 306)
05d292b2 (kx 2023-03-24 03:51:10 +0300 307) info->date = git_commit_time( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 308) info->offset = git_commit_time_offset( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 309)
05d292b2 (kx 2023-03-24 03:51:10 +0300 310) info->offset = (info->offset % 60) + ((info->offset / 60) * 100);
05d292b2 (kx 2023-03-24 03:51:10 +0300 311)
05d292b2 (kx 2023-03-24 03:51:10 +0300 312) sign = git_commit_author( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 313) len = (int)strlen( sign->name ) + 1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 314) author = (char *)__sbrk( len );
05d292b2 (kx 2023-03-24 03:51:10 +0300 315) strcpy( author, sign->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 316) info->author = author;
05d292b2 (kx 2023-03-24 03:51:10 +0300 317)
05d292b2 (kx 2023-03-24 03:51:10 +0300 318) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 319) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 320) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 321)
05d292b2 (kx 2023-03-24 03:51:10 +0300 322)
05d292b2 (kx 2023-03-24 03:51:10 +0300 323) static const char *mime_info( struct cgit_info *info, const char *buffer, size_t length )
05d292b2 (kx 2023-03-24 03:51:10 +0300 324) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 325) const char *mime = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 326) magic_t magic;
05d292b2 (kx 2023-03-24 03:51:10 +0300 327)
05d292b2 (kx 2023-03-24 03:51:10 +0300 328) if( !info || !buffer || !length ) return mime;
05d292b2 (kx 2023-03-24 03:51:10 +0300 329)
05d292b2 (kx 2023-03-24 03:51:10 +0300 330) magic = magic_open( MAGIC_MIME );
05d292b2 (kx 2023-03-24 03:51:10 +0300 331) if( !magic )
05d292b2 (kx 2023-03-24 03:51:10 +0300 332) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 333) html_fatal( "unable to initialize magic library" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 334) return mime;
05d292b2 (kx 2023-03-24 03:51:10 +0300 335) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 336) if( magic_load( magic, NULL ) != 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 337) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 338) html_fatal( "cannot load magic database - %s\n", magic_error( magic ) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 339) magic_close( magic );
05d292b2 (kx 2023-03-24 03:51:10 +0300 340) return mime;
05d292b2 (kx 2023-03-24 03:51:10 +0300 341) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 342)
05d292b2 (kx 2023-03-24 03:51:10 +0300 343) mime = magic_buffer( magic, buffer, length );
05d292b2 (kx 2023-03-24 03:51:10 +0300 344) if( mime )
05d292b2 (kx 2023-03-24 03:51:10 +0300 345) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 346) int len = (int)strlen( mime ) + 1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 347) char *mime_type = (char *)__sbrk( len );
05d292b2 (kx 2023-03-24 03:51:10 +0300 348) memcpy( (void *)mime_type, (const void *)mime, len );
05d292b2 (kx 2023-03-24 03:51:10 +0300 349) info->mime = (const char *)mime_type;
05d292b2 (kx 2023-03-24 03:51:10 +0300 350) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 351)
05d292b2 (kx 2023-03-24 03:51:10 +0300 352) magic_close( magic );
05d292b2 (kx 2023-03-24 03:51:10 +0300 353) return mime;
05d292b2 (kx 2023-03-24 03:51:10 +0300 354) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 355)
05d292b2 (kx 2023-03-24 03:51:10 +0300 356) void fill_mime_info( struct cgit_info *info, const char *path, const char *rpath )
05d292b2 (kx 2023-03-24 03:51:10 +0300 357) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 358) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 359) git_oid cid;
05d292b2 (kx 2023-03-24 03:51:10 +0300 360) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 361) git_tree *tree = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 362) git_object *obj = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 363) git_object_t kind;
05d292b2 (kx 2023-03-24 03:51:10 +0300 364) git_blob *blob = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 365) int blob_allocated = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 366) git_off_t rawsize = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 367) const char *raw = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 368) char mime_buf[1024] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 369) size_t len = 1024;
05d292b2 (kx 2023-03-24 03:51:10 +0300 370)
05d292b2 (kx 2023-03-24 03:51:10 +0300 371) if( !info || !path || !info->revision[0] || info->kind != GIT_OBJECT_BLOB ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 372) if( git_oid_fromstr( &cid, (const char *)&info->revision[0] ) < 0 ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 373) if( !(repo = open_repository( path )) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 374)
05d292b2 (kx 2023-03-24 03:51:10 +0300 375) git_commit_lookup( &commit, repo, &cid );
05d292b2 (kx 2023-03-24 03:51:10 +0300 376) git_commit_tree( &tree, commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 377)
05d292b2 (kx 2023-03-24 03:51:10 +0300 378) blob = (git_blob *)tree;
05d292b2 (kx 2023-03-24 03:51:10 +0300 379) kind = git_object_type( (const git_object *)tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 380) if( rpath && *rpath )
05d292b2 (kx 2023-03-24 03:51:10 +0300 381) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 382) struct found ret = { .kind = GIT_OBJECT_TREE, .oid = NULL, .obj = NULL };
05d292b2 (kx 2023-03-24 03:51:10 +0300 383) char relative_path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 384) sprintf( (char *)&relative_path[0], rpath );
05d292b2 (kx 2023-03-24 03:51:10 +0300 385) find_entry( &ret, repo, tree, (char *)&relative_path[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 386) kind = ret.kind;
05d292b2 (kx 2023-03-24 03:51:10 +0300 387) if( kind == GIT_OBJECT_BLOB )
05d292b2 (kx 2023-03-24 03:51:10 +0300 388) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 389) git_object_dup( &obj, ret.obj );
05d292b2 (kx 2023-03-24 03:51:10 +0300 390) blob_allocated = 1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 391) blob = (git_blob *)obj;
05d292b2 (kx 2023-03-24 03:51:10 +0300 392) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 393) git_object_free( ret.obj ); /* We have to free allocated object returned by find_entry(). */
05d292b2 (kx 2023-03-24 03:51:10 +0300 394) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 395)
05d292b2 (kx 2023-03-24 03:51:10 +0300 396) if( kind != GIT_OBJECT_BLOB )
05d292b2 (kx 2023-03-24 03:51:10 +0300 397) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 398) if( blob_allocated )
05d292b2 (kx 2023-03-24 03:51:10 +0300 399) git_object_free( (git_object *)blob );
05d292b2 (kx 2023-03-24 03:51:10 +0300 400) git_tree_free( tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 401) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 402) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 403) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 404) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 405)
05d292b2 (kx 2023-03-24 03:51:10 +0300 406) rawsize = git_blob_rawsize( blob );
05d292b2 (kx 2023-03-24 03:51:10 +0300 407) raw = (const char *)git_blob_rawcontent( blob );
05d292b2 (kx 2023-03-24 03:51:10 +0300 408) if( rawsize > 1024 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 409) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 410) memcpy( (void *)&mime_buf[0], (const void *)raw, len );
05d292b2 (kx 2023-03-24 03:51:10 +0300 411) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 412) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 413) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 414) memcpy( (void *)&mime_buf[0], (const void *)raw, (size_t)rawsize );
05d292b2 (kx 2023-03-24 03:51:10 +0300 415) len = (size_t)rawsize;
05d292b2 (kx 2023-03-24 03:51:10 +0300 416) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 417)
05d292b2 (kx 2023-03-24 03:51:10 +0300 418) if( blob_allocated )
05d292b2 (kx 2023-03-24 03:51:10 +0300 419) git_object_free( (git_object *)blob );
05d292b2 (kx 2023-03-24 03:51:10 +0300 420) git_tree_free( tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 421)
05d292b2 (kx 2023-03-24 03:51:10 +0300 422) mime_info( info, (const char *)&mime_buf[0], len );
05d292b2 (kx 2023-03-24 03:51:10 +0300 423)
05d292b2 (kx 2023-03-24 03:51:10 +0300 424) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 425) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 426) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 427)
05d292b2 (kx 2023-03-24 03:51:10 +0300 428)
05d292b2 (kx 2023-03-24 03:51:10 +0300 429) size_t branches_number( const char *path, const char *skip )
05d292b2 (kx 2023-03-24 03:51:10 +0300 430) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 431) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 432) git_reference_iterator *iter = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 433) const char *name = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 434) size_t ret = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 435)
05d292b2 (kx 2023-03-24 03:51:10 +0300 436) if( !path ) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 437)
05d292b2 (kx 2023-03-24 03:51:10 +0300 438) if( !(repo = open_repository( path )) ) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 439)
05d292b2 (kx 2023-03-24 03:51:10 +0300 440) if( git_reference_iterator_glob_new( &iter, repo, "refs/heads/*" ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 441) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 442) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 443) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 444) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 445)
05d292b2 (kx 2023-03-24 03:51:10 +0300 446) while( !git_reference_next_name( &name, iter ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 447) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 448) if( skip && *skip )
05d292b2 (kx 2023-03-24 03:51:10 +0300 449) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 450) if( strcmp( (const char *)&name[11], skip ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 451) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 452) ++ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 453) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 454) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 455) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 456) ++ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 457) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 458)
05d292b2 (kx 2023-03-24 03:51:10 +0300 459) git_reference_iterator_free( iter );
05d292b2 (kx 2023-03-24 03:51:10 +0300 460) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 461)
05d292b2 (kx 2023-03-24 03:51:10 +0300 462) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 463) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 464)
05d292b2 (kx 2023-03-24 03:51:10 +0300 465) size_t tags_number( const char *path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 466) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 467) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 468) git_strarray tags;
05d292b2 (kx 2023-03-24 03:51:10 +0300 469) size_t ret = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 470)
05d292b2 (kx 2023-03-24 03:51:10 +0300 471) if( !path ) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 472)
05d292b2 (kx 2023-03-24 03:51:10 +0300 473) if( !(repo = open_repository( path )) ) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 474)
05d292b2 (kx 2023-03-24 03:51:10 +0300 475) if( git_tag_list( &tags, repo ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 476) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 477) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 478) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 479) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 480)
05d292b2 (kx 2023-03-24 03:51:10 +0300 481) ret = tags.count;
05d292b2 (kx 2023-03-24 03:51:10 +0300 482) git_strarray_free( &tags );
05d292b2 (kx 2023-03-24 03:51:10 +0300 483)
05d292b2 (kx 2023-03-24 03:51:10 +0300 484) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 485)
05d292b2 (kx 2023-03-24 03:51:10 +0300 486) return ret;
05d292b2 (kx 2023-03-24 03:51:10 +0300 487) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 488)
05d292b2 (kx 2023-03-24 03:51:10 +0300 489) /**********************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 490) List of references functions:
05d292b2 (kx 2023-03-24 03:51:10 +0300 491) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 492) struct cgit_ref_names *cgit_ref_names_new( void )
05d292b2 (kx 2023-03-24 03:51:10 +0300 493) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 494) struct cgit_ref_names *names = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 495)
05d292b2 (kx 2023-03-24 03:51:10 +0300 496) names = (struct cgit_ref_names *)xmalloc( sizeof(struct cgit_ref_names) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 497) return names;
05d292b2 (kx 2023-03-24 03:51:10 +0300 498) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 499)
05d292b2 (kx 2023-03-24 03:51:10 +0300 500) void cgit_ref_names_allocate( struct cgit_ref_names **ref_names )
05d292b2 (kx 2023-03-24 03:51:10 +0300 501) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 502) struct cgit_ref_names *names = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 503)
05d292b2 (kx 2023-03-24 03:51:10 +0300 504) if( !ref_names ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 505) names = (struct cgit_ref_names *)xmalloc( sizeof(struct cgit_ref_names) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 506) *ref_names = names;
05d292b2 (kx 2023-03-24 03:51:10 +0300 507) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 508)
05d292b2 (kx 2023-03-24 03:51:10 +0300 509) void cgit_ref_names_add( struct cgit_ref_names *names, const char *name )
05d292b2 (kx 2023-03-24 03:51:10 +0300 510) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 511) if( !names ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 512)
05d292b2 (kx 2023-03-24 03:51:10 +0300 513) if( !names->name )
05d292b2 (kx 2023-03-24 03:51:10 +0300 514) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 515) names->name = (char **)xmalloc( sizeof(char *) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 516) names->name[0] = strdup( name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 517) names->len = (size_t)1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 518) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 519) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 520) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 521) names->name = (char **)xrealloc( names->name, (names->len + 1) * sizeof(char *) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 522) names->name[names->len] = strdup( name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 523) ++names->len;
05d292b2 (kx 2023-03-24 03:51:10 +0300 524) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 525) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 526)
05d292b2 (kx 2023-03-24 03:51:10 +0300 527) void cgit_ref_names_free( struct cgit_ref_names *names )
05d292b2 (kx 2023-03-24 03:51:10 +0300 528) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 529) if( !names ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 530)
05d292b2 (kx 2023-03-24 03:51:10 +0300 531) if( names->len && names->name )
05d292b2 (kx 2023-03-24 03:51:10 +0300 532) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 533) size_t i;
05d292b2 (kx 2023-03-24 03:51:10 +0300 534) for( i = 0; i < names->len; ++i )
05d292b2 (kx 2023-03-24 03:51:10 +0300 535) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 536) if( names->name[i] )
05d292b2 (kx 2023-03-24 03:51:10 +0300 537) free( names->name[i] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 538) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 539) free( names->name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 540) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 541) free( names );
05d292b2 (kx 2023-03-24 03:51:10 +0300 542) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 543) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 544) End of List of references functions.
05d292b2 (kx 2023-03-24 03:51:10 +0300 545) **************************************/
05d292b2 (kx 2023-03-24 03:51:10 +0300 546)
05d292b2 (kx 2023-03-24 03:51:10 +0300 547) void lookup_branches_by_prefix( struct cgit_ref_names **ref_names, const char *prefix )
05d292b2 (kx 2023-03-24 03:51:10 +0300 548) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 549) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 550) struct cgit_ref_names *names = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 551)
05d292b2 (kx 2023-03-24 03:51:10 +0300 552) if( !ref_names || !prefix || !*prefix ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 553)
05d292b2 (kx 2023-03-24 03:51:10 +0300 554) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 555) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 556) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 557)
05d292b2 (kx 2023-03-24 03:51:10 +0300 558) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 559) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 560) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 561) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 562)
05d292b2 (kx 2023-03-24 03:51:10 +0300 563) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 564) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 565) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 566) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 567) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 568) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 569) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 570)
05d292b2 (kx 2023-03-24 03:51:10 +0300 571) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 572) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 573) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 574) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 575)
05d292b2 (kx 2023-03-24 03:51:10 +0300 576) if( !(repo = open_repository( (const char *)&path[0] )) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 577)
05d292b2 (kx 2023-03-24 03:51:10 +0300 578) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 579) git_reference_iterator *iter = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 580) const char *name = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 581) const char *refs = "refs/heads/*";
05d292b2 (kx 2023-03-24 03:51:10 +0300 582)
05d292b2 (kx 2023-03-24 03:51:10 +0300 583) if( git_reference_iterator_glob_new( &iter, repo, refs ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 584) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 585) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 586) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 587) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 588)
05d292b2 (kx 2023-03-24 03:51:10 +0300 589) cgit_ref_names_allocate( &names );
05d292b2 (kx 2023-03-24 03:51:10 +0300 590) *ref_names = names;
05d292b2 (kx 2023-03-24 03:51:10 +0300 591)
05d292b2 (kx 2023-03-24 03:51:10 +0300 592) while( !git_reference_next_name( &name, iter ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 593) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 594) size_t len = strlen( prefix );
05d292b2 (kx 2023-03-24 03:51:10 +0300 595)
05d292b2 (kx 2023-03-24 03:51:10 +0300 596) if( !strncmp( prefix, (char *)&name[11], len ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 597) cgit_ref_names_add( names, (const char *)&name[11] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 598) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 599) git_reference_iterator_free( iter );
05d292b2 (kx 2023-03-24 03:51:10 +0300 600) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 601)
05d292b2 (kx 2023-03-24 03:51:10 +0300 602) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 603) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 604)
05d292b2 (kx 2023-03-24 03:51:10 +0300 605) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 606) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 607)
05d292b2 (kx 2023-03-24 03:51:10 +0300 608) void lookup_tags_by_prefix( struct cgit_ref_names **ref_names, const char *prefix )
05d292b2 (kx 2023-03-24 03:51:10 +0300 609) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 610) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 611) struct cgit_ref_names *names = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 612)
05d292b2 (kx 2023-03-24 03:51:10 +0300 613) if( !ref_names || !prefix || !*prefix ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 614)
05d292b2 (kx 2023-03-24 03:51:10 +0300 615) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 616) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 617) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 618)
05d292b2 (kx 2023-03-24 03:51:10 +0300 619) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 620) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 621) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 622) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 623)
05d292b2 (kx 2023-03-24 03:51:10 +0300 624) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 625) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 626) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 627) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 628) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 629) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 630) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 631)
05d292b2 (kx 2023-03-24 03:51:10 +0300 632) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 633) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 634) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 635) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 636)
05d292b2 (kx 2023-03-24 03:51:10 +0300 637) if( !(repo = open_repository( (const char *)&path[0] )) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 638)
05d292b2 (kx 2023-03-24 03:51:10 +0300 639) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 640) git_reference_iterator *iter = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 641) const char *name = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 642) const char *refs = "refs/tags/*";
05d292b2 (kx 2023-03-24 03:51:10 +0300 643)
05d292b2 (kx 2023-03-24 03:51:10 +0300 644) if( git_reference_iterator_glob_new( &iter, repo, refs ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 645) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 646) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 647) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 648) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 649)
05d292b2 (kx 2023-03-24 03:51:10 +0300 650) cgit_ref_names_allocate( &names );
05d292b2 (kx 2023-03-24 03:51:10 +0300 651) *ref_names = names;
05d292b2 (kx 2023-03-24 03:51:10 +0300 652)
05d292b2 (kx 2023-03-24 03:51:10 +0300 653) while( !git_reference_next_name( &name, iter ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 654) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 655) size_t len = strlen( prefix );
05d292b2 (kx 2023-03-24 03:51:10 +0300 656)
05d292b2 (kx 2023-03-24 03:51:10 +0300 657) if( !strncmp( prefix, (char *)&name[10], len ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 658) cgit_ref_names_add( names, (const char *)&name[10] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 659) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 660) git_reference_iterator_free( iter );
05d292b2 (kx 2023-03-24 03:51:10 +0300 661) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 662)
05d292b2 (kx 2023-03-24 03:51:10 +0300 663) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 664) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 665)
05d292b2 (kx 2023-03-24 03:51:10 +0300 666) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 667) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 668)
05d292b2 (kx 2023-03-24 03:51:10 +0300 669)
05d292b2 (kx 2023-03-24 03:51:10 +0300 670) /***********************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 671) List of commits functions:
05d292b2 (kx 2023-03-24 03:51:10 +0300 672) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 673) struct cgit_hex_commits *cgit_hex_commits_new( void )
05d292b2 (kx 2023-03-24 03:51:10 +0300 674) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 675) struct cgit_hex_commits *commits = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 676)
05d292b2 (kx 2023-03-24 03:51:10 +0300 677) commits = (struct cgit_hex_commits *)xmalloc( sizeof(struct cgit_hex_commits) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 678) return commits;
05d292b2 (kx 2023-03-24 03:51:10 +0300 679) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 680)
05d292b2 (kx 2023-03-24 03:51:10 +0300 681) void cgit_hex_commits_allocate( struct cgit_hex_commits **hex_commits )
05d292b2 (kx 2023-03-24 03:51:10 +0300 682) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 683) struct cgit_hex_commits *commits = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 684)
05d292b2 (kx 2023-03-24 03:51:10 +0300 685) if( !hex_commits ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 686) commits = (struct cgit_hex_commits *)xmalloc( sizeof(struct cgit_hex_commits) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 687) *hex_commits = commits;
05d292b2 (kx 2023-03-24 03:51:10 +0300 688) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 689)
05d292b2 (kx 2023-03-24 03:51:10 +0300 690) void cgit_hex_commits_add( struct cgit_hex_commits *commits, const char *hex )
05d292b2 (kx 2023-03-24 03:51:10 +0300 691) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 692) if( !commits ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 693)
05d292b2 (kx 2023-03-24 03:51:10 +0300 694) if( !commits->hex )
05d292b2 (kx 2023-03-24 03:51:10 +0300 695) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 696) commits->hex = (char **)xmalloc( sizeof(char *) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 697) commits->hex[0] = strdup( hex );
05d292b2 (kx 2023-03-24 03:51:10 +0300 698) commits->len = (size_t)1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 699) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 700) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 701) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 702) commits->hex = (char **)xrealloc( commits->hex, (commits->len + 1) * sizeof(char *) );
05d292b2 (kx 2023-03-24 03:51:10 +0300 703) commits->hex[commits->len] = strdup( hex );
05d292b2 (kx 2023-03-24 03:51:10 +0300 704) ++commits->len;
05d292b2 (kx 2023-03-24 03:51:10 +0300 705) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 706) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 707)
05d292b2 (kx 2023-03-24 03:51:10 +0300 708) void cgit_hex_commits_free( struct cgit_hex_commits *commits )
05d292b2 (kx 2023-03-24 03:51:10 +0300 709) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 710) if( !commits ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 711)
05d292b2 (kx 2023-03-24 03:51:10 +0300 712) if( commits->len && commits->hex )
05d292b2 (kx 2023-03-24 03:51:10 +0300 713) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 714) size_t i;
05d292b2 (kx 2023-03-24 03:51:10 +0300 715) for( i = 0; i < commits->len; ++i )
05d292b2 (kx 2023-03-24 03:51:10 +0300 716) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 717) if( commits->hex[i] )
05d292b2 (kx 2023-03-24 03:51:10 +0300 718) free( commits->hex[i] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 719) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 720) free( commits->hex );
05d292b2 (kx 2023-03-24 03:51:10 +0300 721) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 722) free( commits );
05d292b2 (kx 2023-03-24 03:51:10 +0300 723) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 724) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 725) End of List of commits functions.
05d292b2 (kx 2023-03-24 03:51:10 +0300 726) ***********************************/
05d292b2 (kx 2023-03-24 03:51:10 +0300 727)
05d292b2 (kx 2023-03-24 03:51:10 +0300 728) void parse_relative_path( char *ref, char *rpath, const char *relative_path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 729) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 730) char *s, *p = NULL, *n, *path, *path_info;
05d292b2 (kx 2023-03-24 03:51:10 +0300 731) int len = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 732)
05d292b2 (kx 2023-03-24 03:51:10 +0300 733) *ref = '\0', *rpath = '\0';
05d292b2 (kx 2023-03-24 03:51:10 +0300 734)
05d292b2 (kx 2023-03-24 03:51:10 +0300 735) if( relative_path && *relative_path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 736) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 737) path_info = xstrdup( relative_path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 738) s = path_info;
05d292b2 (kx 2023-03-24 03:51:10 +0300 739)
05d292b2 (kx 2023-03-24 03:51:10 +0300 740) while( *s )
05d292b2 (kx 2023-03-24 03:51:10 +0300 741) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 742) while( *s && *s == '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 743) ++s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 744) n = p = s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 745)
05d292b2 (kx 2023-03-24 03:51:10 +0300 746) while( *p && *p != '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 747) ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 748) if( *p )
05d292b2 (kx 2023-03-24 03:51:10 +0300 749) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 750) *p = '\0'; s = ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 751) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 752) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 753) s = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 754)
05d292b2 (kx 2023-03-24 03:51:10 +0300 755) if( !strcmp( n, "tags" ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 756) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 757) sprintf( ref, "refs/%s/", n );
05d292b2 (kx 2023-03-24 03:51:10 +0300 758) n = s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 759) while( *p && *p != '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 760) ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 761) if( *p )
05d292b2 (kx 2023-03-24 03:51:10 +0300 762) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 763) *p = '\0'; s = ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 764) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 765) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 766) s = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 767)
05d292b2 (kx 2023-03-24 03:51:10 +0300 768) if( n && *n )
05d292b2 (kx 2023-03-24 03:51:10 +0300 769) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 770) int found = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 771) char tag[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 772) char reminder[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 773) char *b, *r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 774)
05d292b2 (kx 2023-03-24 03:51:10 +0300 775) struct cgit_ref_names *names = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 776)
05d292b2 (kx 2023-03-24 03:51:10 +0300 777) sprintf( reminder, "%s", s );
05d292b2 (kx 2023-03-24 03:51:10 +0300 778) sprintf( tag, "%s", n );
05d292b2 (kx 2023-03-24 03:51:10 +0300 779)
05d292b2 (kx 2023-03-24 03:51:10 +0300 780) r = (char *)&reminder[0];
05d292b2 (kx 2023-03-24 03:51:10 +0300 781)
05d292b2 (kx 2023-03-24 03:51:10 +0300 782) /*********************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 783) Searching the real name of tag:
05d292b2 (kx 2023-03-24 03:51:10 +0300 784) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 785) lookup_tags_by_prefix( &names, n );
05d292b2 (kx 2023-03-24 03:51:10 +0300 786) while( *r )
05d292b2 (kx 2023-03-24 03:51:10 +0300 787) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 788) b = r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 789) while( *r && *r != '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 790) ++r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 791) if( *r )
05d292b2 (kx 2023-03-24 03:51:10 +0300 792) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 793) *r = '\0'; ++r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 794) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 795)
05d292b2 (kx 2023-03-24 03:51:10 +0300 796) if( b && *b )
05d292b2 (kx 2023-03-24 03:51:10 +0300 797) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 798) char probe[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 799) sprintf( probe, "%s/%s", tag, b );
05d292b2 (kx 2023-03-24 03:51:10 +0300 800)
05d292b2 (kx 2023-03-24 03:51:10 +0300 801) found = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 802) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 803) size_t i, len = strlen( probe );
05d292b2 (kx 2023-03-24 03:51:10 +0300 804) for( i = 0; i < names->len; ++i )
05d292b2 (kx 2023-03-24 03:51:10 +0300 805) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 806) if( !strncmp( probe, names->name[i], len ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 807) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 808) ++found;
05d292b2 (kx 2023-03-24 03:51:10 +0300 809) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 810) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 811) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 812) if( found == 1 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 813) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 814) strcat( tag, "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 815) strcat( tag, b );
05d292b2 (kx 2023-03-24 03:51:10 +0300 816) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 817) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 818) if( found )
05d292b2 (kx 2023-03-24 03:51:10 +0300 819) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 820) strcat( tag, "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 821) strcat( tag, b );
05d292b2 (kx 2023-03-24 03:51:10 +0300 822) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 823) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 824) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 825) cgit_ref_names_free( names );
05d292b2 (kx 2023-03-24 03:51:10 +0300 826)
05d292b2 (kx 2023-03-24 03:51:10 +0300 827) if( found )
05d292b2 (kx 2023-03-24 03:51:10 +0300 828) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 829) strcat( ref, tag );
05d292b2 (kx 2023-03-24 03:51:10 +0300 830) p += r - &reminder[0];
05d292b2 (kx 2023-03-24 03:51:10 +0300 831) s = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 832) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 833) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 834) strcat( ref, n );
05d292b2 (kx 2023-03-24 03:51:10 +0300 835) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 836) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 837) sprintf( ref, "refs/heads/%s", ctx.repo.trunk );
05d292b2 (kx 2023-03-24 03:51:10 +0300 838)
05d292b2 (kx 2023-03-24 03:51:10 +0300 839) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 840) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 841) else if( !strcmp( n, "branches" ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 842) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 843) sprintf( ref, "refs/heads/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 844)
05d292b2 (kx 2023-03-24 03:51:10 +0300 845) n = s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 846) while( *p && *p != '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 847) ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 848) if( *p )
05d292b2 (kx 2023-03-24 03:51:10 +0300 849) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 850) *p = '\0'; s = ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 851) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 852) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 853) s = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 854)
05d292b2 (kx 2023-03-24 03:51:10 +0300 855) if( n && *n )
05d292b2 (kx 2023-03-24 03:51:10 +0300 856) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 857) int found = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 858) char branch[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 859) char reminder[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 860) char *b, *r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 861)
05d292b2 (kx 2023-03-24 03:51:10 +0300 862) struct cgit_ref_names *names = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 863)
05d292b2 (kx 2023-03-24 03:51:10 +0300 864) sprintf( reminder, "%s", s );
05d292b2 (kx 2023-03-24 03:51:10 +0300 865) sprintf( branch, "%s", n );
05d292b2 (kx 2023-03-24 03:51:10 +0300 866)
05d292b2 (kx 2023-03-24 03:51:10 +0300 867) r = (char *)&reminder[0];
05d292b2 (kx 2023-03-24 03:51:10 +0300 868)
05d292b2 (kx 2023-03-24 03:51:10 +0300 869) /************************************
05d292b2 (kx 2023-03-24 03:51:10 +0300 870) Searching the real name of branch:
05d292b2 (kx 2023-03-24 03:51:10 +0300 871) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 872) lookup_branches_by_prefix( &names, n );
05d292b2 (kx 2023-03-24 03:51:10 +0300 873) while( *r )
05d292b2 (kx 2023-03-24 03:51:10 +0300 874) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 875) b = r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 876) while( *r && *r != '/' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 877) ++r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 878) if( *r )
05d292b2 (kx 2023-03-24 03:51:10 +0300 879) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 880) *r = '\0'; ++r;
05d292b2 (kx 2023-03-24 03:51:10 +0300 881) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 882)
05d292b2 (kx 2023-03-24 03:51:10 +0300 883) if( b && *b )
05d292b2 (kx 2023-03-24 03:51:10 +0300 884) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 885) char probe[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 886) sprintf( probe, "%s/%s", branch, b );
05d292b2 (kx 2023-03-24 03:51:10 +0300 887)
05d292b2 (kx 2023-03-24 03:51:10 +0300 888) found = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 889) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 890) size_t i, len = strlen( probe );
05d292b2 (kx 2023-03-24 03:51:10 +0300 891) for( i = 0; i < names->len; ++i )
05d292b2 (kx 2023-03-24 03:51:10 +0300 892) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 893) if( !strncmp( probe, names->name[i], len ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 894) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 895) ++found;
05d292b2 (kx 2023-03-24 03:51:10 +0300 896) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 897) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 898) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 899) if( found == 1 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 900) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 901) strcat( branch, "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 902) strcat( branch, b );
05d292b2 (kx 2023-03-24 03:51:10 +0300 903) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 904) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 905) if( found )
05d292b2 (kx 2023-03-24 03:51:10 +0300 906) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 907) strcat( branch, "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 908) strcat( branch, b );
05d292b2 (kx 2023-03-24 03:51:10 +0300 909) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 910) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 911) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 912) cgit_ref_names_free( names );
05d292b2 (kx 2023-03-24 03:51:10 +0300 913)
05d292b2 (kx 2023-03-24 03:51:10 +0300 914) if( found )
05d292b2 (kx 2023-03-24 03:51:10 +0300 915) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 916) strcat( ref, branch );
05d292b2 (kx 2023-03-24 03:51:10 +0300 917) p += r - &reminder[0];
05d292b2 (kx 2023-03-24 03:51:10 +0300 918) s = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 919) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 920) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 921) strcat( ref, n );
05d292b2 (kx 2023-03-24 03:51:10 +0300 922) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 923) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 924) sprintf( ref, "refs/heads/%s", ctx.repo.trunk );
05d292b2 (kx 2023-03-24 03:51:10 +0300 925)
05d292b2 (kx 2023-03-24 03:51:10 +0300 926) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 927) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 928) else if( !strcmp( n, "trunk" ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 929) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 930) sprintf( ref, "refs/heads/%s", ctx.repo.trunk );
05d292b2 (kx 2023-03-24 03:51:10 +0300 931) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 932) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 933) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 934) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 935) /* return '/' */
05d292b2 (kx 2023-03-24 03:51:10 +0300 936) *--p = '/'; p = n;
05d292b2 (kx 2023-03-24 03:51:10 +0300 937) sprintf( ref, "refs/heads/%s", ctx.repo.trunk );
05d292b2 (kx 2023-03-24 03:51:10 +0300 938) break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 939) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 940) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 941)
05d292b2 (kx 2023-03-24 03:51:10 +0300 942) path = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 943)
05d292b2 (kx 2023-03-24 03:51:10 +0300 944) if( *path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 945) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 946) len = (int)strlen( path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 947)
05d292b2 (kx 2023-03-24 03:51:10 +0300 948) if( path[len-1] =='/' ) { path[len-1] = '\0'; --len; }
05d292b2 (kx 2023-03-24 03:51:10 +0300 949) len += 1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 950)
05d292b2 (kx 2023-03-24 03:51:10 +0300 951) sprintf( rpath, "%s", path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 952) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 953)
05d292b2 (kx 2023-03-24 03:51:10 +0300 954) free( path_info );
05d292b2 (kx 2023-03-24 03:51:10 +0300 955) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 956) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 957)
05d292b2 (kx 2023-03-24 03:51:10 +0300 958) static void fill_hex_list( struct cgit_hex_commits **hex_commits, char *buf )
05d292b2 (kx 2023-03-24 03:51:10 +0300 959) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 960) char *s, *p = NULL, *h;
05d292b2 (kx 2023-03-24 03:51:10 +0300 961) struct cgit_hex_commits *commits = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 962)
05d292b2 (kx 2023-03-24 03:51:10 +0300 963) if( !hex_commits || !buf ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 964)
05d292b2 (kx 2023-03-24 03:51:10 +0300 965) cgit_hex_commits_allocate( &commits );
05d292b2 (kx 2023-03-24 03:51:10 +0300 966) *hex_commits = commits;
05d292b2 (kx 2023-03-24 03:51:10 +0300 967)
05d292b2 (kx 2023-03-24 03:51:10 +0300 968) s = buf;
05d292b2 (kx 2023-03-24 03:51:10 +0300 969) while( *s )
05d292b2 (kx 2023-03-24 03:51:10 +0300 970) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 971) while( *s && *s == '\n' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 972) ++s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 973) h = p = s;
05d292b2 (kx 2023-03-24 03:51:10 +0300 974)
05d292b2 (kx 2023-03-24 03:51:10 +0300 975) while( *p && *p != '\n' )
05d292b2 (kx 2023-03-24 03:51:10 +0300 976) ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 977) if( *p )
05d292b2 (kx 2023-03-24 03:51:10 +0300 978) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 979) *p = '\0'; s = ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 980) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 981) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 982) s = p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 983)
05d292b2 (kx 2023-03-24 03:51:10 +0300 984) cgit_hex_commits_add( commits, h );
05d292b2 (kx 2023-03-24 03:51:10 +0300 985) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 986) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 987)
05d292b2 (kx 2023-03-24 03:51:10 +0300 988)
05d292b2 (kx 2023-03-24 03:51:10 +0300 989) void cgit_fill_commits_list( struct cgit_hex_commits **hex_commits, int ofs, const char *relative_path, const char *revision )
05d292b2 (kx 2023-03-24 03:51:10 +0300 990) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 991) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 992)
05d292b2 (kx 2023-03-24 03:51:10 +0300 993) if( !hex_commits || !relative_path ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 994)
05d292b2 (kx 2023-03-24 03:51:10 +0300 995) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 996) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 997) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 998)
05d292b2 (kx 2023-03-24 03:51:10 +0300 999) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1000) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1001) char ref[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1002) char rpath[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1003) int psize = atoi( ctx.vars.page_size );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1004)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1005) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1006) char cmd[PATH_MAX];
05d292b2 (kx 2023-03-24 03:51:10 +0300 1007) struct strbuf buf = STRBUF_INIT;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1008) pid_t p = (pid_t) -1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1009) int rc;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1010)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1011) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1012) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1013) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1014) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1015) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1016) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1017) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1018)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1019) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1020) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1021) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1022) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1023)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1024) parse_relative_path( (char *)&ref[0], (char *)&rpath[0], relative_path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1025)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1026) /*
05d292b2 (kx 2023-03-24 03:51:10 +0300 1027) NOTE:
05d292b2 (kx 2023-03-24 03:51:10 +0300 1028) ====
05d292b2 (kx 2023-03-24 03:51:10 +0300 1029) The --follow option for blobs is not applicable here because the option --skip=n
05d292b2 (kx 2023-03-24 03:51:10 +0300 1030) doesn't works when option --follow is defined.
05d292b2 (kx 2023-03-24 03:51:10 +0300 1031)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1032) In other words we cannot use --follow here:
05d292b2 (kx 2023-03-24 03:51:10 +0300 1033)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1034) struct cgit_info info = CGIT_INFO_INIT;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1035) const char *follow = "";
05d292b2 (kx 2023-03-24 03:51:10 +0300 1036)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1037) if( revision && *revision )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1038) strncpy( info.revision, revision, GIT_OID_HEXSZ+1 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1039) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 1040) strncpy( info.revision, ctx.repo.info.revision, GIT_OID_HEXSZ+1 );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1041)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1042) fill_commit_info( &info, (const char *)&path[0], (const char *)&rpath[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1043) if( info.kind == GIT_OBJECT_BLOB )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1044) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1045) follow = "--follow";
05d292b2 (kx 2023-03-24 03:51:10 +0300 1046) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1047) */
05d292b2 (kx 2023-03-24 03:51:10 +0300 1048)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1049) ++psize;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1050)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1051) if( revision && *revision )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1052) snprintf( (char *)&cmd[0], 1024, "git --git-dir=%s log --pretty=format:'%%H' --skip=%d -%d %s -- %s 2>/dev/null", (char *)&path[0], ofs, psize, revision, (char *)&rpath[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1053) else
05d292b2 (kx 2023-03-24 03:51:10 +0300 1054) snprintf( (char *)&cmd[0], 1024, "git --git-dir=%s log --pretty=format:'%%H' --skip=%d -%d %s -- %s 2>/dev/null", (char *)&path[0], ofs, psize, (char *)&ref[0], (char *)&rpath[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1055) p = sys_exec_command( &buf, cmd );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1056) rc = sys_wait_command( p, NULL );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1057) if( rc != 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1058) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1059) strbuf_release( &buf );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1060) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1061) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1062)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1063) if( buf.buf[0] )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1064) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1065) strbuf_trim( &buf );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1066)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1067) fill_hex_list( hex_commits, (char *)&buf.buf[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1068) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1069)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1070) strbuf_release( &buf );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1071) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1072)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1073) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1074) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1075)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1076) git_repository *cgit_open_repository( void )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1077) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1078) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1079) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1080)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1081) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1082) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1083) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1084)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1085) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1086) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1087) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1088)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1089) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1090) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1091) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1092) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1093) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1094) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1095) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1096)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1097) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1098) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1099) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1100) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1101)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1102) return open_repository( (const char *)&path[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1103) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1104)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1105) return repo;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1106) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1107)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1108) git_commit *lookup_commit_by_ref( const char *ref )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1109) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1110) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1111) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1112)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1113) if( !ref || !*ref ) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1114)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1115) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1116) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1117) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1118)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1119) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1120) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1121) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1122) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1123)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1124) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1125) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1126) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1127) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1128) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1129) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1130) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1131)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1132) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1133) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1134) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1135) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1136)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1137) if( !(repo = open_repository( (const char *)&path[0] )) ) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1138) commit = get_commit_by_ref( repo, ref );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1139) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1140) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1141)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1142) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1143) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1144)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1145) git_commit *lookup_commit_by_hex( const char *hex )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1146) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1147) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1148) git_commit *commit = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1149)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1150) if( !hex || !*hex ) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1151)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1152) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1153) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1154) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1155)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1156) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1157) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1158) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1159) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1160)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1161) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1162) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1163) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1164) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1165) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1166) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1167) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1168)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1169) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1170) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1171) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1172) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1173)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1174) if( !(repo = open_repository( (const char *)&path[0] )) ) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1175) commit = get_commit_by_hex( repo, hex );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1176) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1177) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1178)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1179) return commit;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1180) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1181)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1182)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1183) struct print_data {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1184) struct strbuf *sb;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1185) int *files;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1186) int *insertions;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1187) int *deletions;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1188) };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1189)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1190) static int printer( const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line, void *data )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1191) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1192) struct print_data *pdata = (struct print_data *)data;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1193)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1194) (void)delta; (void)hunk;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1195)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1196) switch( line->origin )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1197) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1198) case GIT_DIFF_LINE_ADDITION: *pdata->insertions += 1; break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1199) case GIT_DIFF_LINE_DELETION: *pdata->deletions += 1; break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1200) case GIT_DIFF_LINE_FILE_HDR: *pdata->files += 1; break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1201) default: break;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1202) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1203)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1204) if( line->origin == GIT_DIFF_LINE_CONTEXT ||
05d292b2 (kx 2023-03-24 03:51:10 +0300 1205) line->origin == GIT_DIFF_LINE_ADDITION ||
05d292b2 (kx 2023-03-24 03:51:10 +0300 1206) line->origin == GIT_DIFF_LINE_DELETION )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1207) strbuf_addch( pdata->sb, line->origin );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1208)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1209) strbuf_add( pdata->sb, (const void *)line->content, (size_t)line->content_len );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1210)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1211) return 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1212) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1213)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1214) void cgit_fill_diff_with_parent( struct strbuf *sb, char *parent_hex, size_t parent_len, int *files, int *insertions, int *deletions, const char *hex )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1215) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1216) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1217)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1218) git_commit *commit = NULL, *parent = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1219) git_tree *commit_tree = NULL, *parent_tree = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1220) git_diff *diff = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1221)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1222) struct print_data data = { .sb = NULL, .files = NULL, .insertions = NULL, .deletions = NULL };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1223)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1224) if( !parent_hex || !files || !insertions || !deletions || !hex || !*hex ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1225) if( parent_len != GIT_OID_HEXSZ+1 ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1226)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1227) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1228) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1229) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1230)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1231) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1232) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1233) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1234) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1235)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1236) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1237) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1238) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1239) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1240) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1241) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1242) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1243)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1244) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1245) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1246) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1247) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1248)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1249) if( !(repo = open_repository( (const char *)&path[0] )) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1250)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1251) commit = get_commit_by_hex( repo, hex );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1252) if( git_commit_parent( &parent, commit, 0 ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1253) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1254) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1255) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1256) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1257) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1258) if( git_oid_tostr( parent_hex, GIT_OID_HEXSZ+1, git_commit_id( parent ) ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1259) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1260) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1261) git_commit_free( parent );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1262) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1263) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1264) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1265)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1266) if( git_commit_tree( &commit_tree, commit ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1267) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1268) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1269) git_commit_free( parent );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1270) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1271) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1272) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1273) if( git_commit_tree( &parent_tree, parent ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1274) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1275) git_tree_free( commit_tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1276) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1277) git_commit_free( parent );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1278) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1279) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1280) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1281) if( git_diff_tree_to_tree( &diff, repo, parent_tree, commit_tree, NULL ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1282) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1283) git_tree_free( commit_tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1284) git_tree_free( parent_tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1285) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1286) git_commit_free( parent );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1287) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1288) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1289) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1290)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1291)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1292) *files = 0, *insertions = 0, *deletions = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1293)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1294) data.sb = sb;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1295) data.files = files;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1296) data.insertions = insertions;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1297) data.deletions = deletions;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1298)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1299) git_diff_print( diff, GIT_DIFF_FORMAT_PATCH, printer, &data );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1300)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1301) *files = *data.files, *insertions = *data.insertions, *deletions = *data.deletions;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1302)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1303) git_diff_free( diff );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1304) git_tree_free( commit_tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1305) git_tree_free( parent_tree );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1306) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1307) git_commit_free( parent );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1308)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1309) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1310) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1311) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1312)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1313)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1314) void cgit_diff_with_parent( struct strbuf *sb, char *parent_hex, size_t parent_len, int *files, int *insertions, int *deletions, const char *hex, const char *relative_path )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1315) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1316) const char *name = NULL, *git_root = NULL, *repo_root = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1317)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1318) git_commit *commit = NULL, *parent = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1319)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1320) if( !parent_hex || !files || !insertions || !deletions || !hex || !*hex || !relative_path || !*relative_path ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1321) if( parent_len != GIT_OID_HEXSZ+1 ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1322)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1323) name = ctx.repo.name;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1324) git_root = ctx.repo.git_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1325) repo_root = ctx.repo.repo_root;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1326)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1327) *files = 0, *insertions = 0, *deletions = 0;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1328)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1329) if( name && git_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1330) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1331) char ref[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1332) char rpath[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1333)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1334) git_repository *repo = NULL;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1335) char path[PATH_MAX] = { 0 };
05d292b2 (kx 2023-03-24 03:51:10 +0300 1336) char cmd[PATH_MAX];
05d292b2 (kx 2023-03-24 03:51:10 +0300 1337) struct strbuf buf = STRBUF_INIT;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1338) pid_t p = (pid_t) -1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1339) int rc;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1340)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1341) sprintf( (char *)&path[0], "%s/", git_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1342) if( repo_root && *repo_root )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1343) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1344) strcat( (char *)&path[0], repo_root );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1345) strcat( (char *)&path[0], "/" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1346) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1347) strcat( (char *)&path[0], name );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1348)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1349) if( !is_bare( (char *)&path[0] ) )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1350) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1351) strcat( (char *)&path[0], "/.git" );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1352) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1353)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1354) if( !(repo = open_repository( (const char *)&path[0] )) ) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1355)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1356) commit = get_commit_by_hex( repo, hex );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1357) if( git_commit_parent( &parent, commit, 0 ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1358) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1359) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1360) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1361) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1362) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1363) if( git_oid_tostr( parent_hex, GIT_OID_HEXSZ+1, git_commit_id( parent ) ) < 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1364) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1365) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1366) git_commit_free( parent );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1367) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1368) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1369) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1370)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1371) git_commit_free( commit );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1372) git_commit_free( parent );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1373) close_repository( repo );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1374)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1375) /* now we have two revisions */
05d292b2 (kx 2023-03-24 03:51:10 +0300 1376) parse_relative_path( (char *)&ref[0], (char *)&rpath[0], relative_path );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1377)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1378) snprintf( (char *)&cmd[0], 1024, "git --git-dir=%s diff %s %s -- %s 2>/dev/null", (char *)&path[0], parent_hex, hex, (char *)&rpath[0] );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1379) p = sys_exec_command( &buf, cmd );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1380) rc = sys_wait_command( p, NULL );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1381) if( rc != 0 )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1382) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1383) strbuf_release( &buf );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1384) return;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1385) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1386)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1387) if( buf.buf[0] )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1388) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1389) char *p = (char *)&buf.buf[0];
05d292b2 (kx 2023-03-24 03:51:10 +0300 1390)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1391) while( *p )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1392) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1393) if( *p == '\n' && p[1] && p[2] && p[3] )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1394) {
05d292b2 (kx 2023-03-24 03:51:10 +0300 1395) if( (p[1] == '+' && p[2] == '+' && p[3] == '+') ||
05d292b2 (kx 2023-03-24 03:51:10 +0300 1396) (p[1] == '-' && p[2] == '-' && p[3] == '-') )
05d292b2 (kx 2023-03-24 03:51:10 +0300 1397) *files += 1;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1398) if( p[1] == '+' && p[2] != '+' && p[3] != '+' ) { ++p; *insertions += 1; }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1399) if( p[1] == '-' && p[2] != '-' && p[3] != '-' ) { ++p; *deletions += 1; }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1400) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1401) ++p;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1402) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1403) *files /= 2;
05d292b2 (kx 2023-03-24 03:51:10 +0300 1404)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1405) strbuf_addbuf( sb, (const struct strbuf *)&buf );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1406) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1407)
05d292b2 (kx 2023-03-24 03:51:10 +0300 1408) strbuf_release( &buf );
05d292b2 (kx 2023-03-24 03:51:10 +0300 1409) }
05d292b2 (kx 2023-03-24 03:51:10 +0300 1410) }