-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Feature/git fork #628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/git fork #628
Changes from all commits
7223c3e
4f99dbc
1c3621a
a588462
7867f02
f8dd7ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,42 +10,75 @@ test -z "$url" && url=$(git remote get-url origin 2> /dev/null) && origin=true | |
# validate repo url | ||
test -z "$url" && abort "github repo needs to be specified as an argument" | ||
|
||
# validate user | ||
echo "Enter your github username" | ||
read user | ||
[ -n "$user" ] || abort "git username required" | ||
echo "Enter github two-factor authentication code (leave blank if not set up)" | ||
read MFA_CODE | ||
|
||
# extract owner + project from repo url | ||
project=${url##*/} | ||
owner=${url%/$project} | ||
project=${project%.git} | ||
if [[ $owner == git@* ]]; then | ||
owner=${owner##*:} | ||
else | ||
owner=${owner##*/} | ||
fi | ||
owner=${owner##*[/:]} | ||
# Yes, the following extracts server for both SSH and https references | ||
server=${url##*@} | ||
server=${server##*://} | ||
server=${server%%[/:]*} | ||
|
||
# validate | ||
[ -z "$project" -o -z "$owner" ] && abort "github repo needs to be specified as an argument" | ||
|
||
# determine github credentials | ||
user=$(get_config_value "$server.user") | ||
token=$(get_config_value "$server.token") | ||
if [[ $(get_config_value "$server.add-api") == "true" ]]; then | ||
api_server="api.$server" | ||
else | ||
api_server=$server | ||
fi | ||
# retrieve the API prefix and clean it up (i.e. "api/v3/") | ||
api_prefix="$(get_config_value "$server.api-prefix")/" | ||
api_prefix=${api_prefix#/} | ||
api_prefix=${api_prefix/%\/\//\/} | ||
|
||
if [[ -z "$user" ]]; then | ||
# validate user | ||
echo "Enter your github username" | ||
read user | ||
[ -n "$user" ] || abort "git username required" | ||
fi | ||
|
||
if [[ -z "$token" ]]; then | ||
echo "Enter github two-factor authentication code (leave blank if not set up)" | ||
read MFA_CODE | ||
fi | ||
|
||
auth_info='' | ||
header_info='' | ||
if [[ -n "$token" ]]; then | ||
header_info="-H \"Authorization: token ${token}\"" | ||
elif [[ -n "$MFA_CODE" ]]; then | ||
auth_info="-u \"$user\"" | ||
header_info="-H \"X-GitHub-OTP: $MFA_CODE\"" | ||
elif [[ -n "$password" ]]; then | ||
auth_info="-u \"$user\"" | ||
else | ||
echo "No login credentials specified." | ||
exit 1 | ||
fi | ||
|
||
# create fork | ||
curl -qs \ | ||
-X POST \ | ||
-u "$user" \ | ||
-H "X-GitHub-OTP: $MFA_CODE" \ | ||
"https://api.github.com/repos/$owner/$project/forks" | ||
IFS="'" cmd="curl -qs -X POST $auth_info $header_info https://$api_server/${api_prefix}repos/$owner/$project/forks" | ||
eval $cmd | grep "message" >/dev/null | ||
|
||
[ $? = 0 ] || abort "fork failed" | ||
[ $? = 0 ] && abort "fork failed" | ||
|
||
use_ssh=$(get_config_value "$server.use-ssh") | ||
if [[ -z "$use_ssh" ]]; then | ||
echo "Add GitHub remote branch via SSH (you will be prompted to verify the server's credentials)? (y/n)" | ||
read use_ssh | ||
fi | ||
|
||
echo "Add GitHub remote branch via SSH (you will be prompted to verify the server's credentials)? (y/n)" | ||
read use_ssh | ||
# Check if user has ssh configured with GitHub | ||
if [ -n "$use_ssh" ] && ssh -T git@github.com 2>&1 | grep -qi 'success'; then | ||
remote_prefix="git@github.com:" | ||
if [ -n "$use_ssh" ] && ssh -T git@$server 2>&1 | grep -qi 'success'; then | ||
remote_prefix="git@$server:" | ||
else | ||
remote_prefix="https://github.com/" | ||
remote_prefix="https://$server/" | ||
fi | ||
|
||
if [ "$origin" = true ]; then | ||
|
@@ -54,9 +87,30 @@ if [ "$origin" = true ]; then | |
git fetch origin | ||
else | ||
# clone forked repo into current dir | ||
git clone "${remote_prefix}${user}/${project}.git" "$project" | ||
# add reference to origin fork so can merge in upstream changes | ||
cd "$project" | ||
git remote add upstream "${remote_prefix}${owner}/${project}.git" | ||
git fetch upstream | ||
git clone "${remote_prefix}${user}/${project}.git" "$project" 2>/dev/null | ||
|
||
# Check to make sure we cloned the repo. Backoff exponetially and try again | ||
timeout=( 2 2 2 6 6 6 20 20 ) | ||
total_wait=0 | ||
until [[ (( "$total_wait" > 60 )) || -d "$project" ]]; do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it will wait for 64(44 plus the last 20) seconds. |
||
echo "Github is being slow today. Waiting $timeout secs to attempt clone." | ||
sleep ${timeout[0]} | ||
total_wait=$(expr $total_wait + ${timeout[0]}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about that, but some of the older shells don't understand the double parenthesis. So I opted for the more traditional form. |
||
# drop the first element and prepare to wait the next time interval | ||
unset timeout[0] | ||
timeout=( ${timeout[@]} ) | ||
|
||
git clone "${remote_prefix}${user}/${project}.git" "$project" 2>/dev/null | ||
done | ||
|
||
if [[ -d "$project" ]]; then | ||
# add reference to origin fork so can merge in upstream changes | ||
cd "$project" | ||
git remote add upstream "${remote_prefix}${owner}/${project}.git" 2>/dev/null | ||
[[ $? > 0 ]] && echo "WARN: upstream reference already exists" | ||
git fetch upstream | ||
else | ||
echo "Github did not fork within 60 seconds or issue cloning repo." | ||
exit 1 | ||
fi | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# needed_by: git-fork | ||
|
||
get_config_value() { | ||
echo $(git config git-extras.$1) | ||
} | ||
|
||
# set_config_value "key" "value" "global|system" (global or system not required) | ||
set_config_value() { | ||
$(git config ${3+--$3} git-extras.$1 $2) | ||
echo $? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMHO, I prefer to use |
||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the output of
git clone
is cumbersome, but still think we should not hide the error message. They are like low level log, which may be useful sometimes.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still insist the need for the output of
git clone
.