or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-commands.mdconfiguration.mdgit-integration.mdhooks.mdindex.mdlanguage-support.mdrepository-management.md

repository-management.mddocs/

0

# Repository Management

1

2

Repository and hook environment management through the Store system. The Store provides centralized management of hook repositories, environment caching, and cleanup operations for efficient hook execution and storage.

3

4

## Capabilities

5

6

### Store Class

7

8

Central repository and environment management system that handles cloning, caching, and lifecycle management of hook repositories.

9

10

```python { .api }

11

class Store:

12

"""

13

Centralized store for managing hook repositories and environments.

14

15

Provides caching, cloning, and cleanup functionality for hook repositories

16

and their associated environments. Manages the complete lifecycle from

17

initial repository cloning through environment installation to cleanup.

18

"""

19

20

def __init__(self, directory: str | None = None) -> None:

21

"""

22

Initialize store with optional custom directory.

23

24

Parameters:

25

- directory: Custom store directory path (uses default if None)

26

"""

27

28

def clone(self, repo: str, ref: str, deps: Sequence[str] = ()) -> str:

29

"""

30

Clone repository and return installation path.

31

32

Clones the specified repository at the given reference and prepares

33

it for hook installation. Handles caching to avoid duplicate clones.

34

35

Parameters:

36

- repo: Repository URL or local path

37

- ref: Git reference (tag, commit, branch)

38

- deps: Additional dependencies for environment

39

40

Returns:

41

- str: Path to cloned repository installation

42

"""

43

44

def make_local(self, deps: Sequence[str]) -> str:

45

"""

46

Create local repository installation for local hooks.

47

48

Sets up environment for locally defined hooks without external repository.

49

50

Parameters:

51

- deps: Dependencies for local hook environment

52

53

Returns:

54

- str: Path to local installation

55

"""

56

57

def mark_config_used(self, path: str) -> None:

58

"""

59

Mark configuration as recently used for garbage collection.

60

61

Parameters:

62

- path: Configuration file path to mark as used

63

"""

64

65

def select_all_configs(self) -> list[str]:

66

"""

67

Get all configuration files tracked by the store.

68

69

Returns:

70

- list: Paths to all tracked configuration files

71

"""

72

73

def delete_configs(self, configs: list[str]) -> None:

74

"""

75

Delete specified configuration files from tracking.

76

77

Parameters:

78

- configs: List of configuration paths to delete

79

"""

80

81

def select_all_repos(self) -> list[tuple[str, str, str]]:

82

"""

83

Get all repositories managed by the store.

84

85

Returns:

86

- list: Tuples of (repo_name, ref, path) for each repository

87

"""

88

89

def delete_repo(self, db_repo_name: str, ref: str, path: str) -> None:

90

"""

91

Delete repository from store and filesystem.

92

93

Parameters:

94

- db_repo_name: Database repository name

95

- ref: Git reference

96

- path: Repository path to delete

97

"""

98

99

@staticmethod

100

def get_default_directory() -> str:

101

"""

102

Get the default store directory path.

103

104

Returns:

105

- str: Default store directory (typically ~/.cache/pre-commit)

106

"""

107

```

108

109

### Repository Operations

110

111

High-level functions for working with repositories through the store system.

112

113

```python { .api }

114

def all_hooks(root_config: dict[str, Any], store: Store) -> tuple[Hook, ...]:

115

"""

116

Extract all configured hooks from configuration using store.

117

118

Processes the complete configuration file, clones required repositories

119

through the store, and creates Hook instances for all defined hooks.

120

121

Parameters:

122

- root_config: Loaded configuration dictionary

123

- store: Store instance for repository management

124

125

Returns:

126

- tuple: All configured Hook instances

127

"""

128

129

def install_hook_envs(hooks: Sequence[Hook], store: Store) -> None:

130

"""

131

Install environments for all provided hooks using store.

132

133

Coordinates with the store to ensure all hook environments are properly

134

installed and configured with their dependencies.

135

136

Parameters:

137

- hooks: Sequence of hooks requiring environment installation

138

- store: Store instance for environment management

139

"""

140

```

141

142

### Store Database Management

143

144

Internal database operations for tracking repositories and configurations.

145

146

```python { .api }

147

def _get_store_db(store_dir: str) -> sqlite3.Connection:

148

"""

149

Get database connection for store operations.

150

151

Parameters:

152

- store_dir: Store directory path

153

154

Returns:

155

- Connection: SQLite database connection

156

"""

157

158

def _init_store_db(db: sqlite3.Connection) -> None:

159

"""

160

Initialize store database with required tables.

161

162

Parameters:

163

- db: Database connection to initialize

164

"""

165

```

166

167

## Store Configuration

168

169

### Directory Structure

170

171

The store maintains a structured directory layout for efficient organization:

172

173

```

174

~/.cache/pre-commit/ # Default store directory

175

├── db.db # SQLite database for tracking

176

├── repos/ # Cloned repositories

177

│ ├── <repo-hash>/ # Individual repository directories

178

│ │ ├── .git/ # Git repository data

179

│ │ └── <hook-files> # Hook implementation files

180

│ └── ...

181

└── <language-envs>/ # Language-specific environments

182

├── py_env-<hash>/ # Python virtual environments

183

├── node_env-<hash>/ # Node.js environments

184

└── ...

185

```

186

187

### Store Initialization

188

189

```python { .api }

190

def initialize_store(directory: str | None = None) -> Store:

191

"""

192

Initialize a new store instance.

193

194

Parameters:

195

- directory: Custom directory (uses default if None)

196

197

Returns:

198

- Store: Initialized store instance

199

"""

200

```

201

202

## Repository Caching

203

204

### Cache Management

205

206

Functions for managing repository and environment caches.

207

208

```python { .api }

209

def clean_unused_repos(store: Store, configs_in_use: set[str]) -> None:

210

"""

211

Clean repositories not referenced by active configurations.

212

213

Parameters:

214

- store: Store instance to clean

215

- configs_in_use: Set of configuration files still in use

216

"""

217

218

def get_cache_stats(store: Store) -> dict[str, Any]:

219

"""

220

Get statistics about store cache usage.

221

222

Parameters:

223

- store: Store instance to analyze

224

225

Returns:

226

- dict: Cache statistics including size, file counts, etc.

227

"""

228

```

229

230

### Garbage Collection

231

232

```python { .api }

233

def garbage_collect_repos(store: Store) -> int:

234

"""

235

Perform garbage collection on unused repositories.

236

237

Removes repositories and environments that are no longer referenced

238

by any active configurations.

239

240

Parameters:

241

- store: Store instance to garbage collect

242

243

Returns:

244

- int: Number of items removed

245

"""

246

```

247

248

## Environment Management

249

250

### Environment Installation

251

252

```python { .api }

253

def ensure_environment(

254

hook: Hook,

255

store: Store,

256

language_version: str

257

) -> None:

258

"""

259

Ensure hook environment is installed and ready.

260

261

Parameters:

262

- hook: Hook requiring environment

263

- store: Store instance for management

264

- language_version: Specific language version to use

265

"""

266

```

267

268

### Environment Health Checks

269

270

```python { .api }

271

def check_environment_health(

272

prefix: Prefix,

273

language: str,

274

version: str

275

) -> str | None:

276

"""

277

Check if environment is healthy and functional.

278

279

Parameters:

280

- prefix: Environment installation prefix

281

- language: Programming language

282

- version: Language version

283

284

Returns:

285

- str | None: Error message if unhealthy, None if healthy

286

"""

287

```

288

289

## Usage Examples

290

291

### Basic Store Operations

292

293

```python

294

from pre_commit.store import Store

295

from pre_commit.clientlib import load_config

296

from pre_commit.repository import all_hooks, install_hook_envs

297

298

# Initialize store (uses default directory)

299

store = Store()

300

301

# Or initialize with custom directory

302

custom_store = Store('/path/to/custom/store')

303

304

# Load configuration and get all hooks

305

config = load_config('.pre-commit-config.yaml')

306

hooks = all_hooks(config, store)

307

308

print(f"Found {len(hooks)} hooks from {len(config['repos'])} repositories")

309

310

# Install environments for all hooks

311

install_hook_envs(hooks, store)

312

print("All hook environments installed")

313

```

314

315

### Repository Cloning and Management

316

317

```python

318

from pre_commit.store import Store

319

320

store = Store()

321

322

# Clone specific repository

323

repo_path = store.clone(

324

repo='https://github.com/psf/black',

325

ref='22.3.0',

326

deps=['black[jupyter]']

327

)

328

print(f"Repository cloned to: {repo_path}")

329

330

# Create local environment

331

local_path = store.make_local(deps=['flake8', 'mypy'])

332

print(f"Local environment created at: {local_path}")

333

334

# Mark configuration as used (for garbage collection)

335

store.mark_config_used('.pre-commit-config.yaml')

336

```

337

338

### Store Maintenance

339

340

```python

341

from pre_commit.store import Store

342

343

store = Store()

344

345

# Get all repositories managed by store

346

repos = store.select_all_repos()

347

print(f"Store manages {len(repos)} repositories:")

348

for repo_name, ref, path in repos:

349

print(f" {repo_name}@{ref} -> {path}")

350

351

# Get all tracked configurations

352

configs = store.select_all_configs()

353

print(f"Tracking {len(configs)} configurations:")

354

for config_path in configs:

355

print(f" {config_path}")

356

357

# Clean up unused configurations

358

# (In practice, you'd determine which are actually unused)

359

# store.delete_configs(['/path/to/unused/config.yaml'])

360

```

361

362

### Cache Statistics and Cleanup

363

364

```python

365

from pre_commit.store import Store, get_cache_stats, garbage_collect_repos

366

367

store = Store()

368

369

# Get cache statistics

370

stats = get_cache_stats(store)

371

print(f"Cache statistics:")

372

print(f" Total repositories: {stats.get('repo_count', 0)}")

373

print(f" Total size: {stats.get('total_size', 0)} bytes")

374

print(f" Environments: {stats.get('env_count', 0)}")

375

376

# Perform garbage collection

377

removed_count = garbage_collect_repos(store)

378

print(f"Garbage collection removed {removed_count} unused items")

379

```

380

381

### Working with Store Directory

382

383

```python

384

from pre_commit.store import Store

385

386

# Get default store directory

387

default_dir = Store.get_default_directory()

388

print(f"Default store directory: {default_dir}")

389

390

# Initialize store with explicit directory

391

store = Store(directory='/tmp/pre-commit-store')

392

393

# Verify store is using correct directory

394

# (Store doesn't expose directory directly, but you can check filesystem)

395

import os

396

if os.path.exists('/tmp/pre-commit-store'):

397

print("Custom store directory created successfully")

398

```

399

400

### Advanced Repository Operations

401

402

```python

403

from pre_commit.store import Store

404

405

store = Store()

406

407

# Work with multiple repositories

408

repositories = [

409

('https://github.com/psf/black', '22.3.0'),

410

('https://github.com/pycqa/flake8', '4.0.1'),

411

('https://github.com/pre-commit/mirrors-mypy', 'v0.950')

412

]

413

414

repo_paths = []

415

for repo_url, ref in repositories:

416

path = store.clone(repo=repo_url, ref=ref)

417

repo_paths.append(path)

418

print(f"Cloned {repo_url}@{ref} to {path}")

419

420

print(f"Successfully cloned {len(repo_paths)} repositories")

421

422

# Clean up specific repository if needed

423

# store.delete_repo('repo-name', 'ref', '/path/to/repo')

424

```