git.push() 有效,但 github 上的提交为空

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

我在浏览器中使用同构-git(目前Chrome)尝试在github[上保存代码=17=]

在我克隆一个私人 github 存储库后,我正在尝试向其中添加 新文件,执行 commit 将其推送 到同一个私有 Github 存储库。

但是,当我检查 Github 时,记录了提交但完全是空的!

这就像我添加的文件由于某种原因没有链接到提交并且提交不知道它们...

我从推送中得到了一个好的响应:

{
    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
        }
    }
}

这对我来说似乎很奇怪......但是提交及其消息显示在 github 上。

我做错了什么?我想我做了所有必要的事情,但也许我错过了一些东西......

这是我的代码:

    const stagingRoot = '/staging'
    ...
    import('https://unpkg.com/isomorphic-git@1.7.4/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)
          })
      })

我使用脚本标签中包含的 isomorphic-git 及其 FS 库 lightning-fs:

<script src="https://unpkg.com/@isomorphic-git/lightning-fs"></script>
<script src="https://unpkg.com/isomorphic-git@1.7.4"></script>

我还动态导入了isomorphic-git的http库如下,因为我的环境(Kintone)不喜欢ES6:

import('https://unpkg.com/isomorphic-git@1.7.4/http/web/index.js').then(http => {
    window.http = http
    return true
})

我解决了问题,因为有 3 个问题:

  1. 显然lightning-fs没有为rmdir实现递归,所以我自己写了:

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. 显然lightning-fs没有为mkdir实现递归,所以我自己写了:

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. 我误解了作为 add() 命令的参数传递的内容,回想起来这应该是显而易见的,但这就是为什么在文档中只放一些琐碎的例子从来都不是一个好主意,也不要放那么琐碎的例子澄清用例! 那么,我的错误是什么? 再看参数:
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>'
})

API 文档中提供的 example code 只有 filepath 的文件名,因为它位于 root工作树目录。当我写我的代码时,我不知不觉地做了同样的事情:

...
}).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 => {
...

但是工作目录dir应该只有stagingRoot! 并且路径值应该插入到 filepath 中,如下所示:

...
}).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 => {
...

.slice(1)是去掉前面的/因为filepath需要是相对路径!

我终于发现了我的错误,因为当我使用 readdir() 列出目录的内容时,我的 package.json 旁边出现了一个 .git ...

我希望这会对某人有所帮助,所以我也 post 摘录了我的最终代码:

      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
              },
            })
          })
      })