-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
base: main
Are you sure you want to change the base?
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.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,8 +21,49 @@ git-fork(1) -- Fork a repo on github | |
|
||
Remotes will use ssh if you have it configured with GitHub, if not, https will be used. | ||
|
||
Your Github settings can now be saved as git config values instead of | ||
specifying them each time. To enable this you need to execute a few git | ||
config commands like the following. | ||
|
||
$ git config --global git-extras.github.com.user greatcoder99 | ||
|
||
Assuming that your username is 'greatcoder99'. All the configuration | ||
values are prefixed with 'git-extras.' followed by server hostname and | ||
then finally by the variable name (defined below). | ||
|
||
In addition, other Github instances may be used other than just | ||
github.com. So if you have a Github Enterprise instance, then using that | ||
hostname instead of github.com will work as expected. | ||
|
||
Variables that are currently supported: | ||
|
||
user: The username that the Github instance knows you as | ||
|
||
token: The personal access token that has been generated to allow | ||
password-less access to the API. | ||
|
||
add-api: In most cases this should be set to true. This adds the 'api' | ||
hostname to the repo location (i.e. github.com becomes api.github.com) | ||
to access the Github API. The time you would not set this is when | ||
your API hostname is the same as Github instance hostname. | ||
|
||
api-prefix: Github Enterprise much of the time uses "/api/v3/" as a | ||
entry point to the API. Regular Github access does not need to | ||
have a prefix specified. Consult your Github administrator for | ||
the correct prefix to use. | ||
|
||
use-ssh: Set to true in order to set the upstream remote reference | ||
to use SSH instead of https. | ||
|
||
## EXAMPLE | ||
|
||
Create settings to prevent answering questions: | ||
|
||
$ git config --global git-extras.github.com.user bigdog | ||
$ git config --global git-extras.github.com.token d149feb47.... | ||
$ git config --global git-extras.github.com.add-api true | ||
$ git config --global git-extras.github.com.use-ssl true | ||
|
||
Fork expect.js: | ||
|
||
$ git fork https://github.com/LearnBoost/expect.js | ||
|
@@ -51,6 +92,8 @@ git-fork(1) -- Fork a repo on github | |
|
||
Written by Andrew Griffiths <<[email protected]>> | ||
|
||
Github Enterprise support and settings by Gerard Hickey <<[email protected]>> | ||
|
||
## REPORTING BUGS | ||
|
||
<<https://github.com/tj/git-extras/issues>> | ||
|
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
.