diff --git a/server/git/git.go b/server/git/git.go
new file mode 100644
index 0000000..bf95f7c
--- /dev/null
+++ b/server/git/git.go
@@ -0,0 +1,788 @@
+package git
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// GitInterface defines the contract for Git operations
+type GitInterface interface {
+	// Repository operations
+	Init(ctx context.Context, path string) error
+	Clone(ctx context.Context, url, path string) error
+	IsRepository(ctx context.Context, path string) (bool, error)
+
+	// Status and information
+	Status(ctx context.Context) (*Status, error)
+	Log(ctx context.Context, options LogOptions) ([]Commit, error)
+	Show(ctx context.Context, ref string) (*Commit, error)
+
+	// Branch operations
+	ListBranches(ctx context.Context) ([]Branch, error)
+	CreateBranch(ctx context.Context, name string, startPoint string) error
+	Checkout(ctx context.Context, ref string) error
+	DeleteBranch(ctx context.Context, name string, force bool) error
+	GetCurrentBranch(ctx context.Context) (string, error)
+
+	// Commit operations
+	Add(ctx context.Context, paths []string) error
+	AddAll(ctx context.Context) error
+	Commit(ctx context.Context, message string, options CommitOptions) error
+
+	// Remote operations
+	ListRemotes(ctx context.Context) ([]Remote, error)
+	AddRemote(ctx context.Context, name, url string) error
+	RemoveRemote(ctx context.Context, name string) error
+	Fetch(ctx context.Context, remote string, options FetchOptions) error
+	Pull(ctx context.Context, remote, branch string) error
+	Push(ctx context.Context, remote, branch string, options PushOptions) error
+
+	// Merge operations
+	Merge(ctx context.Context, ref string, options MergeOptions) error
+	MergeBase(ctx context.Context, ref1, ref2 string) (string, error)
+
+	// Configuration
+	GetConfig(ctx context.Context, key string) (string, error)
+	SetConfig(ctx context.Context, key, value string) error
+	GetUserConfig(ctx context.Context) (*UserConfig, error)
+	SetUserConfig(ctx context.Context, config UserConfig) error
+}
+
+// Status represents the current state of the repository
+type Status struct {
+	Branch    string
+	IsClean   bool
+	Staged    []FileStatus
+	Unstaged  []FileStatus
+	Untracked []string
+	Conflicts []string
+}
+
+// FileStatus represents the status of a file
+type FileStatus struct {
+	Path   string
+	Status string // "modified", "added", "deleted", "renamed", etc.
+	Staged bool
+}
+
+// Commit represents a Git commit
+type Commit struct {
+	Hash      string
+	Author    Author
+	Committer Author
+	Message   string
+	Parents   []string
+	Timestamp time.Time
+	Files     []CommitFile
+}
+
+// Author represents a Git author or committer
+type Author struct {
+	Name  string
+	Email string
+	Time  time.Time
+}
+
+// CommitFile represents a file in a commit
+type CommitFile struct {
+	Path      string
+	Status    string // "added", "modified", "deleted", "renamed"
+	Additions int
+	Deletions int
+}
+
+// Branch represents a Git branch
+type Branch struct {
+	Name      string
+	IsCurrent bool
+	IsRemote  bool
+	Commit    string
+	Message   string
+}
+
+// Remote represents a Git remote
+type Remote struct {
+	Name string
+	URL  string
+}
+
+// UserConfig represents Git user configuration
+type UserConfig struct {
+	Name  string
+	Email string
+}
+
+// LogOptions defines options for log operations
+type LogOptions struct {
+	MaxCount int
+	Since    time.Time
+	Until    time.Time
+	Author   string
+	Path     string
+	Oneline  bool
+}
+
+// CommitOptions defines options for commit operations
+type CommitOptions struct {
+	Author     *Author
+	Committer  *Author
+	Sign       bool
+	AllowEmpty bool
+}
+
+// FetchOptions defines options for fetch operations
+type FetchOptions struct {
+	All   bool
+	Tags  bool
+	Depth int
+	Prune bool
+}
+
+// PushOptions defines options for push operations
+type PushOptions struct {
+	Force       bool
+	Tags        bool
+	SetUpstream bool
+}
+
+// MergeOptions defines options for merge operations
+type MergeOptions struct {
+	NoFF     bool
+	Message  string
+	Strategy string
+}
+
+// GitError represents a Git-specific error
+type GitError struct {
+	Command string
+	Output  string
+	Err     error
+}
+
+func (e *GitError) Error() string {
+	if e.Err != nil {
+		return fmt.Sprintf("git %s failed: %v\nOutput: %s", e.Command, e.Err, e.Output)
+	}
+	return fmt.Sprintf("git %s failed\nOutput: %s", e.Command, e.Output)
+}
+
+func (e *GitError) Unwrap() error {
+	return e.Err
+}
+
+// Git implementation using os/exec to call git commands
+type Git struct {
+	repoPath string
+	config   GitConfig
+}
+
+// GitConfig holds configuration for Git operations
+type GitConfig struct {
+	Timeout time.Duration
+	Env     map[string]string
+}
+
+// NewGit creates a new Git instance
+func NewGit(repoPath string, config GitConfig) GitInterface {
+	if config.Timeout == 0 {
+		config.Timeout = 30 * time.Second
+	}
+
+	return &Git{
+		repoPath: repoPath,
+		config:   config,
+	}
+}
+
+// DefaultGit creates a Git instance with default configuration
+func DefaultGit(repoPath string) GitInterface {
+	return NewGit(repoPath, GitConfig{
+		Timeout: 30 * time.Second,
+		Env:     make(map[string]string),
+	})
+}
+
+// Ensure Git implements GitInterface
+var _ GitInterface = (*Git)(nil)
+
+// Init initializes a new Git repository
+func (g *Git) Init(ctx context.Context, path string) error {
+	cmd := exec.CommandContext(ctx, "git", "init")
+	cmd.Dir = path
+	return g.runCommand(cmd, "init")
+}
+
+// Clone clones a repository from URL to path
+func (g *Git) Clone(ctx context.Context, url, path string) error {
+	cmd := exec.CommandContext(ctx, "git", "clone", url, path)
+	return g.runCommand(cmd, "clone")
+}
+
+// IsRepository checks if a path is a valid Git repository
+func (g *Git) IsRepository(ctx context.Context, path string) (bool, error) {
+	return g.isValidRepo(path), nil
+}
+
+// Status returns the current status of the repository
+func (g *Git) Status(ctx context.Context) (*Status, error) {
+	cmd := exec.CommandContext(ctx, "git", "status", "--porcelain", "--branch")
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "status")
+	if err != nil {
+		return nil, err
+	}
+
+	return g.parseStatus(output)
+}
+
+// Log returns commit history
+func (g *Git) Log(ctx context.Context, options LogOptions) ([]Commit, error) {
+	args := []string{"log", "--format=%H%n%an%n%ae%n%at%n%s%n%cn%n%ce%n%ct%n%P"}
+
+	if options.MaxCount > 0 {
+		args = append(args, fmt.Sprintf("-%d", options.MaxCount))
+	}
+
+	if !options.Since.IsZero() {
+		args = append(args, fmt.Sprintf("--since=%s", options.Since.Format(time.RFC3339)))
+	}
+
+	if !options.Until.IsZero() {
+		args = append(args, fmt.Sprintf("--until=%s", options.Until.Format(time.RFC3339)))
+	}
+
+	if options.Author != "" {
+		args = append(args, fmt.Sprintf("--author=%s", options.Author))
+	}
+
+	if options.Path != "" {
+		args = append(args, "--", options.Path)
+	}
+
+	if options.Oneline {
+		args = append(args, "--oneline")
+	}
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "log")
+	if err != nil {
+		return nil, err
+	}
+
+	return g.parseLog(output)
+}
+
+// Show shows commit details
+func (g *Git) Show(ctx context.Context, ref string) (*Commit, error) {
+	cmd := exec.CommandContext(ctx, "git", "show", "--format=json", ref)
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "show")
+	if err != nil {
+		return nil, err
+	}
+
+	commits, err := g.parseLog(output)
+	if err != nil || len(commits) == 0 {
+		return nil, &GitError{Command: "show", Output: "failed to parse commit"}
+	}
+
+	return &commits[0], nil
+}
+
+// ListBranches returns all branches
+func (g *Git) ListBranches(ctx context.Context) ([]Branch, error) {
+	cmd := exec.CommandContext(ctx, "git", "branch", "-a", "--format=%(refname:short)%09%(objectname)%09%(contents:subject)")
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "branch")
+	if err != nil {
+		return nil, err
+	}
+
+	return g.parseBranches(output)
+}
+
+// CreateBranch creates a new branch
+func (g *Git) CreateBranch(ctx context.Context, name string, startPoint string) error {
+	args := []string{"branch", name}
+	if startPoint != "" {
+		args = append(args, startPoint)
+	}
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "branch")
+}
+
+// Checkout switches to a branch or commit
+func (g *Git) Checkout(ctx context.Context, ref string) error {
+	cmd := exec.CommandContext(ctx, "git", "checkout", ref)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "checkout")
+}
+
+// DeleteBranch deletes a branch
+func (g *Git) DeleteBranch(ctx context.Context, name string, force bool) error {
+	args := []string{"branch"}
+	if force {
+		args = append(args, "-D")
+	} else {
+		args = append(args, "-d")
+	}
+	args = append(args, name)
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "branch")
+}
+
+// GetCurrentBranch returns the current branch name
+func (g *Git) GetCurrentBranch(ctx context.Context) (string, error) {
+	cmd := exec.CommandContext(ctx, "git", "rev-parse", "--abbrev-ref", "HEAD")
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "rev-parse")
+	if err != nil {
+		return "", err
+	}
+
+	return strings.TrimSpace(output), nil
+}
+
+// Add stages files for commit
+func (g *Git) Add(ctx context.Context, paths []string) error {
+	args := append([]string{"add"}, paths...)
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "add")
+}
+
+// AddAll stages all changes
+func (g *Git) AddAll(ctx context.Context) error {
+	cmd := exec.CommandContext(ctx, "git", "add", "-A")
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "add")
+}
+
+// Commit creates a new commit
+func (g *Git) Commit(ctx context.Context, message string, options CommitOptions) error {
+	args := []string{"commit", "-m", message}
+
+	if options.Author != nil {
+		args = append(args, fmt.Sprintf("--author=%s <%s>", options.Author.Name, options.Author.Email))
+	}
+
+	if options.Sign {
+		args = append(args, "-S")
+	}
+
+	if options.AllowEmpty {
+		args = append(args, "--allow-empty")
+	}
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "commit")
+}
+
+// ListRemotes returns all remotes
+func (g *Git) ListRemotes(ctx context.Context) ([]Remote, error) {
+	cmd := exec.CommandContext(ctx, "git", "remote", "-v")
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "remote")
+	if err != nil {
+		return nil, err
+	}
+
+	return g.parseRemotes(output)
+}
+
+// AddRemote adds a new remote
+func (g *Git) AddRemote(ctx context.Context, name, url string) error {
+	cmd := exec.CommandContext(ctx, "git", "remote", "add", name, url)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "remote")
+}
+
+// RemoveRemote removes a remote
+func (g *Git) RemoveRemote(ctx context.Context, name string) error {
+	cmd := exec.CommandContext(ctx, "git", "remote", "remove", name)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "remote")
+}
+
+// Fetch fetches from a remote
+func (g *Git) Fetch(ctx context.Context, remote string, options FetchOptions) error {
+	args := []string{"fetch"}
+
+	if options.All {
+		args = append(args, "--all")
+	} else if remote != "" {
+		args = append(args, remote)
+	}
+
+	if options.Tags {
+		args = append(args, "--tags")
+	}
+
+	if options.Depth > 0 {
+		args = append(args, fmt.Sprintf("--depth=%d", options.Depth))
+	}
+
+	if options.Prune {
+		args = append(args, "--prune")
+	}
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "fetch")
+}
+
+// Pull pulls from a remote
+func (g *Git) Pull(ctx context.Context, remote, branch string) error {
+	args := []string{"pull"}
+	if remote != "" {
+		args = append(args, remote)
+		if branch != "" {
+			args = append(args, branch)
+		}
+	}
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "pull")
+}
+
+// Push pushes to a remote
+func (g *Git) Push(ctx context.Context, remote, branch string, options PushOptions) error {
+	args := []string{"push"}
+
+	if options.Force {
+		args = append(args, "--force")
+	}
+
+	if options.Tags {
+		args = append(args, "--tags")
+	}
+
+	if options.SetUpstream {
+		args = append(args, "--set-upstream")
+	}
+
+	if remote != "" {
+		args = append(args, remote)
+		if branch != "" {
+			args = append(args, branch)
+		}
+	}
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "push")
+}
+
+// Merge merges a branch into current branch
+func (g *Git) Merge(ctx context.Context, ref string, options MergeOptions) error {
+	args := []string{"merge"}
+
+	if options.NoFF {
+		args = append(args, "--no-ff")
+	}
+
+	if options.Message != "" {
+		args = append(args, "-m", options.Message)
+	}
+
+	if options.Strategy != "" {
+		args = append(args, "-s", options.Strategy)
+	}
+
+	args = append(args, ref)
+
+	cmd := exec.CommandContext(ctx, "git", args...)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "merge")
+}
+
+// MergeBase finds the common ancestor of two commits
+func (g *Git) MergeBase(ctx context.Context, ref1, ref2 string) (string, error) {
+	cmd := exec.CommandContext(ctx, "git", "merge-base", ref1, ref2)
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "merge-base")
+	if err != nil {
+		return "", err
+	}
+
+	return strings.TrimSpace(output), nil
+}
+
+// GetConfig gets a Git configuration value
+func (g *Git) GetConfig(ctx context.Context, key string) (string, error) {
+	cmd := exec.CommandContext(ctx, "git", "config", "--get", key)
+	cmd.Dir = g.repoPath
+	output, err := g.runCommandWithOutput(cmd, "config")
+	if err != nil {
+		return "", err
+	}
+
+	return strings.TrimSpace(output), nil
+}
+
+// SetConfig sets a Git configuration value
+func (g *Git) SetConfig(ctx context.Context, key, value string) error {
+	cmd := exec.CommandContext(ctx, "git", "config", key, value)
+	cmd.Dir = g.repoPath
+	return g.runCommand(cmd, "config")
+}
+
+// GetUserConfig gets user configuration
+func (g *Git) GetUserConfig(ctx context.Context) (*UserConfig, error) {
+	name, err := g.GetConfig(ctx, "user.name")
+	if err != nil {
+		return nil, err
+	}
+
+	email, err := g.GetConfig(ctx, "user.email")
+	if err != nil {
+		return nil, err
+	}
+
+	return &UserConfig{
+		Name:  name,
+		Email: email,
+	}, nil
+}
+
+// SetUserConfig sets user configuration
+func (g *Git) SetUserConfig(ctx context.Context, config UserConfig) error {
+	if err := g.SetConfig(ctx, "user.name", config.Name); err != nil {
+		return err
+	}
+
+	return g.SetConfig(ctx, "user.email", config.Email)
+}
+
+// Helper methods
+
+func (g *Git) runCommand(cmd *exec.Cmd, command string) error {
+	output, err := cmd.CombinedOutput()
+	if err != nil {
+		return &GitError{
+			Command: command,
+			Output:  string(output),
+			Err:     err,
+		}
+	}
+	return nil
+}
+
+func (g *Git) runCommandWithOutput(cmd *exec.Cmd, command string) (string, error) {
+	output, err := cmd.CombinedOutput()
+	if err != nil {
+		return "", &GitError{
+			Command: command,
+			Output:  string(output),
+			Err:     err,
+		}
+	}
+	return string(output), nil
+}
+
+func (g *Git) isValidRepo(path string) bool {
+	gitDir := filepath.Join(path, ".git")
+	info, err := os.Stat(gitDir)
+	return err == nil && info.IsDir()
+}
+
+func (g *Git) parseStatus(output string) (*Status, error) {
+	lines := strings.Split(strings.TrimSpace(output), "\n")
+	status := &Status{
+		Staged:    []FileStatus{},
+		Unstaged:  []FileStatus{},
+		Untracked: []string{},
+		Conflicts: []string{},
+	}
+
+	for _, line := range lines {
+		if strings.HasPrefix(line, "## ") {
+			// Parse branch info
+			parts := strings.Fields(line[3:])
+			if len(parts) > 0 {
+				status.Branch = parts[0]
+			}
+			continue
+		}
+
+		if len(line) < 3 {
+			continue
+		}
+
+		// Parse file status
+		staged := line[0:1]
+		unstaged := line[1:2]
+		path := strings.TrimSpace(line[3:])
+
+		if staged != " " {
+			status.Staged = append(status.Staged, FileStatus{
+				Path:   path,
+				Status: g.parseStatusCode(staged),
+				Staged: true,
+			})
+		}
+
+		if unstaged != " " {
+			status.Unstaged = append(status.Unstaged, FileStatus{
+				Path:   path,
+				Status: g.parseStatusCode(unstaged),
+				Staged: false,
+			})
+		}
+
+		if staged == " " && unstaged == "?" {
+			status.Untracked = append(status.Untracked, path)
+		}
+	}
+
+	status.IsClean = len(status.Staged) == 0 && len(status.Unstaged) == 0 && len(status.Untracked) == 0
+	return status, nil
+}
+
+func (g *Git) parseStatusCode(code string) string {
+	switch code {
+	case "M":
+		return "modified"
+	case "A":
+		return "added"
+	case "D":
+		return "deleted"
+	case "R":
+		return "renamed"
+	case "C":
+		return "copied"
+	case "U":
+		return "unmerged"
+	default:
+		return "unknown"
+	}
+}
+
+func (g *Git) parseLog(output string) ([]Commit, error) {
+	lines := strings.Split(strings.TrimSpace(output), "\n")
+	var commits []Commit
+
+	// Each commit takes 9 lines in the format:
+	// Hash, AuthorName, AuthorEmail, AuthorTime, Subject, CommitterName, CommitterEmail, CommitterTime, Parents
+	for i := 0; i < len(lines); i += 9 {
+		if i+8 >= len(lines) {
+			break
+		}
+
+		hash := lines[i]
+		authorName := lines[i+1]
+		authorEmail := lines[i+2]
+		authorTimeStr := lines[i+3]
+		subject := lines[i+4]
+		committerName := lines[i+5]
+		committerEmail := lines[i+6]
+		committerTimeStr := lines[i+7]
+		parentsStr := lines[i+8]
+
+		// Parse timestamps
+		authorTime, _ := strconv.ParseInt(authorTimeStr, 10, 64)
+		committerTime, _ := strconv.ParseInt(committerTimeStr, 10, 64)
+
+		// Parse parents
+		var parents []string
+		if parentsStr != "" {
+			parents = strings.Fields(parentsStr)
+		}
+
+		commit := Commit{
+			Hash: hash,
+			Author: Author{
+				Name:  authorName,
+				Email: authorEmail,
+				Time:  time.Unix(authorTime, 0),
+			},
+			Committer: Author{
+				Name:  committerName,
+				Email: committerEmail,
+				Time:  time.Unix(committerTime, 0),
+			},
+			Message:   subject,
+			Parents:   parents,
+			Timestamp: time.Unix(authorTime, 0),
+		}
+
+		commits = append(commits, commit)
+	}
+
+	return commits, nil
+}
+
+func (g *Git) parseBranches(output string) ([]Branch, error) {
+	lines := strings.Split(strings.TrimSpace(output), "\n")
+	var branches []Branch
+
+	for _, line := range lines {
+		if strings.TrimSpace(line) == "" {
+			continue
+		}
+
+		parts := strings.Split(line, "\t")
+		if len(parts) < 3 {
+			continue
+		}
+
+		branch := Branch{
+			Name:     parts[0],
+			Commit:   parts[1],
+			Message:  parts[2],
+			IsRemote: strings.HasPrefix(parts[0], "remotes/"),
+		}
+
+		// Check if this is the current branch
+		if !branch.IsRemote {
+			branch.IsCurrent = strings.HasPrefix(line, "*")
+		}
+
+		branches = append(branches, branch)
+	}
+
+	return branches, nil
+}
+
+func (g *Git) parseRemotes(output string) ([]Remote, error) {
+	lines := strings.Split(strings.TrimSpace(output), "\n")
+	var remotes []Remote
+	seen := make(map[string]bool)
+
+	for _, line := range lines {
+		if strings.TrimSpace(line) == "" {
+			continue
+		}
+
+		parts := strings.Fields(line)
+		if len(parts) < 3 {
+			continue
+		}
+
+		name := parts[0]
+		if seen[name] {
+			continue
+		}
+
+		remotes = append(remotes, Remote{
+			Name: name,
+			URL:  parts[1],
+		})
+		seen[name] = true
+	}
+
+	return remotes, nil
+}
