or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command.mdconfiguration.mddatabase.mddiff.mdexceptions.mdindex-staging.mdindex.mdobjects.mdreferences.mdremote.mdrepository.md

objects.mddocs/

0

# Git Objects

1

2

Access to Git's core object model including commits, trees, blobs, and tags. Provides complete metadata access, object traversal capabilities, and serialization support for repository analysis and manipulation.

3

4

## Capabilities

5

6

### Base Object Interface

7

8

Foundation class for all Git objects providing common functionality for object identification, serialization, and repository access.

9

10

```python { .api }

11

class Object:

12

def __init__(self, repo: "Repo", binsha: bytes):

13

"""

14

Initialize a git object.

15

16

Args:

17

repo: Repository containing the object

18

binsha: Binary SHA-1 hash of the object

19

"""

20

21

@property

22

def hexsha(self) -> str:

23

"""Hexadecimal SHA-1 hash string."""

24

25

@property

26

def binsha(self) -> bytes:

27

"""Binary SHA-1 hash."""

28

29

@property

30

def type(self) -> str:

31

"""Object type string ('commit', 'tree', 'blob', 'tag')."""

32

33

@property

34

def size(self) -> int:

35

"""Size of object data in bytes."""

36

37

@property

38

def repo(self) -> "Repo":

39

"""Repository containing this object."""

40

41

def __eq__(self, other: Any) -> bool:

42

"""Compare objects by SHA-1 hash."""

43

44

def __hash__(self) -> int:

45

"""Hash based on SHA-1."""

46

47

class IndexObject(Object):

48

"""Base for objects that can be part of an index (trees, blobs, submodules)."""

49

50

def __init__(self, repo: "Repo", binsha: bytes, mode: int = None, path: str = None):

51

"""

52

Initialize index object.

53

54

Args:

55

repo: Repository containing object

56

binsha: Binary SHA-1 hash

57

mode: Unix file mode

58

path: Path within repository

59

"""

60

61

@property

62

def mode(self) -> int:

63

"""Unix file mode."""

64

65

@property

66

def path(self) -> str:

67

"""Path within repository."""

68

69

@property

70

def name(self) -> str:

71

"""Object name (basename of path)."""

72

```

73

74

### Commit Objects

75

76

Represent Git commits with full metadata including author, committer, message, and parent relationships.

77

78

```python { .api }

79

class Commit(Object):

80

def __init__(

81

self,

82

repo: "Repo",

83

binsha: bytes,

84

tree: "Tree" = None,

85

author: "Actor" = None,

86

authored_date: int = None,

87

author_tz_offset: int = None,

88

committer: "Actor" = None,

89

committed_date: int = None,

90

committer_tz_offset: int = None,

91

message: str = None,

92

parents: list["Commit"] = None,

93

encoding: str = None

94

):

95

"""

96

Initialize commit object.

97

98

Args:

99

repo: Repository containing commit

100

binsha: Binary SHA-1 hash

101

tree: Tree object for this commit

102

author: Author information

103

authored_date: Author timestamp

104

author_tz_offset: Author timezone offset

105

committer: Committer information

106

committed_date: Commit timestamp

107

committer_tz_offset: Committer timezone offset

108

message: Commit message

109

parents: Parent commits

110

encoding: Text encoding

111

"""

112

113

@property

114

def message(self) -> str:

115

"""Commit message."""

116

117

@property

118

def author(self) -> "Actor":

119

"""Author information."""

120

121

@property

122

def committer(self) -> "Actor":

123

"""Committer information."""

124

125

@property

126

def authored_date(self) -> int:

127

"""Author timestamp as seconds since epoch."""

128

129

@property

130

def committed_date(self) -> int:

131

"""Commit timestamp as seconds since epoch."""

132

133

@property

134

def authored_datetime(self) -> datetime:

135

"""Author timestamp as datetime object."""

136

137

@property

138

def committed_datetime(self) -> datetime:

139

"""Commit timestamp as datetime object."""

140

141

@property

142

def author_tz_offset(self) -> int:

143

"""Author timezone offset in seconds."""

144

145

@property

146

def committer_tz_offset(self) -> int:

147

"""Committer timezone offset in seconds."""

148

149

@property

150

def tree(self) -> "Tree":

151

"""Tree object for this commit."""

152

153

@property

154

def parents(self) -> tuple["Commit", ...]:

155

"""Parent commits."""

156

157

@property

158

def stats(self) -> "Stats":

159

"""Commit statistics (files changed, insertions, deletions)."""

160

161

def iter_parents(self, paths: list[str] = None, **kwargs) -> Iterator["Commit"]:

162

"""

163

Iterate parent commits.

164

165

Args:

166

paths: Limit to commits affecting these paths

167

**kwargs: Additional git log options

168

169

Returns:

170

Iterator of parent commits

171

"""

172

173

def iter_items(

174

self,

175

repo: "Repo",

176

*args,

177

**kwargs

178

) -> Iterator["Commit"]:

179

"""

180

Iterate commits.

181

182

Args:

183

repo: Repository to search

184

*args: Positional arguments

185

**kwargs: Keyword arguments

186

187

Returns:

188

Iterator of commits

189

"""

190

```

191

192

### Tree Objects

193

194

Represent Git tree objects (directories) with support for traversal and content access.

195

196

```python { .api }

197

class Tree(IndexObject):

198

def __init__(self, repo: "Repo", binsha: bytes, mode: int = None, path: str = None):

199

"""

200

Initialize tree object.

201

202

Args:

203

repo: Repository containing tree

204

binsha: Binary SHA-1 hash

205

mode: Unix file mode

206

path: Path within repository

207

"""

208

209

def __getitem__(self, item: Union[int, str]) -> IndexObject:

210

"""Get tree item by index or name."""

211

212

def __contains__(self, item: str) -> bool:

213

"""Check if tree contains item."""

214

215

def __len__(self) -> int:

216

"""Number of items in tree."""

217

218

def __iter__(self) -> Iterator[IndexObject]:

219

"""Iterate over tree items."""

220

221

@property

222

def trees(self) -> list["Tree"]:

223

"""Subdirectories in this tree."""

224

225

@property

226

def blobs(self) -> list["Blob"]:

227

"""Files in this tree."""

228

229

def traverse(

230

self,

231

predicate: Callable[[IndexObject, int], bool] = None,

232

prune: Callable[[IndexObject, int], bool] = None,

233

depth: int = -1,

234

branch_first: bool = True,

235

visit_once: bool = False,

236

ignore_self: int = 1

237

) -> Iterator[IndexObject]:

238

"""

239

Traverse tree recursively.

240

241

Args:

242

predicate: Filter function for items

243

prune: Function to skip subtrees

244

depth: Maximum depth (-1 for unlimited)

245

branch_first: Traverse breadth-first vs depth-first

246

visit_once: Visit each object only once

247

ignore_self: Skip self in traversal

248

249

Returns:

250

Iterator of tree objects

251

"""

252

253

class TreeModifier:

254

"""Helper for modifying tree objects."""

255

256

def __init__(self, cache: list = None):

257

"""

258

Initialize tree modifier.

259

260

Args:

261

cache: Initial cache entries

262

"""

263

264

def add(self, sha: Union[str, bytes], mode: int, name: str, force: bool = False) -> "TreeModifier":

265

"""

266

Add entry to tree.

267

268

Args:

269

sha: Object SHA-1 hash

270

mode: Unix file mode

271

name: Entry name

272

force: Overwrite existing entries

273

274

Returns:

275

Self for chaining

276

"""

277

278

def write(self, repo: "Repo") -> "Tree":

279

"""

280

Write modified tree to repository.

281

282

Args:

283

repo: Repository to write to

284

285

Returns:

286

New tree object

287

"""

288

```

289

290

### Blob Objects

291

292

Represent Git blob objects (files) with content access and metadata.

293

294

```python { .api }

295

class Blob(IndexObject):

296

def __init__(self, repo: "Repo", binsha: bytes, mode: int = None, path: str = None):

297

"""

298

Initialize blob object.

299

300

Args:

301

repo: Repository containing blob

302

binsha: Binary SHA-1 hash

303

mode: Unix file mode

304

path: Path within repository

305

"""

306

307

@property

308

def data_stream(self) -> "OStream":

309

"""Stream for reading blob data."""

310

311

@property

312

def mime_type(self) -> str:

313

"""MIME type of blob content."""

314

315

@property

316

def encoding(self) -> Optional[str]:

317

"""Text encoding of blob (if text)."""

318

319

def __str__(self) -> str:

320

"""Blob content as string."""

321

322

@property

323

def executable(self) -> bool:

324

"""True if blob has executable mode."""

325

```

326

327

### Tag Objects

328

329

Represent Git annotated tag objects with metadata and target object references.

330

331

```python { .api }

332

class TagObject(Object):

333

def __init__(

334

self,

335

repo: "Repo",

336

binsha: bytes,

337

object: Object = None,

338

tag: str = None,

339

tagger: "Actor" = None,

340

tagged_date: int = None,

341

tagger_tz_offset: int = None,

342

message: str = None

343

):

344

"""

345

Initialize tag object.

346

347

Args:

348

repo: Repository containing tag

349

binsha: Binary SHA-1 hash

350

object: Tagged object

351

tag: Tag name

352

tagger: Tagger information

353

tagged_date: Tag timestamp

354

tagger_tz_offset: Tagger timezone offset

355

message: Tag message

356

"""

357

358

@property

359

def object(self) -> Object:

360

"""Tagged object."""

361

362

@property

363

def tag(self) -> str:

364

"""Tag name."""

365

366

@property

367

def tagger(self) -> "Actor":

368

"""Tagger information."""

369

370

@property

371

def tagged_date(self) -> int:

372

"""Tag timestamp as seconds since epoch."""

373

374

@property

375

def tagged_datetime(self) -> datetime:

376

"""Tag timestamp as datetime object."""

377

378

@property

379

def tagger_tz_offset(self) -> int:

380

"""Tagger timezone offset in seconds."""

381

382

@property

383

def message(self) -> str:

384

"""Tag message."""

385

```

386

387

### Submodule Objects

388

389

Manage Git submodules with update and traversal capabilities.

390

391

```python { .api }

392

class Submodule(IndexObject):

393

def __init__(self, repo: "Repo", binsha: bytes, mode: int = None, path: str = None, name: str = None, parent_commit: "Commit" = None, url: str = None, branch_path: str = None):

394

"""

395

Initialize submodule.

396

397

Args:

398

repo: Parent repository

399

binsha: Submodule commit SHA

400

mode: File mode

401

path: Submodule path

402

name: Submodule name

403

parent_commit: Parent commit

404

url: Submodule URL

405

branch_path: Branch path

406

"""

407

408

def update(

409

self,

410

recursive: bool = False,

411

init: bool = True,

412

to_latest_revision: bool = False,

413

progress: "UpdateProgress" = None,

414

dry_run: bool = False,

415

force: bool = False,

416

keep_going: bool = False

417

) -> "Submodule":

418

"""

419

Update submodule.

420

421

Args:

422

recursive: Update recursively

423

init: Initialize if needed

424

to_latest_revision: Update to latest

425

progress: Progress reporter

426

dry_run: Don't make changes

427

force: Force update

428

keep_going: Continue on errors

429

430

Returns:

431

Updated submodule

432

"""

433

434

@property

435

def module(self) -> "Repo":

436

"""Submodule repository."""

437

438

@property

439

def url(self) -> str:

440

"""Submodule URL."""

441

442

class UpdateProgress:

443

"""Progress reporter for submodule updates."""

444

445

def update(

446

self,

447

op_code: int,

448

cur_count: Union[str, float],

449

max_count: Union[str, float] = None,

450

message: str = ""

451

) -> None:

452

"""

453

Update progress.

454

455

Args:

456

op_code: Operation code

457

cur_count: Current progress

458

max_count: Maximum progress

459

message: Progress message

460

"""

461

462

class RootModule(Submodule):

463

"""Virtual root of all submodules in repository for easier traversal."""

464

465

def __init__(self, repo: "Repo"): ...

466

467

def update(

468

self,

469

previous_commit: "Commit" = None,

470

recursive: bool = True,

471

force_remove: bool = False,

472

init: bool = True,

473

to_latest_revision: bool = False,

474

progress: "RootUpdateProgress" = None,

475

dry_run: bool = False,

476

force_reset: bool = False,

477

keep_going: bool = False

478

) -> "RootModule": ...

479

480

class RootUpdateProgress(UpdateProgress):

481

"""Extended progress reporter for root module operations with additional opcodes."""

482

483

# Additional operation codes beyond UpdateProgress

484

REMOVE: int

485

PATHCHANGE: int

486

BRANCHCHANGE: int

487

URLCHANGE: int

488

```

489

490

## Usage Examples

491

492

### Working with Commits

493

494

```python

495

from git import Repo

496

497

repo = Repo('/path/to/repo')

498

499

# Get latest commit

500

commit = repo.head.commit

501

502

# Access commit metadata

503

print(f"SHA: {commit.hexsha}")

504

print(f"Author: {commit.author.name} <{commit.author.email}>")

505

print(f"Date: {commit.authored_datetime}")

506

print(f"Message: {commit.message}")

507

508

# Access commit tree and parents

509

tree = commit.tree

510

parents = commit.parents

511

512

# Get commit statistics

513

stats = commit.stats

514

print(f"Files changed: {stats.total['files']}")

515

print(f"Insertions: {stats.total['insertions']}")

516

print(f"Deletions: {stats.total['deletions']}")

517

```

518

519

### Traversing Trees

520

521

```python

522

# Get tree from commit

523

tree = commit.tree

524

525

# Access tree items

526

for item in tree:

527

if item.type == 'tree':

528

print(f"Directory: {item.path}")

529

elif item.type == 'blob':

530

print(f"File: {item.path} ({item.size} bytes)")

531

532

# Recursive traversal

533

for item in tree.traverse():

534

print(f"{item.type}: {item.path}")

535

536

# Filter traversal

537

python_files = [item for item in tree.traverse()

538

if item.type == 'blob' and item.path.endswith('.py')]

539

```

540

541

### Working with Blobs

542

543

```python

544

# Get blob object

545

blob = tree['README.md']

546

547

# Access blob content

548

content = blob.data_stream.read().decode('utf-8')

549

print(content)

550

551

# Check if executable

552

if blob.executable:

553

print("File is executable")

554

555

# Get MIME type

556

print(f"MIME type: {blob.mime_type}")

557

```

558

559

### Working with Tags

560

561

```python

562

# Access annotated tag

563

tag = repo.tags['v1.0.0']

564

if hasattr(tag, 'tag'): # Annotated tag

565

tag_obj = tag.tag

566

print(f"Tag: {tag_obj.tag}")

567

print(f"Tagger: {tag_obj.tagger}")

568

print(f"Date: {tag_obj.tagged_datetime}")

569

print(f"Message: {tag_obj.message}")

570

print(f"Tagged object: {tag_obj.object.type}")

571

```

572

573

### Creating Objects

574

575

```python

576

from git import Actor

577

import time

578

579

# Create new commit

580

author = Actor("John Doe", "john@example.com")

581

committer = author

582

583

# Create tree modifier

584

from git.objects import TreeModifier

585

modifier = TreeModifier()

586

587

# Add files to tree

588

with open('new_file.txt', 'rb') as f:

589

blob_data = f.read()

590

591

# Create blob and add to tree

592

blob = repo.odb.store(IStream('blob', len(blob_data), BytesIO(blob_data)))

593

modifier.add(blob.binsha, 0o100644, 'new_file.txt')

594

595

# Write new tree

596

new_tree = modifier.write(repo)

597

598

# Create new commit

599

new_commit = Commit.create_from_tree(

600

repo,

601

new_tree,

602

message="Added new file",

603

parent_commits=[repo.head.commit],

604

author=author,

605

committer=committer

606

)

607

```