Git LFS 不会推送 LFS 文件,除非我用 object-id 指定它们

Git LFS doesn't push LFS files unless I specify them with object-id

我在使用 LFS 的 Azure DevOps 上托管了一个存储库。 推送提交时,新的 LFS 对象不会随之推送(如果我将更改拉到单独的存储库,它会产生 Smudge Error: Object does not exist on server [404])。

要推送 LFS 对象的唯一方法是通过指定对象 ID 手动执行:

git lfs push origin --object-id ae488...

这是我的 git config -l:

$ git config -l
http.sslcainfo=C:/Users/200207121/AppData/Local/Programs/Git/mingw64/ssl/certs/ca-bundle.crt
http.sslbackend=openssl
diff.astextplain.textconv=astextplain
core.autocrlf=true
core.fscache=true
core.symlinks=false
core.editor="C:\Program Files\Notepad++\notepad++.exe" -multiInst -notabbar -nosession -noPlugin
credential.helper=manager
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
user.email=<omitted>
user.name=<omitted>
alias.lg=log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
http.sslverify=false
diff.tool=default-difftool
difftool.default-difftool.cmd=code --wait --diff $LOCAL $REMOTE
merge.tool=vscode
mergetool.vscode.cmd=code --wait $MERGED
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
remote.origin.url=https://.../MyRepo/_git/MyRepo
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
lfs.https://dev.azure.com/.../MyRepo.git/info/lfs.access=basic
lfs.https://dev.azure.com/.../MyRepo/info/lfs/objects/.access=basic
branch.7_1_0.remote=origin
branch.7_1_0.merge=refs/heads/7_1_0
branch.7_1_A.remote=origin
branch.7_1_A.merge=refs/heads/7_1_A
branch.atvcm01008318_text_class.remote=origin
branch.atvcm01008318_text_class.merge=refs/heads/text_class
branch.atvcm01008824.remote=origin
branch.atvcm01008824.merge=refs/heads/atvcm01008824
branch.atvcm01000423.remote=origin
branch.atvcm01000423.merge=refs/heads/atvcm01000423
gui.wmstate=normal
gui.geometry=1272x626+-5+0 254 315

为了防止推送特定分支,我在 pre-pushhook 中添加了这些行。我目前没有在这个分支上签出,我尝试推送的 LFS 也不在这个分支上(所以我不怀疑它可能是由这个钩子引起的):

#!/bin/sh

### Prevent pushing test branch
if [[ `grep 'testing_AA'` ]]; then 
  echo "You really don't want to push this branch. Aborting."
  exit 1
fi
### End of edition

command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n"; exit 2; }
git lfs pre-push "$@"

为什么我必须为要推送的 LFS 指定 git lfs push --object-id <oid>

pre-push 钩子的工作方式是从标准输入中读取行,这些行指示要推送哪些引用以及它们的旧值和新值是什么。与您的脚本一样,git lfs pre-push 用作预推挂钩,并期望在其标准输入中提供此数据。然后它会根据此确定需要推送哪些 LFS 对象并推送它们。

您的 pre-push 钩子所做的是使用 grep 读取所有标准输入。然后它在没有输入的情况下调用 git lfs pre-push。由于 Git LFS 认为没有要推送的引用(因为 none 在其标准输入上提供),它什么也不推送。

如果你想在推送特定引用的情况下中止,那么你需要让你的预推送钩子一次解析一行标准输入,如果匹配该行则中止,并且如果您不这样做,请将其附加到 git lfs pre-push 的未来输入中。所以像下面这样:

#!/bin/sh

INPUT=""

while read line
do
    if echo $line | grep -qs 'testing_AA'
    then
        echo "You really don't want to push this branch. Aborting." >&2
        exit 1
    fi
    INPUT="$INPUT $line"
done

printf "%s %s %s %s\n" $INPUT | git lfs pre-push "$@"