Last active
March 7, 2017 21:42
-
-
Save jlinoff/14c6901bbd9682a3f33efe92379e93b7 to your computer and use it in GitHub Desktop.
Demo to show how to setup a Google git-repo from scratch with 2 projects, it creates the projects, the manifest and the repo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# This example sets up two remote repositories named project1 and | |
# project2 in the current directory. | |
# | |
# It assumes a very old version of bash so that it can be used | |
# Mac OS X as well as Linux. | |
# | |
# Run it like this: | |
# | |
# $ mkdir /tmp/tryit | |
# $ cd /tmp/tryit | |
# $ cp ~/Downloads/setup.sh . | |
# $ chmod a+x setup.sh | |
# $ tree . # you must have tree installed | |
# $ ./setup.sh | |
# | |
# When it is done, you can run repo commands like this. | |
# | |
# $ cd myrepo | |
# $ ../bin/repo version | |
# $ ../bin/repo forall -p -c pwd | |
# | |
# Note that the bin/repo command is a wrapper that | |
# correctly sets the environment for new and existing | |
# repos. | |
# | |
# License: MIT Open Source | |
# Copyright (c) 2017 by Joe Linoff | |
# ================================================================ | |
# Functions | |
# ================================================================ | |
# Print an info message with context (caller line number) | |
function info() { | |
local Msg="$*" | |
echo -e "INFO:${BASH_LINENO[0]}: $Msg" | |
} | |
# Print a warning message with context (caller line number) | |
function warn() { | |
local Msg="$*" | |
echo -e "WARNING:${BASH_LINENO[0]}: $Msg" | |
} | |
# Print an error message and exit. | |
function err() { | |
local Msg="$*" | |
echo -e "ERROR:${BASH_LINENO[0]}: $Msg" | |
exit 1 | |
} | |
# Run a command with decorations. | |
function runcmd() { | |
local Cmd="$*" | |
local LineNum=${BASH_LINENO[0]} | |
echo | |
echo "INFO:${LineNum}: cmd.run=$Cmd" | |
eval "$Cmd" | |
local st=$? | |
echo "INFO:${LineNum}: cmd.status=$st" | |
if (( st )) ; then | |
echo "ERROR:${LineNum}: command failed" | |
exit 1 | |
fi | |
} | |
# ================================================================ | |
# Main | |
# ================================================================ | |
Checks=('remote-project1.git' | |
'remote-project2.git' | |
'remote-manifest.git' | |
'project1' | |
'project1a' | |
'project2' | |
'manifest' | |
'myrepo' | |
'bin' | |
) | |
for Check in ${Checks[@]} ; do | |
rm -rf "$Check" | |
if [ -e "$Check" ] ; then | |
err "file must not exist: $Check" | |
fi | |
done | |
RootDir=$(pwd) | |
# Create the remotes. | |
# The first two are for projects, | |
# the last one is for the remote. | |
runcmd git init --bare remote-project1.git | |
runcmd git init --bare remote-project2.git | |
runcmd git init --bare remote-manifest.git | |
# Create project1 by cloning from the remote. | |
runcmd git clone file://$RootDir/remote-project1.git project1 | |
runcmd cd project1 | |
runcmd pwd | |
runcmd git branch --list --all | |
runcmd git remote show origin | |
runcmd echo 'project1' '>' info.txt | |
runcmd git add info.txt | |
runcmd git commit -m "'Create info.txt'" | |
runcmd git push | |
runcmd git branch --list --all | |
runcmd git remote show origin | |
runcmd cd .. | |
# Create project2 from an existing git repo. | |
runcmd mkdir project2 | |
runcmd cd project2 | |
runcmd git init | |
runcmd echo 'project2' '>' info.txt | |
runcmd git add info.txt | |
runcmd git commit -m "'Create info.txt'" | |
runcmd git branch --list --all | |
# Now create the remote origin association. | |
runcmd git remote add origin file://$RootDir/remote-project2.git | |
runcmd git push --set-upstream origin master | |
runcmd git branch --list --all | |
runcmd git remote show origin | |
runcmd cd .. | |
# Create project1a from the project one, verify that info.txt | |
# exists. | |
runcmd git clone file://$RootDir/remote-project1.git project1a | |
runcmd cd project1a | |
runcmd ls -l info.txt | |
runcmd cat info.txt | |
runcmd cd .. | |
# Create the manifest. | |
# Create the default.xml file for project1 and project2. | |
# This is the hard part. | |
runcmd git clone file://$RootDir/remote-manifest.git manifest | |
runcmd cd manifest | |
runcmd pwd | |
runcmd git branch --list --all | |
runcmd git remote show origin | |
cat >default.xml <<EOF | |
<?xml version="1.0" encoding="UTF-8"?> | |
<manifest> | |
<remote name="origin" fetch="file://$RootDir/" /> | |
<default revision="master" remote="origin" /> | |
<project remote="origin" | |
path="project1" | |
name="remote-project1.git" /> | |
<project remote="origin" | |
path="project2" | |
name="remote-project2.git" /> | |
</manifest> | |
EOF | |
runcmd cat -n default.xml | |
runcmd git add default.xml | |
runcmd git commit -m "'Add default.xml'" | |
runcmd git push | |
runcmd cd .. | |
# Create the official git-repo local repository if necessary. | |
if [ ! -d git-repo ] ; then | |
runcmd git clone https://gerrit.googlesource.com/git-repo | |
runcmd cd git-repo | |
runcmd git checkout stable | |
runcmd cd .. | |
fi | |
runcmd export REPO_URL=file://$RootDir/git-repo | |
runcmd git-repo/repo help init | |
# Create the wrapper if it is not already there. | |
# This sets up the environment properly for repo | |
# and allows it to work with existing repos that | |
# may have used an older version. | |
if [ ! -f bin/repo ] ; then | |
[ ! -d bin ] && runcmd mkdir bin || true | |
cat >bin/repo <<EOF | |
#!/bin/bash | |
Loc=$(pwd)/git-repo | |
export REPO_URL=file://\$Loc | |
# Fix the repo configuration files. | |
File='.repo/repo/.git/FETCH_HEAD' | |
if [ -f \$File ] ; then | |
sed -i -E -e "s@ of .*\\\$@ of \$Loc@" \$File | |
fi | |
File='.repo/repo/.git/config' | |
if [ -f \$File ] ; then | |
sed -i -E -e "s@url = .*\\\$@url = \$Loc/.git@" \$File | |
fi | |
File='.repo/repo/.git/.repo_config.json' | |
if [ -f \$File ] ; then | |
Osname="\$( uname | tr 'A-Z' 'a-z')" | |
case "\$Osname" in | |
linux) | |
# GNU sed is very powerful. | |
sed -i -E -e "/remote.origin.url/{n;d;}" \$File | |
sed -i -E -e "s@(remote.origin.url.*\\\$)@\\1\n \"\$Loc/.git\"@" \$File | |
;; | |
darwin) | |
# Posix sed is slightly different. | |
sed -i -E -e "/remote.origin.url/{n;d;}" \$File | |
sed -i -E -e "s@(remote.origin.url.*\\\$)@\\1 \"\$Loc/.git\"@" \$File | |
;; | |
*) | |
echo "ERROR: unknown OS type: '\$Osname'." | |
exit 1 | |
;; | |
esac | |
fi | |
# Quote arguments. | |
Cmd="\$Loc/repo" | |
while (( \$# > 0 )) ; do | |
Arg="\$1" | |
shift | |
if echo "\$Arg" | egrep -q ' |\t' ; then | |
Cmd+=" \\"\$Arg\\"" | |
else | |
Cmd+=" \$Arg" | |
fi | |
done | |
# Echo the command line if REPO_CMD_ECHO=yes. | |
case "\$REPO_CMD_ECHO" in | |
y|yes|t|true) | |
echo "\$Cmd" | |
;; | |
*) | |
;; | |
esac | |
# Run the command. | |
eval \$Cmd | |
st=\$? | |
if (( st )) ; then | |
echo "ERROR: command failed (\$st)." | |
fi | |
exit \$st | |
EOF | |
chmod a+x bin/repo | |
fi | |
# Now that we have the manifest and the project remotes, create the | |
# repo. | |
runcmd mkdir myrepo | |
runcmd cd myrepo | |
runcmd ../bin/repo init -u file://$RootDir/remote-manifest.git | |
runcmd ../bin/repo sync | |
runcmd ../bin/repo forall -p -c pwd | |
runcmd ../bin/repo --version | |
runcmd ../bin/repo forall -p -c "'pwd && uname && uptime'" | |
which tree | |
if (( $? == 0 )) ; then | |
runcmd tree . | |
else | |
warn "command not found: tree" | |
fi | |
info "done" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment