├── README.mkd └── gitpod /README.mkd: -------------------------------------------------------------------------------- 1 | # complete rewrite (Feb 2019) 2 | 3 | This is a complete rewrite of the code, to accommodate the fact that the old 4 | code no longer works under git v2.18 and above, due to fundamental changes in 5 | how git runs upload-pack. Basically, I am unable to fool it into executing 6 | gitpod's wrapper instead of the real "git-upload-pack", something that is 7 | required for the old version to do its thing. Luckily, I realised that 8 | git-daemon has (and apparently always had!), an "access hook" option, which 9 | gives us an "in". 10 | 11 | # hardcoded stuff (customisation TBD!) and other backward incompatibilities 12 | 13 | The script currently has some hardcodings; please let me know if you need any 14 | of them made more flexible/customisable 15 | 16 | - hardcoded to github.com 17 | - hardcoded "lazy" duration (just under 2.5 hours) 18 | 19 | Also, there is also no support for ssh mode now; if authenticated access to 20 | cached repos is needed, it's best done using gitolite, and enabling the 21 | "upstream" trigger. 22 | 23 | # install and use 24 | 25 | - best to create a special userid only for this 26 | 27 | - put this program in ~/bin in that userid 28 | 29 | - run this command 30 | 31 | git daemon \ 32 | --access-hook=$HOME/bin/gitpod \ 33 | --informative-errors \ 34 | --max-connections=1 \ 35 | --base-path=$HOME \ 36 | --export-all \ 37 | --reuseaddr \ 38 | --verbose \ 39 | --detach 40 | 41 | The "max-connections" is optional; I am running this on a very low-RAM 42 | box, so it helps me. (Sadly, git-daemon produces a cryptic "Connection 43 | reset by peer" when the limit is exceeded; be sure to inform your users 44 | that if they see that message they should try again after some time!) 45 | 46 | - add repos using this command: 47 | 48 | bin/gitpod add GITHUB_USER/GITHUB_REPO 49 | 50 | - (OPTIONAL) add the "status" repo 51 | 52 | cd 53 | git init status 54 | cd status 55 | git commit --allow-empty -m empty 56 | 57 | # for "users" 58 | 59 | Users use this as `git://this.host/GITHUB_USER/GITHUB_REPO` (for example `git 60 | clone git://127.0.0.1/sitaramc/gitolite`) 61 | 62 | # finding the status 63 | 64 | There's a very kludgey method to check what repos have recently been "fetched" 65 | from github.com: just run an ls-remote on a repo called "status": 66 | 67 | git ls-remote git://this.host.name/status 68 | 69 | A list of tags will show up, each of which is a carefully formatted set of 70 | date, time, IP address, and repo name. 71 | 72 | Yes, it's a kludge, as I already said, but if you can think of a better way to 73 | show users *something*, I'd be happy to hear it. 74 | 75 | -------------------------------------------------------------------------------- /gitpod: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # See README for documentation 4 | 5 | if [ "$1" = "add" ] 6 | then 7 | # we're being run manually from the command line 8 | cd 9 | git clone --mirror https://github.com/$2 $2.git 10 | exit $? 11 | fi 12 | 13 | # ---------------------------------------------------------------------- 14 | # check that we're being called by git-daemon; exit if not. We have not yet 15 | # added support for 'git archive', by the way 16 | [ "$1" = "upload-pack" ] || { echo huh?; exit 1; } 17 | 18 | # get the repo name 19 | repo=$2 # this is also $PWD, by the way 20 | # it is a full path; let's trim it a bit for our purposes 21 | repo=${repo#$HOME/} 22 | repo=${repo%.git} 23 | 24 | # no action needed for status repo 25 | [ "$repo" = "status/" ] && exit 0 26 | # about that trailing slash: status is a non-bare repo, so $repo starts out as 27 | # "$HOME/status/.git", and the two transformations above turn it into "status/" 28 | 29 | # code to add a tag to an optional "status" repo 30 | set_status() ( 31 | [ -d $HOME/status ] || return 32 | 33 | echo "$*" >> ~/gh.status.log 34 | cd $HOME/status 35 | unset GIT_DIR 36 | git tag "$1" 37 | 38 | # housekeeping; delete all but the last 100 "status" lines (i.e., tags). 39 | # I've no idea what happens when there are way too many tags, and I don't 40 | # care, in this application. This "100" is another hardcoding, by the way 41 | git tag | head -n -100 | while read t 42 | do 43 | git tag -d "$t" 44 | echo $t >> $HOME/deleted.tags 45 | done 46 | ) 47 | 48 | # too noisy; commented out 49 | # set_status "`date +%F.%H-%M-%S`-$REMOTE_ADDR-$repo" 50 | 51 | # is it fresh? We currently hardcode freshness as just under 2.5 hours 52 | # (specifically, 10% of a day) 53 | if perl -e 'exit 0 if -M "FETCH_HEAD" > 0.1; exit 1' 54 | then 55 | set_status "`date +%F.%H-%M-%S`-fetching-$repo" 56 | git fetch 57 | set_status "`date +%F.%H-%M-%S`-fetching-$repo-DONE" 58 | fi 59 | 60 | exit 0 61 | --------------------------------------------------------------------------------