# Stuck at challenge git step 5

**URL:** <https://forum.codecrafters.io/t/stuck-at-challenge-git-step-5/646>\
**Category:** Challenges\
**Tags:** challenge:git\
**Created:** [June 7, 2024, 7:35am UTC](https://forum.codecrafters.io/t/stuck-at-challenge-git-step-5/646 "2024-06-07T07:35:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vijaychandra-Govindapalle](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/vijaychandra-govindapalle/32/549_2.png) [@Vijaychandra-Govindapalle](https://forum.codecrafters.io/u/Vijaychandra-Govindapalle)\
**Post date:** [June 7, 2024, 7:35am UTC](https://forum.codecrafters.io/t/stuck-at-challenge-git-step-5/646/1 "2024-06-07T07:35:14Z")

</div>

I’m stuck on Stage #(FE4)

I’ve tried multiple solutions from the solved examples but I am not able to pass.

Here are my logs:

```auto
[tester::#FE4] Running tests for Stage #FE4 (Write a tree object)
remote: [tester::#FE4] $ ./your_git.sh init
remote: [your_program] Initialized git directory
remote: [tester::#FE4] Creating some files & directories
remote: [tester::#FE4] $ ./your_git.sh write-tree
remote: [your_program] 801923b6ac7e55825b73e85ecbeaf26da256505d65496b5b730f2784a1129f210c65eddf53e94c55ca40a0d504bd1b82f45d397fad62dab9563190570bf21250eee4dce73d38daa7b534ae98c9d5056d7f192d74684a2148b7a639b7e1516a244df951a6
remote: [tester::#FE4] Expected a 40-char SHA as output. Got: 801923b6ac7e55825b73e85ecbeaf26da256505d65496b5b730f2784a1129f210c65eddf53e94c55ca40a0d504bd1b82f45d397fad62dab9563190570bf21250eee4dce73d38daa7b534ae98c9d5056d7f192d74684a2148b7a639b7e1516a244df951a6

```

And here’s a snippet of my code:

```javascript
const fs = require("fs");
const path = require("path");
const zlib = require("zlib")
const crypto = require("crypto")

 const command = process.argv[2];

 switch (command) {
   case "init":
     createGitDirectory();
     break;
   case "cat-file":
     readBlobObject(process.argv[4]);
     break;
   case "hash-object":
     writeBlobObject(process.argv[4]);
     break;
   case "ls-tree":
     listTreeContent(process.argv[4]);
     break;
   case "write-tree":
      process.stdout.write(writeTreeObject(process.cwd()).toString('hex'));
      break;    
   default:
     throw new Error(`Unknown command ${command}`);    
 }

 function createGitDirectory() {
   fs.mkdirSync(path.join(process.cwd(), ".git"), { recursive: true });
   fs.mkdirSync(path.join(process.cwd(), ".git", "objects"), { recursive: true });
   fs.mkdirSync(path.join(process.cwd(), ".git", "refs"), { recursive: true });

   fs.writeFileSync(path.join(process.cwd(), ".git", "HEAD"), "ref: refs/heads/main\n");
   console.log("Initialized git directory");
 }

 function readBlobObject(blobHash) {
    const filePath = sliceHash(blobHash)
    const compressedData = (fs.readFileSync(`.git/objects/${filePath}`)); 
    const decompressedData = decompressData(compressedData);
    const blobContent = extractContent(decompressedData);

    process.stdout.write(blobContent)
 }

 
 function sliceHash(Hash){
    return Hash.slice(0,2) + '/' + Hash.slice(2);
 }

 function decompressData(compressedData){
    return zlib.inflateSync(compressedData);
 }

 function extractContent(decompressedData){
    return decompressedData.toString().split('\0')[1];
 }

 function writeBlobObject(file){
    const fileActualContent = fs.readFileSync(file);
    const fileContent = `blob ${fileActualContent.length}\0${fileActualContent}`;
    const blobHash = createShaHash(fileContent)
    const filePath = sliceHash(blobHash)
    const compressedData = zlib.deflateSync(fileContent);
    createObject(filePath,compressedData);
    process.stdout.write(blobHash)
    const sha = createShaBinary(fileContent);
    return sha;

 }

 function createObject(objectSubPath,compressedData){
    fs.mkdirSync(`.git/objects/${objectSubPath.split('/')[0]}`, { recursive : true})
    fs.writeFileSync(`.git/objects/${objectSubPath}`,compressedData);
 }

 function createShaHash(data){
    const shaHash = crypto.createHash('sha1');
    shaHash.update(data);
    return shaHash.digest('hex');
 }

 function createShaBinary(data){
    const shaHash = crypto.createHash('sha1');
    shaHash.update(data);
    return shaHash.digest();
 }

 

 function listTreeContent(shaHash){
    const filePath = sliceHash(shaHash);
    const fileContent = decompressData(fs.readFileSync(`.git/objects/${filePath}`));
    const tree = fileContent.toString().split("\0").slice(1);
    const fileNames = [];
    for(let i = 0; i < tree.length; i++){
        fileNames.push(tree[i].split(' ')[1]);
    }
    process.stdout.write(fileNames.join("\n"));
 }

 function parseTree(dir){
   return fs.readdirSync(dir)
   .filter((file) => file !== ".git")
   .map((file) => {
      const fullPath = path.join(dir,file);
      if(fs.lstatSync(fullPath).isDirectory()){
         return {
            mode: 40000,
            name: file,
            hash: writeTreeObject(fullPath).toString('binary'),
         };
      } 
      return {
            mode: 100644,
            name: file,
            hash: writeBlobObject(fullPath).toString('binary'),
         };
      
   });
 }

  function writeTreeObject(dirPath) { 
    const tree = parseTree(dirPath); 
    const treeContent = tree.reduce((acc,{mode, name, hash})=>
      Buffer.concat([
         acc,
         Buffer.from(`${mode} ${name}\0`),
         Buffer.from(hash , 'binary'),
      ])
    ,Buffer.alloc(0));

    const treeObject = Buffer.concat([
      Buffer.from(`tree ${treeContent.length}\0`),
      treeContent
    ]);
    const treeHash = createShaHash(treeObject);
    const compressedData = zlib.deflateSync(treeObject);
    const subDirectory = treeHash.slice(0,2);
    const fileName = treeHash.slice(2);
    const sha = createShaBinary(treeObject);
    if(!fs.existsSync(path.resolve(".git", "objects",subDirectory))){
      fs.mkdirSync(path.resolve(".git", "objects",subDirectory));
    }
    fs.writeFileSync(path.resolve(".git", "objects",subDirectory,fileName), compressedData);
    return sha;
 }

```

---

<div class="post-metadata">

**Author:** ![rohitpaulk](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/rohitpaulk/32/6_2.png) [@rohitpaulk](https://forum.codecrafters.io/u/rohitpaulk)\
**Post date:** [June 7, 2024, 4:44pm UTC](https://forum.codecrafters.io/t/stuck-at-challenge-git-step-5/646/2 "2024-06-07T16:44:44Z")

</div>

> [@Vijaychandra-Govindapalle](#):
>
> ```auto
> function createShaBinary(data){
> const shaHash = crypto.createHash('sha1');
> shaHash.update(data);
> return shaHash.digest();
> }
> 
> ```

Could you try using `shaHash.digest('hex')` instead? (and remove the `.toString('hex')` from the top of the file)

I think the reason you’re seeing more than 40 chars is that `shaHash.digest()` returns a buffer of bytes by default (which is a “long” string), and converting that the hex is what results in a hexadecimal string that’s extremely long.

---

<div class="post-metadata">

**Author:** ![Vijaychandra-Govindapalle](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/vijaychandra-govindapalle/32/549_2.png) [@Vijaychandra-Govindapalle](https://forum.codecrafters.io/u/Vijaychandra-Govindapalle)\
**Post date:** [June 8, 2024, 2:46am UTC](https://forum.codecrafters.io/t/stuck-at-challenge-git-step-5/646/3 "2024-06-08T02:46:14Z")

</div>

I have tried multiple solutions like you said I have used the `shaHash.digest('hex')` first and then tried to convert it to binary using `toString('binary')` to store hashes in binary format and also tried returning only `sha` in the `createShaBinary` method and then converting using `.digest('binary')` while storing hashes and used `.digest('hex')` while producing the output and storing objects. Also tried keeping it as hex without converting to binary. Still I am not getting a 40 char sha, please help I am just stuck at this stage.

```auto
remote: [tester::#FE4] Running tests for Stage #FE4 (Write a tree object)
remote: [tester::#FE4] $ ./your_git.sh init
remote: [your_program] Initialized git directory
remote: [tester::#FE4] Creating some files & directories
remote: [tester::#FE4] $ ./your_git.sh write-tree
remote: [your_program] ef69c0a874e5df0bde8fd5ad93b37e2b8b0affb70596acea65c19abd0dab4994746aa2b834c2cf6833b2ffaaa1caeb3bf0032a6374a80420dacc232426eb0004463fb35c7e44799f470bce7e2ffdb1e420782b4cd1dadd3a9cd2dde779fa60dc1dcaba67
remote: [tester::#FE4] Expected a 40-char SHA as output. Got: ef69c0a874e5df0bde8fd5ad93b37e2b8b0affb70596acea65c19abd0dab4994746aa2b834c2cf6833b2ffaaa1caeb3bf0032a6374a80420dacc232426eb0004463fb35c7e44799f470bce7e2ffdb1e420782b4cd1dadd3a9cd2dde779fa60dc1dcaba67
remote: [tester::#FE4] Test failed
remote:

```

---

<div class="post-metadata">

**Author:** ![Vijaychandra-Govindapalle](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/vijaychandra-govindapalle/32/549_2.png) [@Vijaychandra-Govindapalle](https://forum.codecrafters.io/u/Vijaychandra-Govindapalle)\
**Post date:** [June 8, 2024, 10:08am UTC](https://forum.codecrafters.io/t/stuck-at-challenge-git-step-5/646/4 "2024-06-08T10:08:29Z")

</div>

Hey really thanks for the help looks like the issue I was printing the blob hash in `writeBlobObject` function which resulted in the extra characters.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/3X/7/0/700657133935c15703e22c7c8870394f6e6dc27d.svg) [@system](https://forum.codecrafters.io/u/system)\
**Post date:** [June 13, 2024, 10:09am UTC](https://forum.codecrafters.io/t/stuck-at-challenge-git-step-5/646/5 "2024-06-13T10:09:02Z")

</div>

Closed on June 13, 2024, 10:09am UTC

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