{"thread":{"id":"29129","subject":"process committed files in post-receive hook","startedAt":"2011-12-10T10:29:12Z","lastAt":"2011-12-15T08:19:08Z","messageCount":8,"participants":["Hao","Michael Schubert","Ivan Heffner","Alexey Shumkin","Neal Kreitzinger","Hao Wang","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"180765","messageId":"loom.20111210T111457-837@post.gmane.org","threadId":"29129","inReplyTo":null,"subject":"process committed files in post-receive hook","fromName":"Hao","fromEmail":"billhao@gmail.com","sentAt":"2011-12-10T10:29:12Z","receivedAt":"2011-12-10T10:29:12Z","isPatch":false,"sender":{"key":"billhao@gmail.com","avatar":null},"body":"Hi guys,\n\nI am writing a post-receive hook in Python that examines the content of some \nfiles (the HEAD rev). Because the repo is a bare one on the server. My current \napproach is to check out a working copy on the server and run 'git pull' in post-\nreceive to get the most up-to-date version, and then process files in the \nworking copy.\n\nI have two questions. First, is there a way that I can access file content in a \nbare repo without checking out a working copy? If this is not possible, my \napproach would be reasonable. However, when 'git pull' was called in the python \nscript post-receive when a commit occurs, it gives an error.\n\nremote: fatal: Not a git repository: '.'\n\nThe call in python is\n\nsubprocess.Popen([\"git\", \"pull\"], cwd=\"/Users/git/ts.git.workingcopy\")\n\nI read from a post (http://stackoverflow.com/questions/4043609/) that GIT_DIR is \ncausing this error. Is it safe to unset GIT_DIR in post-receive?\n\nThanks a lot.\n"},{"id":"180778","messageId":"4EE340D2.200@elegosoft.com","threadId":"29129","inReplyTo":"loom.20111210T111457-837@post.gmane.org","subject":"Re: process committed files in post-receive hook","fromName":"Michael Schubert","fromEmail":"mschub@elegosoft.com","sentAt":"2011-12-10T11:21:54Z","receivedAt":"2011-12-10T11:21:54Z","isPatch":false,"sender":{"key":"mschub@elegosoft.com","avatar":null},"body":"On 12/10/2011 11:29 AM, Hao wrote:\n> I am writing a post-receive hook in Python that examines the content of some \n> files (the HEAD rev). Because the repo is a bare one on the server. My current \n> approach is to check out a working copy on the server and run 'git pull' in post-\n> receive to get the most up-to-date version, and then process files in the \n> working copy.\n\nYou could do something like this as a post-receive hook:\n\n#!/bin/sh\n\ntest_dir=$(mktemp -d /tmp/test.XXXXXXXXXX)\nGIT_WORK_TREE=$test_dir git checkout -f\n/usr/local/bin/check.py $test_dir\nrm -rf $test_dir\n"},{"id":"180783","messageId":"CAF_oF=yHGFs0TiXkbdoNFxXk2w8TcKSoYx2ZkiOQyYzgYHmxSQ@mail.gmail.com","threadId":"29129","inReplyTo":"4EE340D2.200@elegosoft.com","subject":"Re: process committed files in post-receive hook","fromName":"Ivan Heffner","fromEmail":"iheffner@gmail.com","sentAt":"2011-12-10T12:06:35Z","receivedAt":"2011-12-10T12:06:35Z","isPatch":false,"sender":{"key":"iheffner@gmail.com","avatar":"https://gravatar.com/avatar/1ead000fad98fe337916f06edfc94fd87207ffc81a3a5363589e51c4f2bfa602?d=mp&s=160"},"body":"On Sat, Dec 10, 2011 at 3:21 AM, Michael Schubert <mschub@elegosoft.com> wrote:\n> On 12/10/2011 11:29 AM, Hao wrote:\n>> I am writing a post-receive hook in Python that examines the content of some\n>> files (the HEAD rev). Because the repo is a bare one on the server. My current\n>> approach is to check out a working copy on the server and run 'git pull' in post-\n>> receive to get the most up-to-date version, and then process files in the\n>> working copy.\n>\n\nYou can actually use a combination of git ls-files and git cat-file -p\nin order to list and look at te content of files on the remote without\nchecking out an entire working tree.\n"},{"id":"180813","messageId":"20111211013131.1a37bf08@zappedws","threadId":"29129","inReplyTo":"loom.20111210T111457-837@post.gmane.org","subject":"Re: process committed files in post-receive hook","fromName":"Alexey Shumkin","fromEmail":"alex.crezoff@gmail.com","sentAt":"2011-12-10T21:31:31Z","receivedAt":"2011-12-10T21:31:31Z","isPatch":false,"sender":{"key":"alex.crezoff@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1183752?v=4"},"body":"> I have two questions. First, is there a way that I can access file\n> content in a bare repo without checking out a working copy? \n\n$ git show <commit>:<filename>\n\ne.g. for bare repo of Git the following command\n$ git show v1.7.8:Documentation/RelNotes/1.7.8.txt\noutputs\n--->8---\nGit v1.7.8 Release Notes\n========================\n\nUpdates since v1.7.7\n--------------------\n\n * Some git-svn, git-gui, git-p4 (in contrib) and msysgit updates.\n\n * Updates to bash completion scripts.\n--->8---\n"},{"id":"181198","messageId":"4EE94783.1010805@gmail.com","threadId":"29129","inReplyTo":"loom.20111210T111457-837@post.gmane.org","subject":"Re: process committed files in post-receive hook","fromName":"Neal Kreitzinger","fromEmail":"nkreitzinger@gmail.com","sentAt":"2011-12-15T01:04:03Z","receivedAt":"2011-12-15T01:04:03Z","isPatch":false,"sender":{"key":"nkreitzinger@gmail.com","avatar":null},"body":"On 12/10/2011 4:29 AM, Hao wrote:\n> Hi guys,\n>\n> I am writing a post-receive hook in Python that examines the content\n> of some files (the HEAD rev). Because the repo is a bare one on the\n> server. My current approach is to check out a working copy on the\n> server and run 'git pull' in post- receive to get the most up-to-date\n> version, and then process files in the working copy.\n>\n> I have two questions. First, is there a way that I can access file\n> content in a bare repo without checking out a working copy? If this\n> is not possible, my approach would be reasonable. However, when 'git\n> pull' was called in the python script post-receive when a commit\n> occurs, it gives an error.\n>\n> remote: fatal: Not a git repository: '.'\n>\n> The call in python is\n>\n> subprocess.Popen([\"git\", \"pull\"],\n> cwd=\"/Users/git/ts.git.workingcopy\")\n>\n> I read from a post (http://stackoverflow.com/questions/4043609/) that\n> GIT_DIR is causing this error. Is it safe to unset GIT_DIR in\n> post-receive?\n>\nThe specific processing you intend to perform on the files would\ndetermine which of the access techniques is appropriate for you.\nGenerally speaking, I think a checkout in a non-bare repo makes sense. \nYou could limit it to a shallow clone (see git-clone manpage) to save space.\n\nAnother way to get the files is git-archive (creates tar file), that you \ncould extract to a dir for processing.\n\nIn both cases, you need to consider the default permissions in play with \ngit-checkout and git-archive if permissions are important in your \nprocessing.\n\nv/r,\nneal\n"},{"id":"181201","messageId":"4EE95523.9030702@gmail.com","threadId":"29129","inReplyTo":"4EE94783.1010805@gmail.com","subject":"Re: process committed files in post-receive hook","fromName":"Hao Wang","fromEmail":"billhao@gmail.com","sentAt":"2011-12-15T02:02:11Z","receivedAt":"2011-12-15T02:02:11Z","isPatch":false,"sender":{"key":"billhao@gmail.com","avatar":null},"body":"Thank you all for providing the options. Just so you know I finally went \nwith Alexey's suggestion. I used 'git show' to get both a list of files \nin a directory and the content of each file. It works great on a bare \nrepository so there is no need to check out a copy on the server.\n\nBelow is the python code in my post-receive hook for this task, where \nrev is something like 'HEAD:directory_name' for the first function and \n'HEAD:directory/filename' for the second function.\n\n# get a list of rule files using git show\ndef getRuleFileList(rev):\n     # run git show\n     p = subprocess.Popen(['git', 'show', rev], stdout=subprocess.PIPE)\n     p.wait()\n     if p.returncode != 0: return None # error\n\n     # parse output\n     i = 0\n     filelist = []\n     for line in p.stdout.readlines():\n         filelist.append(line)\n     p.stdout.close()\n     return filelist\n\n# read the content of a file\ndef readfile(rev):\n     # run git show\n     p = subprocess.Popen(['git', 'show', rev], stdout=subprocess.PIPE)\n     p.wait()\n     if p.returncode != 0: return None # error\n     return p.stdout.read()\n\nHao\n\nOn 12/14/11 5:04 PM, Neal Kreitzinger wrote:\n> On 12/10/2011 4:29 AM, Hao wrote:\n>> Hi guys,\n>>\n>> I am writing a post-receive hook in Python that examines the content\n>> of some files (the HEAD rev). Because the repo is a bare one on the\n>> server. My current approach is to check out a working copy on the\n>> server and run 'git pull' in post- receive to get the most up-to-date\n>> version, and then process files in the working copy.\n>>\n>> I have two questions. First, is there a way that I can access file\n>> content in a bare repo without checking out a working copy? If this\n>> is not possible, my approach would be reasonable. However, when 'git\n>> pull' was called in the python script post-receive when a commit\n>> occurs, it gives an error.\n>>\n>> remote: fatal: Not a git repository: '.'\n>>\n>> The call in python is\n>>\n>> subprocess.Popen([\"git\", \"pull\"],\n>> cwd=\"/Users/git/ts.git.workingcopy\")\n>>\n>> I read from a post (http://stackoverflow.com/questions/4043609/) that\n>> GIT_DIR is causing this error. Is it safe to unset GIT_DIR in\n>> post-receive?\n>>\n> The specific processing you intend to perform on the files would\n> determine which of the access techniques is appropriate for you.\n> Generally speaking, I think a checkout in a non-bare repo makes sense.\n> You could limit it to a shallow clone (see git-clone manpage) to save\n> space.\n>\n> Another way to get the files is git-archive (creates tar file), that you\n> could extract to a dir for processing.\n>\n> In both cases, you need to consider the default permissions in play with\n> git-checkout and git-archive if permissions are important in your\n> processing.\n>\n> v/r,\n> neal\n"},{"id":"181212","messageId":"20111215072301.GC1327@sigill.intra.peff.net","threadId":"29129","inReplyTo":"4EE95523.9030702@gmail.com","subject":"Re: process committed files in post-receive hook","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-12-15T07:23:01Z","receivedAt":"2011-12-15T07:23:01Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Dec 14, 2011 at 06:02:11PM -0800, Hao Wang wrote:\n\n> Thank you all for providing the options. Just so you know I finally\n> went with Alexey's suggestion. I used 'git show' to get both a list\n> of files in a directory and the content of each file. It works great\n> on a bare repository so there is no need to check out a copy on the\n> server.\n\nIf you are scripting, we usually encourage the use of \"plumbing\"\ncommands whose output is guaranteed not to change (\"show\" is a\n\"porcelain\" command intended to be used by end-users, and it's possible\nthat its behavior might change from version to version).\n\nThe plumbing command to get a directory listing for a tree is \"git\nls-tree\" (try the \"--name-only\" option for terse output, and use \"-z\" if\nyou want to be robust in the face of filenames with funny characters).\n\n> # get a list of rule files using git show\n> def getRuleFileList(rev):\n>     # run git show\n>     p = subprocess.Popen(['git', 'show', rev], stdout=subprocess.PIPE)\n>     p.wait()\n>     if p.returncode != 0: return None # error\n> \n>     # parse output\n>     i = 0\n>     filelist = []\n>     for line in p.stdout.readlines():\n>         filelist.append(line)\n>     p.stdout.close()\n>     return filelist\n\nDoesn't this put \"tree HEAD:foo\", as printed by \"git show\", at the top\nof your filelist? Another reason to use ls-tree.\n\n> # read the content of a file\n> def readfile(rev):\n>     # run git show\n>     p = subprocess.Popen(['git', 'show', rev], stdout=subprocess.PIPE)\n>     p.wait()\n>     if p.returncode != 0: return None # error\n>     return p.stdout.read()\n\nThe plumbing for this is \"git cat-file blob ...\".\n\n-Peff\n"},{"id":"181214","messageId":"4EE9AD7C.5080107@gmail.com","threadId":"29129","inReplyTo":"20111215072301.GC1327@sigill.intra.peff.net","subject":"Re: process committed files in post-receive hook","fromName":"Hao Wang","fromEmail":"billhao@gmail.com","sentAt":"2011-12-15T08:19:08Z","receivedAt":"2011-12-15T08:19:08Z","isPatch":false,"sender":{"key":"billhao@gmail.com","avatar":null},"body":"\n> If you are scripting, we usually encourage the use of \"plumbing\"\n> commands whose output is guaranteed not to change (\"show\" is a\n> \"porcelain\" command intended to be used by end-users, and it's possible\n> that its behavior might change from version to version).\n>\n> The plumbing command to get a directory listing for a tree is \"git\n> ls-tree\" (try the \"--name-only\" option for terse output, and use \"-z\" if\n> you want to be robust in the face of filenames with funny characters).\n\nJeff, thank you for the information. This is really helpful.\n\n>> # get a list of rule files using git show\n>> def getRuleFileList(rev):\n>>      # run git show\n>>      p = subprocess.Popen(['git', 'show', rev], stdout=subprocess.PIPE)\n>>      p.wait()\n>>      if p.returncode != 0: return None # error\n>>\n>>      # parse output\n>>      i = 0\n>>      filelist = []\n>>      for line in p.stdout.readlines():\n>>          filelist.append(line)\n>>      p.stdout.close()\n>>      return filelist\n>\n> Doesn't this put \"tree HEAD:foo\", as printed by \"git show\", at the top\n> of your filelist? Another reason to use ls-tree.\n\nYes, the first two items (\"tree HEAD:foo\" and an empty line) are removed \nlater from filelist.\n\nHao\n"}]}