Ailete619
Ailete619

Reputation: 254

git.push() works but the commit on github is empty

I use isomorphic-git in the browser (Chrome at the moment) to try to save code on github

After I clone a private github repository, I am trying to add new files to it, do a commit and push it back on the same private Github repository.

But, when I check on Github, the commits are recorded but totally empty!

enter image description here

It is like the files I added where not linked to the commit for some reason and the commit is not aware of them ...

I get an Ok response from the push though:

{
    headers: {
        cache-control: "no-cache, max-age=0, must-revalidate"
        content-type: "application/x-git-receive-pack-result"
        date: "Tue, 04 Aug 2020 04:58:59 GMT"
        expires: "Fri, 01 Jan 1980 00:00:00 GMT"
        pragma: "no-cache"
        server: "cloudflare"
        vary: "Accept-Encoding"
        x-github-request-id: "CE24:0E4C:16E8D5:2B275C:5F28EB11"
    ok: true
    refs: {
        refs/heads/master: {
            error: ""
            ok: true
        }
    }
}

Which seems strange to me ... But the commit and its message show up on github.

What am I doing wrong? I think I did all the necessary things but maybe I missed something ...

Here, is my code:

    const stagingRoot = '/staging'
    ...
    import('https://unpkg.com/[email protected]/http/web/index.js').then(http => {
      window.http = http
      return true
    }).then(response => {
      // Initialize isomorphic-git with a file system
      window.fs = new LightningFS('fs')
      // Using the Promisified version
      window.pfs = window.fs.promises
      return true
    }).then(response => {
      const buttonSpace = document.getElementById('git_button_space')
      const repositoryURL = appendText({value:'https://github.com/<my private repository path>.git'},document.getElementById('git_repository_url_space'))
      let branch = appendDropdown(
        {items:[{label:'master',value:'master'}],value:'master'},
        document.getElementById('git_repository_branch_space'),
        function(event) {}
      )
      const username = appendText({value:'<my user name>'},document.getElementById('user-js-git_username_space'))
      const password = appendText({value:'<my app key>'},document.getElementById('user-js-git_password_space'))
      const path = appendText({value:'/git/git_app2'},document.getElementById('user-js-git_repository_path_space'))
      const pushButton = appendButton('プッシュ',buttonSpace, function(event) {
        return pfs.du(stagingRoot)
        .then(diskUsage => {
          return pfs.rmdir(stagingRoot,{recursive: true})
        })
        .catch(error => {
          return true
        }).then(response => {
          return pfs.mkdir(stagingRoot)
          .catch(error => {
            return true
          })
        }).then(response => {
          return git.clone({
            fs,
            http,
            dir:stagingRoot,
            corsProxy: 'https://cors.isomorphic-git.org',
            url: repositoryURL.getValue(),
            ref: branch.getValue(),
            onAuth: url => {
              const auth = {
                username: username.getValue(),
                password: password.getValue(),
              }
              return auth
            },
            singleBranch: true,
            depth: 100
          })
        }).then(response => {
          return pfs.du(stagingRoot+path.getValue())
            .then(diskUsage => {
              return true
            })
            .catch(error => {
              return pfs.mkdir(stagingRoot+path.getValue(),{recursive:true})
              .catch(error => {
                return true
              })
            })
          }).then(response => {
            return git.add({ fs, dir: stagingRoot+'/git', filepath: 'git_app2' })
          }).then(response => {
            return pfs.writeFile(stagingRoot+path.getValue()+'/package.json', JSON.stringify({key1:val1,key2:val2}))
          }).then(response => {
            return git.add({ fs, dir: stagingRoot+path.getValue(), filepath: 'package.json' })
          }).then(response => {
            const user = kintone.getLoginUser()
            return swal.fire({
              input: 'textarea',
              inputPlaceholder: 'commit message',
              inputAttributes: {
                'aria-label': 'commit message'
              },
              showCancelButton: true
            }).then(commitMessageResponse =>{
              if(commitMessageResponse.isConfirmed) {
                return git.commit({
                  fs,
                  dir: stagingRoot,
                  author: {
                    name: user.name,
                    email: user.email,
                  },
                  message: commitMessageResponse.value,
                  ref: branch.getValue(),
                })
              } else {
                return false
              }
            })
          }).then(response => {
            return git.push({
              fs,
              http,
              dir: stagingRoot,
              corsProxy: 'https://cors.isomorphic-git.org',
              remote: 'origin',
              ref: branch.getValue(),
              onAuth: url => {
                const auth = {
                  username: username.getValue(),
                  password: password.getValue(),
                }
                return auth
              },
            })
          }).then(response => {
            console.log(response)
          })
      })

I use isomorphic-git and its FS library lightning-fs that are included with script tags:

<script src="https://unpkg.com/@isomorphic-git/lightning-fs"></script>
<script src="https://unpkg.com/[email protected]"></script>

I also dynamically import isomorphic-git's http library like below as my environment (Kintone) does not like ES6:

import('https://unpkg.com/[email protected]/http/web/index.js').then(http => {
    window.http = http
    return true
})

Upvotes: 3

Views: 972

Answers (1)

Ailete619
Ailete619

Reputation: 254

I solved the problems, because there were 3 of them :

  1. Apparently lightning-fs does not implement recursion for rmdir, so I wrote my own:

function recursive_rmdir(path) {
  return pfs.readdir(path).then(fileList=> {
    const allPromises = []
    fileList.forEach(file => {
      allPromises.push(pfs.lstat(path+'/'+file).then(fileInfo => {
        if(fileInfo.isDirectory()) {
          return recursive_rmdir(path+'/'+file)
        } else {
          return pfs.unlink(path+'/'+file)
        }
      }))
    })
    return Promise.all(allPromises).then(response => {
      return pfs.rmdir(path)
    })
  })
}

  1. Apparently lightning-fs does not implement recursion for mkdir, so I wrote my own:

function recursive_mkdir(path) {
  function mkdir(existing_path,recursive_path) {
    const new_path = existing_path+recursive_path[0]+'/'
    return pfs.du(new_path)
      .then(diskUsage => {
        return true
      })
      .catch(error => {
        return pfs.mkdir(new_path)
          .catch(error => {
            console.log('error',error)
            return false
          })
      }).then(response => {
        if (recursive_path.length > 1) {
          return mkdir(new_path,recursive_path.slice(1))
        }
        return true
      })
  }
  return mkdir('',path.split('/'))
}

  1. I misunderstood what to pass as arguments for the add() command, which in retrospect should have been obvious but is why putting only trivial examples in the documentation is never a good idea, put not so trivial example too to clarify use cases! So, what was my mistake? Let's look at the parameters:
git.add({
    fs: <a file system implementation client>,
    dir: '<The working tree directory path>',
    filepath: '<The path to the file to add to the index>'
})

The example code provided in the API documentation had only the file name for filepath as it is located at the root of the working tree directory. When I wrote my code, I unwittingly did the same thing:

...
}).then(response => {
    return pfs.writeFile(stagingRoot+path.getValue()+'/package.json', JSON.stringify({key1:val1,key2:val2}))
}).then(response => {
    return git.add({ fs, dir: stagingRoot+path.getValue(), filepath: 'package.json' })
}).then(response => {
...

But the working directory dir should be only stagingRoot! And the path value should be inserted into the filepath like below:

...
}).then(response => {
    return pfs.writeFile(stagingRoot+path.getValue()+'/package.json', JSON.stringify({key1:val1,key2:val2}}))
}).then(response => {
    return git.add({ fs, dir: stagingRoot, filepath: path.getValue().slice(1)+'/'+'package.json' })
}).then(response => {
...

※ the .slice(1) is to take off the leading / as filepath needs to be a relative path!

I finally caught my error because a .git appeared next to my package.json when I used readdir() to list the content of the directory ...

I hope this will help someone, so I also post extracts of my final code:

      const pushButton = appendButton('プッシュ',buttonSpace, function(event) {
        return pfs.du(stagingRoot)
        .then(diskUsage => {
          return recursive_rmdir(stagingRoot)
        })
        .catch(error => {
          return true
        }).then(response => {
          return pfs.mkdir(stagingRoot)
          .catch(error => {
            console.log(error)
            return true
          })
        }).then(response => {
          return git.clone({
            fs,
            http,
            dir:stagingRoot,
            corsProxy: 'https://cors.isomorphic-git.org',
            url: repositoryURL.getValue(),
            ref: branch.getValue(),
            onAuth: url => {
              const auth = {
                username: username.getValue(),
                password: password.getValue(),
              }
              return auth
            },
            singleBranch: true,
            depth: 100
          })
        }).then(response => {
          return recursive_mkdir(stagingRoot+path.getValue())
            .catch(error => {
              console.log(error)
              return true
            })
          }).then(response => {
            return pfs.writeFile(stagingRoot+path.getValue()+'/package.json', JSON.stringify({key1:val1,key2:val2}))
          }).then(response => {
            return git.add({ fs, dir: stagingRoot, filepath: path.getValue().slice(1)+'/'+'package.json' })

          }).then(response => {
            const user = kintone.getLoginUser()
            return swal.fire({
              input: 'textarea',
              inputPlaceholder: 'コミットのメッセージここに入力してください',
              inputAttributes: {
                'aria-label': 'コミットのメッセージここに入力してください'
              },
              showCancelButton: true
            }).then(commitMessageResponse =>{
              if(commitMessageResponse.isConfirmed) {
                return git.commit({
                  fs,
                  dir: stagingRoot,
                  author: {
                    name: user.name,
                    email: user.email,
                  },
                  message: commitMessageResponse.value,
                  ref: branch.getValue(),
                })
              } else {
                return false
              }
            })
          }).then(response => {
            return git.push({
              fs,
              http,
              dir: stagingRoot,
              corsProxy: 'https://cors.isomorphic-git.org',
              remote: 'origin',
              ref: branch.getValue(),
              onAuth: url => {
                const auth = {
                  username: username.getValue(),
                  password: password.getValue(),
                }
                return auth
              },
            })
          })
      })

Upvotes: 2

Related Questions