Git test failing with Typescript on stage 4

I’m stuck on stage 4 of GIT Challenge, the tests keep saying:

Did you write the tree object? Did not find a file in .git/objects/<first 2 chars of sha>/<remaining chars of sha>

I’ve tried to debug printing if the directories exists and i get true.

Here’s a snippet of my code:

import {
  exists,
  mkdir,
  readdir,
  readFile,
  stat,
  writeFile,
} from 'node:fs/promises';
import { join } from 'node:path';
import { Tree } from '../types';
import { createHash } from 'node:crypto';
import { deflateSync } from 'node:zlib';

let baseDir: string | undefined;

export async function WriteTree(path: string): Promise<string> {
  if (!baseDir) {
    baseDir = path;
  }

  const objs = (await readdir(path)).filter((v) => v !== '.git');

  const trees: Tree[] = [];

  for (const v of objs) {
    const fullPath = join(path, v);

    const st = await stat(fullPath);
    if (st.isFile()) {
      trees.push({
        mode: '100644',
        name: v,
        type: 'blob',
        sha: await writeToBlob(fullPath),
      });
    }
    if (st.isDirectory()) {
      trees.push({
        mode: '040000',
        name: v,
        type: 'tree',
        sha: await WriteTree(fullPath),
      });
    }
  }

  const contents = trees.reduce((acc, { mode, name, sha }) => {
    return Buffer.concat([
      acc,
      Buffer.from(`${mode} ${name}\0`),
      Buffer.from(sha, 'hex'),
    ]);
  }, Buffer.alloc(0));

  const treeContents = Buffer.concat([
    Buffer.from(`tree ${contents.length}\0`),
    contents,
  ]);

  const treeHash = createHash('sha1').update(treeContents).digest('hex');
  const dir = treeHash.slice(0, 2);

  await mkdir(join(baseDir, '.git', 'objects', dir), {
    recursive: true,
  });
  await writeFile(
    join(baseDir, '.git', 'objects', dir, treeHash.slice(2)),
    deflateSync(treeContents),
  );

  console.log(
    await exists(
      join(join(baseDir, '.git', 'objects', dir, treeHash.slice(2))),
    ),
  );

  return treeHash;
}

async function writeToBlob(path: string): Promise<string> {
  const content = await readFile(path);
  const header = `blob ${content.length}\0`;

  const data = Buffer.concat([Buffer.from(header), content]);
  const hash = createHash('sha1').update(data).digest('hex');

  const destDir = join(baseDir!, '.git', 'objects', hash.slice(0, 2));
  const fileDir = join(destDir, hash.slice(2));

  await mkdir(destDir, { recursive: true });
  await writeFile(fileDir, deflateSync(data));

  return hash;
}

Hey @AndreaGero,

Took a look at your repository, looks like this is related to the __dirname usage. __dirname returns the directory of the current script, but your program is actually being run from a separate directory (just like you’d run git in a different directory), so the correct function to use would be process.cwd() instead.

I was able to get the file written to the correct location with with this change:

Logs:

I see how this can be confusing when testing locally, will keep an eye out and see if we can do something about this!

@AndreaGero I saw your note re: how other code examples were using __dirname, turned out to be an error in how our Javascript starter code was structured. Fixed here: Fix Javascript usage by rohitpaulk · Pull Request #91 · codecrafters-io/build-your-own-git · GitHub.

@rohitpaulk I saw you tagged me on Github, thank for the help btw!

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.