or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdblame.mdcheckout.mdconfig.mddiff-status.mdindex-operations.mdindex.mdobjects.mdreferences.mdremotes.mdrepository.mdrevwalk.mdsignatures.md

diff-status.mddocs/

0

# Diff and Status

1

2

File difference computation and working directory status tracking. These operations help understand changes between different states of the repository, including modifications, additions, and deletions of files.

3

4

## Capabilities

5

6

### Diff Operations

7

8

Compare different states of the repository to identify changes.

9

10

```javascript { .api }

11

/**

12

* Diff tree to tree

13

* @param {Repository} repo - Repository instance

14

* @param {Tree} oldTree - Old tree to compare from

15

* @param {Tree} newTree - New tree to compare to

16

* @param {DiffOptions} opts - Diff options

17

* @returns {Promise<Diff>} Diff object

18

*/

19

Diff.treeToTree(repo, oldTree, newTree, opts): Promise<Diff>;

20

21

/**

22

* Diff tree to index

23

* @param {Repository} repo - Repository instance

24

* @param {Tree} oldTree - Tree to compare from

25

* @param {Index} index - Index to compare to

26

* @param {DiffOptions} opts - Diff options

27

* @returns {Promise<Diff>} Diff object

28

*/

29

Diff.treeToIndex(repo, oldTree, index, opts): Promise<Diff>;

30

31

/**

32

* Diff index to working directory

33

* @param {Repository} repo - Repository instance

34

* @param {Index} index - Index to compare from

35

* @param {DiffOptions} opts - Diff options

36

* @returns {Promise<Diff>} Diff object

37

*/

38

Diff.indexToWorkdir(repo, index, opts): Promise<Diff>;

39

40

/**

41

* Diff tree to working directory

42

* @param {Repository} repo - Repository instance

43

* @param {Tree} oldTree - Tree to compare from

44

* @param {DiffOptions} opts - Diff options

45

* @returns {Promise<Diff>} Diff object

46

*/

47

Diff.treeToWorkdir(repo, oldTree, opts): Promise<Diff>;

48

49

/**

50

* Diff tree to working directory with index

51

* @param {Repository} repo - Repository instance

52

* @param {Tree} oldTree - Tree to compare from

53

* @param {DiffOptions} opts - Diff options

54

* @returns {Promise<Diff>} Diff object

55

*/

56

Diff.treeToWorkdirWithIndex(repo, oldTree, opts): Promise<Diff>;

57

58

/**

59

* Diff two blobs

60

* @param {Blob} oldBlob - Old blob to compare from

61

* @param {string} oldAsPath - Path name for old blob

62

* @param {Blob} newBlob - New blob to compare to

63

* @param {string} newAsPath - Path name for new blob

64

* @param {DiffOptions} opts - Diff options

65

* @param {Function} fileCallback - File callback

66

* @param {Function} binaryCallback - Binary callback

67

* @param {Function} hunkCallback - Hunk callback

68

* @param {Function} lineCallback - Line callback

69

* @returns {Promise<void>}

70

*/

71

Diff.blobs(oldBlob, oldAsPath, newBlob, newAsPath, opts, fileCallback, binaryCallback, hunkCallback, lineCallback): Promise<void>;

72

73

/**

74

* Diff blob to buffer

75

* @param {Blob} oldBlob - Old blob to compare from

76

* @param {string} oldAsPath - Path name for old blob

77

* @param {Buffer} buffer - Buffer to compare to

78

* @param {string} bufferAsPath - Path name for buffer

79

* @param {DiffOptions} opts - Diff options

80

* @param {Function} fileCallback - File callback

81

* @param {Function} binaryCallback - Binary callback

82

* @param {Function} hunkCallback - Hunk callback

83

* @param {Function} lineCallback - Line callback

84

* @returns {Promise<void>}

85

*/

86

Diff.blobToBuffer(oldBlob, oldAsPath, buffer, bufferAsPath, opts, fileCallback, binaryCallback, hunkCallback, lineCallback): Promise<void>;

87

```

88

89

**Usage Examples:**

90

91

```javascript

92

const NodeGit = require('nodegit');

93

94

const repo = await NodeGit.Repository.open('./my-repo');

95

96

// Compare two commits

97

const commit1 = await repo.getHeadCommit();

98

const commit2 = await commit1.parent(0);

99

100

const tree1 = await commit1.getTree();

101

const tree2 = await commit2.getTree();

102

103

const diff = await NodeGit.Diff.treeToTree(repo, tree2, tree1, null);

104

console.log('Number of changes:', diff.numDeltas());

105

106

// Compare index to working directory

107

const index = await repo.index();

108

const workdirDiff = await NodeGit.Diff.indexToWorkdir(repo, index, null);

109

110

console.log('Unstaged changes:', workdirDiff.numDeltas());

111

112

// Compare tree to working directory

113

const headTree = await (await repo.getHeadCommit()).getTree();

114

const fullDiff = await NodeGit.Diff.treeToWorkdir(repo, headTree, null);

115

116

console.log('All changes since last commit:', fullDiff.numDeltas());

117

```

118

119

### Diff Instance Methods

120

121

Methods available on Diff objects to examine and process changes.

122

123

```javascript { .api }

124

/**

125

* Get number of deltas (changed files)

126

* @returns {number} Number of changed files

127

*/

128

diff.numDeltas(): number;

129

130

/**

131

* Get delta by index

132

* @param {number} idx - Delta index

133

* @returns {DiffDelta} Delta object

134

*/

135

diff.getDelta(idx): DiffDelta;

136

137

/**

138

* Get patches for diff

139

* @returns {Promise<ConvenientPatch[]>} Array of patch objects

140

*/

141

diff.patches(): Promise<ConvenientPatch[]>;

142

143

/**

144

* Convert diff to string

145

* @returns {string} Diff as string

146

*/

147

diff.toString(): string;

148

149

/**

150

* Convert diff to buffer

151

* @param {number} format - Output format

152

* @returns {Promise<Buffer>} Diff as buffer

153

*/

154

diff.toBuf(format): Promise<Buffer>;

155

156

/**

157

* Iterate through diff

158

* @param {Function} fileCallback - Called for each file

159

* @param {Function} binaryCallback - Called for binary files

160

* @param {Function} hunkCallback - Called for each hunk

161

* @param {Function} lineCallback - Called for each line

162

* @returns {Promise<void>}

163

*/

164

diff.foreach(fileCallback, binaryCallback, hunkCallback, lineCallback): Promise<void>;

165

166

/**

167

* Find similar files (renames/copies)

168

* @param {DiffFindOptions} opts - Find options

169

* @returns {Promise<void>}

170

*/

171

diff.findSimilar(opts): Promise<void>;

172

173

/**

174

* Merge diffs

175

* @param {Diff} from - Diff to merge from

176

* @returns {Promise<void>}

177

*/

178

diff.merge(from): Promise<void>;

179

180

/**

181

* Get best similarity score

182

* @returns {number} Best similarity (0-100)

183

*/

184

diff.getBestSimilarity(): number;

185

```

186

187

**Usage Examples:**

188

189

```javascript

190

// Examine diff details

191

const diff = await NodeGit.Diff.treeToTree(repo, tree1, tree2, null);

192

193

// Look for renames

194

await diff.findSimilar({

195

flags: NodeGit.Diff.FIND.RENAMES

196

});

197

198

// Get patches with details

199

const patches = await diff.patches();

200

patches.forEach(async function(patch) {

201

const oldFile = patch.oldFile();

202

const newFile = patch.newFile();

203

204

console.log('File:', newFile.path());

205

console.log('Status:', patch.status());

206

console.log('Lines added:', patch.lineStats().total_additions);

207

console.log('Lines deleted:', patch.lineStats().total_deletions);

208

209

// Get hunks for this patch

210

const hunks = await patch.hunks();

211

hunks.forEach(async function(hunk) {

212

console.log('Hunk header:', hunk.header());

213

214

// Get lines for this hunk

215

const lines = await hunk.lines();

216

lines.forEach(function(line) {

217

const origin = String.fromCharCode(line.origin());

218

console.log(origin + line.content());

219

});

220

});

221

});

222

223

// Iterate through diff manually

224

await diff.foreach(

225

function(delta, progress) {

226

console.log('File changed:', delta.newFile().path());

227

},

228

function(delta, progress) {

229

console.log('Binary file:', delta.newFile().path());

230

},

231

function(delta, hunk) {

232

console.log('Hunk:', hunk.header().trim());

233

},

234

function(delta, hunk, line) {

235

const origin = String.fromCharCode(line.origin());

236

console.log(origin + line.content().trim());

237

}

238

);

239

```

240

241

### Status Operations

242

243

Get working directory and index status information.

244

245

```javascript { .api }

246

/**

247

* Get file status

248

* @param {Repository} repo - Repository instance

249

* @param {string} path - File path

250

* @returns {Promise<number>} Status flags

251

*/

252

Status.file(repo, path): Promise<number>;

253

254

/**

255

* Iterate through all status entries

256

* @param {Repository} repo - Repository instance

257

* @param {Function} callback - Status callback function

258

* @returns {Promise<void>}

259

*/

260

Status.foreach(repo, callback): Promise<void>;

261

262

/**

263

* Check if path should be ignored

264

* @param {Repository} repo - Repository instance

265

* @param {string} path - File path

266

* @returns {Promise<boolean>} True if should be ignored

267

*/

268

Status.shouldIgnore(repo, path): Promise<boolean>;

269

```

270

271

### Repository Status Methods

272

273

Convenience methods on Repository for status operations.

274

275

```javascript { .api }

276

/**

277

* Get repository status

278

* @returns {Promise<StatusFile[]>} Array of status files

279

*/

280

repository.getStatus(): Promise<StatusFile[]>;

281

282

/**

283

* Get status with options

284

* @param {StatusOptions} opts - Status options

285

* @returns {Promise<StatusFile[]>} Array of status files

286

*/

287

repository.getStatusExt(opts): Promise<StatusFile[]>;

288

289

/**

290

* Check if path is ignored

291

* @param {string} path - File path to check

292

* @returns {Promise<boolean>} True if ignored

293

*/

294

repository.isIgnored(path): Promise<boolean>;

295

```

296

297

**Usage Examples:**

298

299

```javascript

300

// Get repository status

301

const statusFiles = await repo.getStatus();

302

303

statusFiles.forEach(function(file) {

304

const path = file.path();

305

const flags = file.statusFlags();

306

307

console.log('File:', path);

308

309

if (flags & NodeGit.Status.STATUS.INDEX_NEW) {

310

console.log(' New in index');

311

}

312

if (flags & NodeGit.Status.STATUS.INDEX_MODIFIED) {

313

console.log(' Modified in index');

314

}

315

if (flags & NodeGit.Status.STATUS.INDEX_DELETED) {

316

console.log(' Deleted in index');

317

}

318

if (flags & NodeGit.Status.STATUS.WT_NEW) {

319

console.log(' New in working tree');

320

}

321

if (flags & NodeGit.Status.STATUS.WT_MODIFIED) {

322

console.log(' Modified in working tree');

323

}

324

if (flags & NodeGit.Status.STATUS.WT_DELETED) {

325

console.log(' Deleted in working tree');

326

}

327

if (flags & NodeGit.Status.STATUS.IGNORED) {

328

console.log(' Ignored');

329

}

330

});

331

332

// Check specific file status

333

const fileStatus = await NodeGit.Status.file(repo, 'README.md');

334

if (fileStatus & NodeGit.Status.STATUS.WT_MODIFIED) {

335

console.log('README.md has been modified');

336

}

337

338

// Check if file is ignored

339

const isIgnored = await repo.isIgnored('node_modules/package.json');

340

if (isIgnored) {

341

console.log('File is ignored by .gitignore');

342

}

343

344

// Iterate through status

345

await NodeGit.Status.foreach(repo, function(path, flags) {

346

console.log('Status for', path + ':', flags);

347

});

348

```

349

350

### Status with Options

351

352

Get status with filtering and configuration options.

353

354

```javascript { .api }

355

/**

356

* Get extended status with options

357

* @param {StatusOptions} opts - Status options

358

* @returns {Promise<StatusFile[]>} Filtered status files

359

*/

360

repository.getStatusExt(opts): Promise<StatusFile[]>;

361

```

362

363

**Usage Examples:**

364

365

```javascript

366

// Get status with options

367

const statusOptions = {

368

flags:

369

NodeGit.Status.OPT.INCLUDE_UNTRACKED |

370

NodeGit.Status.OPT.RECURSE_UNTRACKED_DIRS,

371

pathspec: ['src/', 'docs/']

372

};

373

374

const filteredStatus = await repo.getStatusExt(statusOptions);

375

376

filteredStatus.forEach(function(file) {

377

console.log('Filtered status:', file.path(), file.statusFlags());

378

});

379

380

// Include ignored files

381

const allStatus = await repo.getStatusExt({

382

flags:

383

NodeGit.Status.OPT.INCLUDE_IGNORED |

384

NodeGit.Status.OPT.INCLUDE_UNTRACKED

385

});

386

387

console.log('All files including ignored:', allStatus.length);

388

```

389

390

### StatusFile Methods

391

392

Methods available on StatusFile objects.

393

394

```javascript { .api }

395

/**

396

* Get file path

397

* @returns {string} File path

398

*/

399

statusFile.path(): string;

400

401

/**

402

* Get status flags

403

* @returns {number} Status flags bitmask

404

*/

405

statusFile.statusFlags(): number;

406

407

/**

408

* Get diff from HEAD to index

409

* @returns {DiffDelta} HEAD to index diff

410

*/

411

statusFile.headToIndex(): DiffDelta;

412

413

/**

414

* Get diff from index to working directory

415

* @returns {DiffDelta} Index to working directory diff

416

*/

417

statusFile.indexToWorkdir(): DiffDelta;

418

```

419

420

**Usage Examples:**

421

422

```javascript

423

const statusFiles = await repo.getStatus();

424

425

statusFiles.forEach(function(file) {

426

console.log('Path:', file.path());

427

428

const headToIndex = file.headToIndex();

429

if (headToIndex) {

430

console.log(' Staged change:', headToIndex.status());

431

}

432

433

const indexToWorkdir = file.indexToWorkdir();

434

if (indexToWorkdir) {

435

console.log(' Unstaged change:', indexToWorkdir.status());

436

}

437

});

438

```

439

440

## Types

441

442

```javascript { .api }

443

interface DiffOptions {

444

flags: number;

445

ignoreSubmodules: number;

446

pathspec: string[];

447

notifyCallback: Function;

448

progressCallback: Function;

449

contextLines: number;

450

interhunkLines: number;

451

idAbbrev: number;

452

maxSize: number;

453

oldPrefix: string;

454

newPrefix: string;

455

}

456

457

interface DiffFindOptions {

458

flags: number;

459

renameThreshold: number;

460

renameFromRewriteThreshold: number;

461

copyThreshold: number;

462

breakRewriteThreshold: number;

463

renameLimit: number;

464

metric: Function;

465

}

466

467

interface StatusOptions {

468

flags: number;

469

pathspec: string[];

470

baseline: Tree;

471

}

472

473

interface DiffDelta {

474

status(): number;

475

flags(): number;

476

similarity(): number;

477

nfiles(): number;

478

oldFile(): DiffFile;

479

newFile(): DiffFile;

480

}

481

482

interface DiffFile {

483

path(): string;

484

size(): number;

485

flags(): number;

486

mode(): number;

487

id(): Oid;

488

}

489

490

interface ConvenientPatch {

491

oldFile(): DiffFile;

492

newFile(): DiffFile;

493

status(): number;

494

lineStats(): { total_context: number, total_additions: number, total_deletions: number };

495

hunks(): Promise<ConvenientHunk[]>;

496

}

497

498

interface ConvenientHunk {

499

size(): number;

500

header(): string;

501

lines(): Promise<DiffLine[]>;

502

}

503

504

interface DiffLine {

505

origin(): number;

506

oldLineno(): number;

507

newLineno(): number;

508

numLines(): number;

509

content(): string;

510

contentOffset(): number;

511

}

512

513

// Status flags

514

Status.STATUS = {

515

CURRENT: 0,

516

INDEX_NEW: 1,

517

INDEX_MODIFIED: 2,

518

INDEX_DELETED: 4,

519

INDEX_RENAMED: 8,

520

INDEX_TYPECHANGE: 16,

521

WT_NEW: 128,

522

WT_MODIFIED: 256,

523

WT_DELETED: 512,

524

WT_TYPECHANGE: 1024,

525

WT_RENAMED: 2048,

526

IGNORED: 16384,

527

CONFLICTED: 32768

528

};

529

530

// Status options

531

Status.OPT = {

532

INCLUDE_UNTRACKED: 1,

533

INCLUDE_IGNORED: 2,

534

INCLUDE_UNMODIFIED: 4,

535

EXCLUDE_SUBMODULES: 8,

536

RECURSE_UNTRACKED_DIRS: 16,

537

DISABLE_PATHSPEC_MATCH: 32,

538

RECURSE_IGNORED_DIRS: 64,

539

RENAMES_HEAD_TO_INDEX: 128,

540

RENAMES_INDEX_TO_WORKDIR: 256,

541

SORT_CASE_SENSITIVELY: 512,

542

SORT_CASE_INSENSITIVELY: 1024,

543

RENAMES_FROM_REWRITES: 2048,

544

NO_REFRESH: 4096,

545

UPDATE_INDEX: 8192

546

};

547

548

// Diff find flags

549

Diff.FIND = {

550

BY_CONFIG: 0,

551

RENAMES: 1,

552

RENAMES_AND_COPIES: 2,

553

COPIES: 4,

554

COPIES_HARDER: 8,

555

RENAMES_FROM_REWRITES: 16,

556

BREAK_REWRITES: 32,

557

AND_BREAK_REWRITES: 48,

558

FOR_UNTRACKED: 64,

559

ALL: 255,

560

IGNORE_LEADING_WHITESPACE: 0,

561

IGNORE_WHITESPACE: 4194304,

562

DONT_IGNORE_WHITESPACE: 8388608,

563

EXACT_MATCH_ONLY: 16777216,

564

BREAK_REWRITES_FOR_RENAMES_ONLY: 33554432,

565

REMOVE_UNMODIFIED: 67108864

566

};

567

568

// Delta status

569

Diff.DELTA = {

570

UNMODIFIED: 0,

571

ADDED: 1,

572

DELETED: 2,

573

MODIFIED: 3,

574

RENAMED: 4,

575

COPIED: 5,

576

IGNORED: 6,

577

UNTRACKED: 7,

578

TYPECHANGE: 8,

579

UNREADABLE: 9,

580

CONFLICTED: 10

581

};

582

```