Lindenii Project Forge
Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.
/forged/internal/ipc/git2c/extra.go (raw)
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
package git2c
import (
"encoding/hex"
"fmt"
"time"
)
func (c *Client) ResolveRef(repoPath, refType, refName string) (string, error) {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return "", fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(3); err != nil {
return "", fmt.Errorf("sending command failed: %w", err)
}
if err := c.writer.WriteData([]byte(refType)); err != nil {
return "", fmt.Errorf("sending ref type failed: %w", err)
}
if err := c.writer.WriteData([]byte(refName)); err != nil {
return "", fmt.Errorf("sending ref name failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return "", fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return "", Perror(status)
}
id, err := c.reader.ReadData()
if err != nil {
return "", fmt.Errorf("reading oid failed: %w", err)
}
return hex.EncodeToString(id), nil
}
func (c *Client) ListBranches(repoPath string) ([]string, error) {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return nil, fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(4); err != nil {
return nil, fmt.Errorf("sending command failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return nil, fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return nil, Perror(status)
}
count, err := c.reader.ReadUint()
if err != nil {
return nil, fmt.Errorf("reading count failed: %w", err)
}
branches := make([]string, 0, count)
for range count {
name, err := c.reader.ReadData()
if err != nil {
return nil, fmt.Errorf("reading branch name failed: %w", err)
}
branches = append(branches, string(name))
}
return branches, nil
}
func (c *Client) FormatPatch(repoPath, commitHex string) (string, error) {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return "", fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(5); err != nil {
return "", fmt.Errorf("sending command failed: %w", err)
}
if err := c.writer.WriteData([]byte(commitHex)); err != nil {
return "", fmt.Errorf("sending commit failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return "", fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return "", Perror(status)
}
buf, err := c.reader.ReadData()
if err != nil {
return "", fmt.Errorf("reading patch failed: %w", err)
}
return string(buf), nil
}
func (c *Client) CommitPatch(repoPath, commitHex string) (parentHex string, stats string, patch string, err error) {
if err = c.writer.WriteData([]byte(repoPath)); err != nil {
return "", "", "", fmt.Errorf("sending repo path failed: %w", err)
}
if err = c.writer.WriteUint(6); err != nil {
return "", "", "", fmt.Errorf("sending command failed: %w", err)
}
if err = c.writer.WriteData([]byte(commitHex)); err != nil {
return "", "", "", fmt.Errorf("sending commit failed: %w", err)
}
status, err2 := c.reader.ReadUint()
if err2 != nil {
return "", "", "", fmt.Errorf("reading status failed: %w", err2)
}
if status != 0 {
return "", "", "", Perror(status)
}
id, err2 := c.reader.ReadData()
if err2 != nil {
return "", "", "", fmt.Errorf("reading parent oid failed: %w", err2)
}
statsBytes, err2 := c.reader.ReadData()
if err2 != nil {
return "", "", "", fmt.Errorf("reading stats failed: %w", err2)
}
patchBytes, err2 := c.reader.ReadData()
if err2 != nil {
return "", "", "", fmt.Errorf("reading patch failed: %w", err2)
}
return hex.EncodeToString(id), string(statsBytes), string(patchBytes), nil
}
func (c *Client) MergeBase(repoPath, hexA, hexB string) (string, error) {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return "", fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(7); err != nil {
return "", fmt.Errorf("sending command failed: %w", err)
}
if err := c.writer.WriteData([]byte(hexA)); err != nil {
return "", fmt.Errorf("sending oid A failed: %w", err)
}
if err := c.writer.WriteData([]byte(hexB)); err != nil {
return "", fmt.Errorf("sending oid B failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return "", fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return "", Perror(status)
}
base, err := c.reader.ReadData()
if err != nil {
return "", fmt.Errorf("reading base oid failed: %w", err)
}
return hex.EncodeToString(base), nil
}
func (c *Client) Log(repoPath, refSpec string, n uint) ([]Commit, error) {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return nil, fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(8); err != nil {
return nil, fmt.Errorf("sending command failed: %w", err)
}
if err := c.writer.WriteData([]byte(refSpec)); err != nil {
return nil, fmt.Errorf("sending refspec failed: %w", err)
}
if err := c.writer.WriteUint(uint64(n)); err != nil {
return nil, fmt.Errorf("sending limit failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return nil, fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return nil, Perror(status)
}
var out []Commit
for {
id, err := c.reader.ReadData()
if err != nil {
break
}
title, _ := c.reader.ReadData()
authorName, _ := c.reader.ReadData()
authorEmail, _ := c.reader.ReadData()
date, _ := c.reader.ReadData()
out = append(out, Commit{
Hash: hex.EncodeToString(id),
Author: string(authorName),
Email: string(authorEmail),
Date: string(date),
Message: string(title),
})
}
return out, nil
}
func (c *Client) CommitTreeOID(repoPath, commitHex string) (string, error) {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return "", fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(12); err != nil {
return "", fmt.Errorf("sending command failed: %w", err)
}
if err := c.writer.WriteData([]byte(commitHex)); err != nil {
return "", fmt.Errorf("sending oid failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return "", fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return "", Perror(status)
}
id, err := c.reader.ReadData()
if err != nil {
return "", fmt.Errorf("reading tree oid failed: %w", err)
}
return hex.EncodeToString(id), nil
}
func (c *Client) CommitCreate(repoPath, treeHex string, parents []string, authorName, authorEmail string, when time.Time, message string) (string, error) {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return "", fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(13); err != nil {
return "", fmt.Errorf("sending command failed: %w", err)
}
if err := c.writer.WriteData([]byte(treeHex)); err != nil {
return "", fmt.Errorf("sending tree oid failed: %w", err)
}
if err := c.writer.WriteUint(uint64(len(parents))); err != nil {
return "", fmt.Errorf("sending parents count failed: %w", err)
}
for _, p := range parents {
if err := c.writer.WriteData([]byte(p)); err != nil {
return "", fmt.Errorf("sending parent oid failed: %w", err)
}
}
if err := c.writer.WriteData([]byte(authorName)); err != nil {
return "", fmt.Errorf("sending author name failed: %w", err)
}
if err := c.writer.WriteData([]byte(authorEmail)); err != nil {
return "", fmt.Errorf("sending author email failed: %w", err)
}
if err := c.writer.WriteInt(when.Unix()); err != nil {
return "", fmt.Errorf("sending when failed: %w", err)
}
_, offset := when.Zone()
if err := c.writer.WriteInt(int64(offset / 60)); err != nil {
return "", fmt.Errorf("sending tz offset failed: %w", err)
}
if err := c.writer.WriteData([]byte(message)); err != nil {
return "", fmt.Errorf("sending message failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return "", fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return "", Perror(status)
}
id, err := c.reader.ReadData()
if err != nil {
return "", fmt.Errorf("reading commit oid failed: %w", err)
}
return hex.EncodeToString(id), nil
}
func (c *Client) UpdateRef(repoPath, refName, commitHex string) error {
if err := c.writer.WriteData([]byte(repoPath)); err != nil {
return fmt.Errorf("sending repo path failed: %w", err)
}
if err := c.writer.WriteUint(14); err != nil {
return fmt.Errorf("sending command failed: %w", err)
}
if err := c.writer.WriteData([]byte(refName)); err != nil {
return fmt.Errorf("sending ref name failed: %w", err)
}
if err := c.writer.WriteData([]byte(commitHex)); err != nil {
return fmt.Errorf("sending commit oid failed: %w", err)
}
status, err := c.reader.ReadUint()
if err != nil {
return fmt.Errorf("reading status failed: %w", err)
}
if status != 0 {
return Perror(status)
}
return nil
}