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

[PATCH] contrib/hooks: add post-update hook for updating working copy

From
Sam Vilain <sam.vilain@catalyst.net.nz>
Date
Jun 30, 2007, 08:56 UTC
Message-ID
<11831937823588-git-send-email-sam.vilain@catalyst.net.nz>
In-Reply-To
<11831937822950-git-send-email-sam.vilain@catalyst.net.nz>

Many users want 'git push' to work like 'git pull'; that is, after the transfer of the new objects, the working copy is updated, too. This hook tries to be paranoid and never lose any information, as well as being able to be safely just chmod +x'ed without destroying anything it shouldn't.

Also allude to this potential feature on the man page for git-push.
Signed-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>
---
 Documentation/git-push.txt   |    4 ++-
 templates/hooks--post-update |   78 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 665f6dc..9f5fbc7 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -20,7 +20,9 @@ necessary to complete the given refs.
 
 You can make interesting things happen to a repository
 every time you push into it, by setting up 'hooks' there.  See
-documentation for gitlink:git-receive-pack[1].
+documentation for gitlink:git-receive-pack[1].  One commonly
+requested feature, updating the working copy of the target
+repository, must be enabled in this way.
 
 
 OPTIONS
diff --git a/templates/hooks--post-update b/templates/hooks--post-update
index bcba893..b5d490c 100644
--- a/templates/hooks--post-update
+++ b/templates/hooks--post-update
@@ -1,8 +1,78 @@
 #!/bin/sh
 #
-# An example hook script to prepare a packed repository for use over
-# dumb transports.
+# This hook does two things:
 #
-# To enable this hook, make this file executable by "chmod +x post-update".
+#  1. update the "info" files that allow the list of references to be
+#     queries over dumb transports such as http
+#
+#  2. if this repository looks like it is a non-bare repository, and
+#     the checked-out branch is pushed to, then update the working copy.
+#     This makes "push" and "pull" symmetric operations, as in darcs and
+#     bzr.
+
+git-update-server-info
+
+export GIT_DIR=`cd $GIT_DIR; pwd`
+[ `expr "$GIT_DIR" : '.*/\.git'` = 0 ] && exit 0
+
+tree_in_revlog() {
+    ref=$1
+    tree=$2
+    found=$(
+    tail logs/$ref | while read commit rubbish
+    do
+        this_tree=`git-rev-parse commit $commit^{tree}`
+	if [ "$this_tree" = "$tree" ]
+        then
+	    echo $commit
+        fi
+    done
+    )
+    [ -n "$found" ] && true
+}
+
+for ref
+do
+active=`git-symbolic-ref HEAD`
+if [ "$ref" = "$active" ]
+then
+  echo "Pushing to checked out branch - updating working copy" >&2
+  success=
+  if ! (cd ..; git-diff-files) | grep -q .
+  then
+    # save the current index just in case
+    current_tree=`git-write-tree`
+    if tree_in_revlog $ref $current_tree
+    then
+      cd ..
+      if git-diff-index -R --name-status HEAD >&2 &&
+         git-diff-index -z --name-only --diff-filter=A HEAD | xargs -0r rm &&
+         git-reset --hard HEAD
+      then
+         success=1
+      else
+        echo "E:unexpected error during update" >&2
+      fi
+    else
+      echo "E:uncommitted, staged changes found" >&2
+    fi
+  else
+    echo "E:unstaged changes found" >&2
+  fi
 
-exec git-update-server-info
+  if [ -z "$success" ]
+  then
+    (
+    echo "Non-bare repository checkout is not clean - not updating it"
+    echo "However I AM going to update the index.  Any half-staged commit"
+    echo "in that checkout will be thrown away, but on the bright side"
+    echo "this is probably the least confusing thing for us to do and at"
+    echo "least we're not throwing any files somebody has changed away"
+    git-reset --mixed HEAD
+    echo
+    echo "This is the new status of the upstream working copy:"
+    git-status
+    ) >&2
+  fi
+fi
+done
-- 
1.5.2.1.1131.g3b90
Previous: Sam VilainNext: Sam Vilain
Message 10 of 37 in “a bunch of outstanding updates”
  1. Sam VilainJun 30, 2007
  2. repack: improve documentation on -a optionSam Vilain, Jun 30, 2007
  3. git-svn: use git-log rather than rev-list | xargs cat-fileSam Vilain, Jun 30, 2007
  4. git-svn: cache max revision in rev_db databasesSam Vilain, Jun 30, 2007
  5. GIT-VERSION-GEN: don't convert - delimiter to .'sSam Vilain, Jun 30, 2007
  6. git-remote: document -nSam Vilain, Jun 30, 2007
  7. git-remote: allow 'git-remote fetch' as a synonym for 'git fetch'Sam Vilain, Jun 30, 2007
  8. git-merge-ff: fast-forward only mergeSam Vilain, Jun 30, 2007
  9. git-mergetool: add support for ediffSam Vilain, Jun 30, 2007
  10. contrib/hooks: add post-update hook for updating working copySam Vilain, Jun 30, 2007
  11. git-repack: generational repacking (and example hook script)Sam Vilain, Jun 30, 2007
  12. Nicolas PitreJul 3, 2007
  13. Sam VilainJul 3, 2007
  14. Nicolas PitreJul 3, 2007
  15. Shawn O. PearceJul 3, 2007
  16. Sam VilainJul 4, 2007
  17. Johannes SchindelinJul 4, 2007
  18. Sam VilainJul 4, 2007
  19. Alex RiesenJul 4, 2007
  20. Nicolas PitreJul 4, 2007
  21. Junio C HamanoJun 30, 2007
  22. Sam VilainJul 1, 2007
  23. Junio C HamanoJul 2, 2007
  24. Junio C HamanoJun 30, 2007
  25. Sam VilainJul 1, 2007
  26. Johannes SchindelinJun 30, 2007
  27. Matthias LederhoferJun 30, 2007
  28. Junio C HamanoJun 30, 2007
  29. Frank LichtenheldJun 30, 2007
  30. Junio C HamanoJun 30, 2007
  31. Jakub NarebskiJul 11, 2007
  32. Junio C HamanoJul 1, 2007
  33. Eric WongJul 1, 2007
  34. Junio C HamanoJul 1, 2007
  35. Frank LichtenheldJun 30, 2007
  36. Junio C HamanoJun 30, 2007
  37. Frank LichtenheldJun 30, 2007

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.