git/list[1] front-page[2] threads[3] people[4] search[5] about
 

how to check for uncommitted/unstaged changes on remote side before pushing

From
MHMarc Haber <mh+git@zugschlus.de>
Date
Nov 8, 2015, 21:23 UTC
Message-ID
<20151108212320.GA18762@torres.zugschlus.de>
Hi,

I am trying to abuse git as a code distribution channel and would like to be able to trigger redistribution just by git push.

The idea is to push to a remote to the branch that is currently checked out followed by a git reset --hard in the post-receive hook. I have already figured out that I need to set receive.denyCurrentBranch to ignore to be able to push to the currently checked out branch.

I am also aware that it is a good idea to git pull before git push just in case there were local commits on the remote.

git reset --hard will unconditionally throw away local uncommitted changes. I would like to detect this situation on the remote and abort the receive progress. But my pre-receive hook does not work as intended. Here is my code:

#!/bin/bash
echo "this is the pre-receive hook on $HOSTNAME"
if [ "$(git status --porcelain | wc -l)" -ne 0 ]; then
  echo "there are uncommitted changes"
  echo "PWD=$PWD"
  echo "git status --porcelain"
  git status --porcelain
  echo "end git status"
  exit 1
fi
When I invoke my hook from the remote, everything is fine:
mh@jessie:~/.stdacct$ .git/hooks/pre-receive
this is the pre-receive hook on jessie
there are uncommitted changes
PWD=/home/mh/.stdacct
git status --porcelain
 M dotfiles/.bashrc
 M hooks/pre-receive-hook
?? hooks/pre-receive-hook~
end git status
mh@jessie:~/.stdacct$ 
However, the output is different when invoked during a push:
[7/504]mh@swivel:~/git/stdacct$ git push jessie
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 363 bytes | 0 bytes/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: this is the pre-receive hook on jessie
remote: there are uncommitted changes
remote: PWD=/home/mh/.stdacct/.git
remote: git status --porcelain
remote: ?? HEAD
remote: ?? ORIG_HEAD
remote: ?? config
remote: ?? description
remote: ?? hooks/applypatch-msg.sample
remote: ?? hooks/commit-msg.sample
remote: ?? hooks/post-receive
remote: ?? hooks/post-update.sample
remote: ?? hooks/pre-applypatch.sample
remote: ?? hooks/pre-commit.sample
remote: ?? hooks/pre-push.sample
remote: ?? hooks/pre-rebase.sample
remote: ?? hooks/pre-receive
remote: ?? hooks/prepare-commit-msg.sample
remote: ?? hooks/update.sample
remote: ?? index
remote: ?? index.lock
remote: ?? info/
remote: ?? logs/
remote: ?? objects/
remote: ?? refs/
remote: end git status
To ssh://jessie/home/mh/.stdacct
 ! [remote rejected] jessie -> jessie (pre-receive hook declined)
error: failed to push some refs to 'ssh://jessie/home/mh/.stdacct'

It looks like the hook thinks that it is invoked inside the .git/hooks directory which is not considered part of the repository.

What is going wrong here?

If my entire approach is wrong, what is the recommended way to prevent a repository with unstaged or uncommitted changes from being pushed to?

Greetings Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421
Next: Dennis Kaarsemaker
Message 1 of 4 in “how to check for uncommitted/unstaged changes on remote side before pushing”
  1. Marc HaberNov 8, 2015
  2. Dennis KaarsemakerNov 9, 2015
  3. Marc HaberNov 9, 2015
  4. Dennis KaarsemakerNov 9, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.