1*4c3eb207Smrg#!/bin/sh 2*4c3eb207Smrg 3*4c3eb207Smrg# Script to add some local git customizations suitable for working 4*4c3eb207Smrg# with the GCC git repository 5*4c3eb207Smrg 6*4c3eb207Smrgask () { 7*4c3eb207Smrg question=$1 8*4c3eb207Smrg default=$2 9*4c3eb207Smrg var=$3 10*4c3eb207Smrg echo -n $question "["$default"]? " 11*4c3eb207Smrg read answer 12*4c3eb207Smrg if [ "x$answer" = "x" ] 13*4c3eb207Smrg then 14*4c3eb207Smrg eval $var=\$default 15*4c3eb207Smrg else 16*4c3eb207Smrg eval $var=\$answer 17*4c3eb207Smrg fi 18*4c3eb207Smrg} 19*4c3eb207Smrg 20*4c3eb207Smrg# Add a git command to find the git commit equivalent to legacy SVN revision NNN 21*4c3eb207Smrggit config alias.svn-rev '!f() { rev=$1; shift; git log --all --grep="^From-SVN: r\\?$rev\\b" "${@}"; } ; f' 22*4c3eb207Smrg 23*4c3eb207Smrg# Add git commands to convert git commit to monotonically increasing revision number 24*4c3eb207Smrg# and vice versa 25*4c3eb207Smrggit config alias.gcc-descr '!f() { "`git rev-parse --show-toplevel`/contrib/git-descr.sh" $@; } ; f' 26*4c3eb207Smrggit config alias.gcc-undescr '!f() { "`git rev-parse --show-toplevel`/contrib/git-undescr.sh" $@; } ; f' 27*4c3eb207Smrg 28*4c3eb207Smrggit config alias.gcc-verify '!f() { "`git rev-parse --show-toplevel`/contrib/gcc-changelog/git_check_commit.py" $@; } ; f' 29*4c3eb207Smrggit config alias.gcc-backport '!f() { "`git rev-parse --show-toplevel`/contrib/git-backport.py" $@; } ; f' 30*4c3eb207Smrggit config alias.gcc-fix-changelog '!f() { "`git rev-parse --show-toplevel`/contrib/git-fix-changelog.py" $@; } ; f' 31*4c3eb207Smrggit config alias.gcc-mklog '!f() { "`git rev-parse --show-toplevel`/contrib/mklog.py" $@; } ; f' 32*4c3eb207Smrggit config alias.gcc-commit-mklog '!f() { "`git rev-parse --show-toplevel`/contrib/git-commit-mklog.py" "$@"; }; f' 33*4c3eb207Smrg 34*4c3eb207Smrg# Make diff on MD files use "(define" as a function marker. 35*4c3eb207Smrg# Use this in conjunction with a .gitattributes file containing 36*4c3eb207Smrg# *.md diff=md 37*4c3eb207Smrggit config diff.md.xfuncname '^\(define.*$' 38*4c3eb207Smrg 39*4c3eb207Smrg# Tell git send-email where patches go. 40*4c3eb207Smrg# ??? Maybe also set sendemail.tocmd to guess from MAINTAINERS? 41*4c3eb207Smrggit config sendemail.to 'gcc-patches@gcc.gnu.org' 42*4c3eb207Smrg 43*4c3eb207Smrgset_user=$(git config --get "user.name") 44*4c3eb207Smrgset_email=$(git config --get "user.email") 45*4c3eb207Smrg 46*4c3eb207Smrgif [ "x$set_user" = "x" ] 47*4c3eb207Smrgthen 48*4c3eb207Smrg # Try to guess the user's name by looking it up in the password file 49*4c3eb207Smrg new_user=$(getent passwd $(whoami) | awk -F: '{ print $5 }') 50*4c3eb207Smrg if [ "x$new_user" = "x" ] 51*4c3eb207Smrg then 52*4c3eb207Smrg new_user="(no default)" 53*4c3eb207Smrg fi 54*4c3eb207Smrgelse 55*4c3eb207Smrg new_user=$set_user 56*4c3eb207Smrgfi 57*4c3eb207Smrgask "Your name" "${new_user}" new_user 58*4c3eb207Smrgif [ "x$new_user" = "x(no default)" ] 59*4c3eb207Smrgthen 60*4c3eb207Smrg echo "Cannot continue, git needs to record your name against commits" 61*4c3eb207Smrg exit 1 62*4c3eb207Smrgfi 63*4c3eb207Smrg 64*4c3eb207Smrgif [ "x$set_email" = "x" ] 65*4c3eb207Smrgthen 66*4c3eb207Smrg new_email="(no_default)" 67*4c3eb207Smrgelse 68*4c3eb207Smrg new_email=$set_email 69*4c3eb207Smrgfi 70*4c3eb207Smrg 71*4c3eb207Smrgask "Your email address (for git commits)" "${new_email}" new_email 72*4c3eb207Smrgif [ "x$new_email" = "x(no default)" ] 73*4c3eb207Smrgthen 74*4c3eb207Smrg echo "Cannot continue, git needs to record your email address against commits" 75*4c3eb207Smrg exit 1 76*4c3eb207Smrgfi 77*4c3eb207Smrg 78*4c3eb207Smrgif [ "x$set_user" != "x$new_user" ] 79*4c3eb207Smrgthen 80*4c3eb207Smrg git config "user.name" "$new_user" 81*4c3eb207Smrgfi 82*4c3eb207Smrg 83*4c3eb207Smrgif [ "x$set_email" != "x$new_email" ] 84*4c3eb207Smrgthen 85*4c3eb207Smrg git config "user.email" "$new_email" 86*4c3eb207Smrgfi 87*4c3eb207Smrg 88*4c3eb207Smrgupstream=$(git config --get "gcc-config.upstream") 89*4c3eb207Smrgif [ "x$upstream" = "x" ] 90*4c3eb207Smrgthen 91*4c3eb207Smrg upstream="origin" 92*4c3eb207Smrgfi 93*4c3eb207Smrgask "Local name for upstream repository" "origin" upstream 94*4c3eb207Smrg 95*4c3eb207Smrgv=$(git config --get-all "remote.${upstream}.fetch") 96*4c3eb207Smrgif [ "x$v" = "x" ] 97*4c3eb207Smrgthen 98*4c3eb207Smrg echo "Remote $upstream does not seem to exist as a remote" 99*4c3eb207Smrg exit 1 100*4c3eb207Smrgfi 101*4c3eb207Smrggit config "gcc-config.upstream" "$upstream" 102*4c3eb207Smrg 103*4c3eb207Smrgremote_id=$(git config --get "gcc-config.user") 104*4c3eb207Smrgif [ "x$remote_id" = "x" ] 105*4c3eb207Smrgthen 106*4c3eb207Smrg # See if the url specifies the remote user name. 107*4c3eb207Smrg url=$(git config --get "remote.$upstream.url") 108*4c3eb207Smrg if [ "x$url" = "x" ] 109*4c3eb207Smrg then 110*4c3eb207Smrg # This is a pure guess, but for many people it might be OK. 111*4c3eb207Smrg remote_id=$(whoami) 112*4c3eb207Smrg else 113*4c3eb207Smrg remote_id=$(echo $url | sed -r "s|^.*ssh://(.+)@gcc.gnu.org.*$|\1|") 114*4c3eb207Smrg if [ x$remote_id = x$url ] 115*4c3eb207Smrg then 116*4c3eb207Smrg remote_id=$(whoami) 117*4c3eb207Smrg fi 118*4c3eb207Smrg fi 119*4c3eb207Smrgfi 120*4c3eb207Smrg 121*4c3eb207Smrgask "Account name on gcc.gnu.org (for your personal branches area)" $remote_id remote_id 122*4c3eb207Smrggit config "gcc-config.user" "$remote_id" 123*4c3eb207Smrg 124*4c3eb207Smrgold_pfx=$(git config --get "gcc-config.userpfx") 125*4c3eb207Smrgif [ "x$old_pfx" = "x" ] 126*4c3eb207Smrgthen 127*4c3eb207Smrg old_pfx="me" 128*4c3eb207Smrgfi 129*4c3eb207Smrgecho 130*4c3eb207Smrgecho "Local branch prefix for personal branches you want to share" 131*4c3eb207Smrgecho "(local branches starting <prefix>/ can be pushed directly to your" 132*4c3eb207Smrgask "personal area on the gcc server)" $old_pfx new_pfx 133*4c3eb207Smrggit config "gcc-config.userpfx" "$new_pfx" 134*4c3eb207Smrg 135*4c3eb207Smrgecho 136*4c3eb207Smrgask "Install prepare-commit-msg git hook for 'git commit-mklog' alias" yes dohook 137*4c3eb207Smrgif [ "x$dohook" = xyes ]; then 138*4c3eb207Smrg hookdir=`git rev-parse --git-path hooks` 139*4c3eb207Smrg if [ -f "$hookdir/prepare-commit-msg" ]; then 140*4c3eb207Smrg echo " Moving existing prepare-commit-msg hook to prepare-commit-msg.bak" 141*4c3eb207Smrg mv "$hookdir/prepare-commit-msg" "$hookdir/prepare-commit-msg.bak" 142*4c3eb207Smrg fi 143*4c3eb207Smrg install -c "`git rev-parse --show-toplevel`/contrib/prepare-commit-msg" "$hookdir" 144*4c3eb207Smrgfi 145*4c3eb207Smrg 146*4c3eb207Smrg# Scan the existing settings to see if there are any we need to rewrite. 147*4c3eb207Smrgvendors=$(git config --get-all "remote.${upstream}.fetch" "refs/vendors/" | sed -r "s:.*refs/vendors/([^/]+)/.*:\1:" | sort | uniq) 148*4c3eb207Smrgurl=$(git config --get "remote.${upstream}.url") 149*4c3eb207Smrgpushurl=$(git config --get "remote.${upstream}.pushurl") 150*4c3eb207Smrgfor v in $vendors 151*4c3eb207Smrgdo 152*4c3eb207Smrg echo "Migrating vendor \"$v\" to new remote \"vendors/$v\"" 153*4c3eb207Smrg git config --unset-all "remote.${upstream}.fetch" "refs/vendors/$v/" 154*4c3eb207Smrg git config --unset-all "remote.${upstream}.push" "refs/vendors/$v/" 155*4c3eb207Smrg git config "remote.vendors/${v}.url" "${url}" 156*4c3eb207Smrg if [ "x$pushurl" != "x" ] 157*4c3eb207Smrg then 158*4c3eb207Smrg git config "remote.vendors/${v}.pushurl" "${pushurl}" 159*4c3eb207Smrg fi 160*4c3eb207Smrg git config --add "remote.vendors/${v}.fetch" "+refs/vendors/$v/heads/*:refs/remotes/vendors/${v}/*" 161*4c3eb207Smrg git config --add "remote.vendors/${v}.fetch" "+refs/vendors/$v/tags/*:refs/tags/vendors/${v}/*" 162*4c3eb207Smrgdone 163*4c3eb207Smrg 164*4c3eb207Smrg# Convert the remote 'pfx' to users/pfx to avoid problems with ambiguous refs 165*4c3eb207Smrg# on user branches 166*4c3eb207Smrgold_remote=$(git config --get "remote.${old_pfx}.url") 167*4c3eb207Smrgif [ -n "${old_remote}" ] 168*4c3eb207Smrgthen 169*4c3eb207Smrg echo "Migrating remote \"${old_pfx}\" to new remote \"users/${new_pfx}\"" 170*4c3eb207Smrg # Create a dummy fetch rule that will cause the subsequent prune to remove the old remote refs. 171*4c3eb207Smrg git config --replace-all "remote.${old_pfx}.fetch" "+refs/empty/*:refs/remotes/${old_pfx}/*" 172*4c3eb207Smrg # Remove any remotes 173*4c3eb207Smrg git remote prune ${old_pfx} 174*4c3eb207Smrg git config --remove-section "remote.${old_pfx}" 175*4c3eb207Smrg for br in $(git branch --list "${old_pfx}/*") 176*4c3eb207Smrg do 177*4c3eb207Smrg old_remote=$(git config --get "branch.${br}.remote") 178*4c3eb207Smrg if [ "${old_remote}" = "${old_pfx}" ] 179*4c3eb207Smrg then 180*4c3eb207Smrg git config "branch.${br}.remote" "users/${new_pfx}" 181*4c3eb207Smrg fi 182*4c3eb207Smrg done 183*4c3eb207Smrgfi 184*4c3eb207Smrg 185*4c3eb207Smrgecho "Setting up tracking for personal namespace $remote_id in remotes/users/${new_pfx}" 186*4c3eb207Smrggit config "remote.users/${new_pfx}.url" "${url}" 187*4c3eb207Smrgif [ "x$pushurl" != "x" ] 188*4c3eb207Smrgthen 189*4c3eb207Smrg git config "remote.users/${new_pfx}.pushurl" "${pushurl}" 190*4c3eb207Smrgfi 191*4c3eb207Smrggit config --replace-all "remote.users/${new_pfx}.fetch" "+refs/users/${remote_id}/heads/*:refs/remotes/users/${new_pfx}/*" "refs/users/${remote_id}/heads/" 192*4c3eb207Smrggit config --replace-all "remote.users/${new_pfx}.fetch" "+refs/users/${remote_id}/tags/*:refs/tags/users/${new_pfx}/*" "refs/users/${remote_id}/tags/" 193*4c3eb207Smrggit config --replace-all "remote.users/${new_pfx}.push" "refs/heads/${new_pfx}/*:refs/users/${remote_id}/heads/*" "refs/users/${remote_id}" 194*4c3eb207Smrg 195*4c3eb207Smrgif [ "$old_pfx" != "$new_pfx" -a "$old_pfx" != "${upstream}" ] 196*4c3eb207Smrgthen 197*4c3eb207Smrg git config --remove-section "remote.${old_pfx}" 198*4c3eb207Smrgfi 199*4c3eb207Smrg 200*4c3eb207Smrggit config --unset-all "remote.${upstream}.fetch" "refs/users/${remote_id}/" 201*4c3eb207Smrggit config --unset-all "remote.${upstream}.push" "refs/users/${remote_id}/" 202*4c3eb207Smrg 203*4c3eb207Smrggit fetch "users/${new_pfx}" 204