1

I have a repo hosted on Azure DevOps that uses LFS. When pushing a commit, the new LFS object isn't pushed with it (if I pull the changes on a separate repository, it yields Smudge Error: Object does not exist on server [404]).

The only way for the LFS object to be pushed is to do it manually by specifying the object id :

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

Here is my 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

To prevent a specific branch from pushing, I have added those lines in pre-pushhook. I'm not currently checked out on this branch, and the LFS I try to push isn't on this branch either (so I don't suspect it can be caused by this hook) :

#!/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 "$@"

Why do I have to specify git lfs push --object-id <oid> for the LFS to be pushed ?

Arthur Attout
  • 2,701
  • 2
  • 26
  • 49

1 Answers1

1

The way that a pre-push hook works is to read lines from standard input that indicate which refs are to be pushed and what their old and new values are. Like your script, git lfs pre-push works as a pre-push hook and expects this data on its standard input. It then determines what LFS objects need to be pushed based on that and pushes them.

What your pre-push hook does is read all of the standard input with grep. It then invokes git lfs pre-push with no input. Since Git LFS thinks there are no refs to push (because none were provided on its standard input), it pushes nothing.

If you want to abort in the case that you're pushing a specific ref, then you need to have your pre-push hook parse the standard input a line at a time, aborting if you match the line, and appending it to the future input to git lfs pre-push if you don't. So something like the following:

#!/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 "$@"
bk2204
  • 64,793
  • 6
  • 84
  • 100
  • This is really an overcomplicated way to handle push to me .. Or there's an use to it I don't get. Anyway, [I should have known it wasn't that easy](https://stackoverflow.com/a/30471886/7540393). Thanks for the troubleshoot ! – Arthur Attout Jan 24 '20 at 15:03
  • Thanks a lot for the help. **There's just one mistake**: The last line should be changed to `printf "%s %s %s %s\n" $INPUT | git lfs pre-push "$@"` in order to re-transmit the *remote* and *remote URL* arguments. – Patrick Janser Mar 17 '22 at 13:20