-
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 2 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,77 @@ 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 password" | ||
read password | ||
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:$password\"" | ||
header_info="-H \"X-GitHub-OTP: $MFA_CODE\"" | ||
elif [[ -n "$password" ]]; then | ||
auth_info="-u \"$user:$password\"" | ||
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 >/dev/null | ||
|
||
[ $? = 0 ] || abort "fork failed" | ||
|
||
echo "Add GitHub remote branch via SSH (you will be prompted to verify the server's credentials)? (y/n)" | ||
read use_ssh | ||
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 | ||
|
||
# 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 | ||
|
@@ -55,6 +90,12 @@ if [ "$origin" = true ]; then | |
else | ||
# clone forked repo into current dir | ||
git clone "${remote_prefix}${user}/${project}.git" "$project" | ||
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. Maybe we could check if $project exists before cloning into it? 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. Git clone will not allow one to clone over an already existing repo directory.
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. @hickey |
||
until [[ -d "$project" ]]; do | ||
echo "Github is being slow today. Waiting 10 secs to attempt clone." | ||
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. There are various causes that should be responsible for the failure of 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. The issue I see there is that git clone is very verbose and just adds a lot of cruf to the terminal that does not need to be there (see below). Although I just realized that I should be sending stderr to /dev/null to avoid the excess cruf. Since the fork is asynchronous there is no way to determine when the fork is complete other than trying it. If I execute the fork command against github.com, the repo exists by the time that the clone is attempted. But if I try the fork command against the internal Github Enterprise instance, I end up waiting at least once for the fork to complete. (probably the fast LAN vs 200 ms across the net). The more that I think about it, the attempt to clone should probably only be attempted for about a minute or so. After that point the command should exit with an error code and a message that the repo could not be cloned locally.
|
||
sleep 10 | ||
git clone "${remote_prefix}${user}/${project}.git" "$project" | ||
done | ||
|
||
# add reference to origin fork so can merge in upstream changes | ||
cd "$project" | ||
git remote add upstream "${remote_prefix}${owner}/${project}.git" | ||
|
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 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
.\" generated with Ronn/v0.7.3 | ||
.\" http://github.com/rtomayko/ronn/tree/0.7.3 | ||
. | ||
.TH "GIT\-FORK" "1" "August 2016" "" "Git Extras" | ||
.TH "GIT\-FORK" "1" "February 2017" "" "" | ||
. | ||
.SH "NAME" | ||
\fBgit\-fork\fR \- Fork a repo on github | ||
|
@@ -40,7 +40,71 @@ adds the forked repo as a remote called \fBorigin\fR | |
.P | ||
Remotes will use ssh if you have it configured with GitHub, if not, https will be used\. | ||
. | ||
.P | ||
Your Github settings can not 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\. | ||
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 believe you meant now rather than "not be saved" here. |
||
. | ||
.IP "" 4 | ||
. | ||
.nf | ||
|
||
$ git config \-\-global git\-extras\.github\.com\.user greatcoder99 | ||
. | ||
.fi | ||
. | ||
.IP "" 0 | ||
. | ||
.P | ||
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)\. | ||
. | ||
.P | ||
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\. | ||
. | ||
.P | ||
Variables that are currently supported: | ||
. | ||
.IP "" 4 | ||
. | ||
.nf | ||
|
||
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\. | ||
. | ||
.fi | ||
. | ||
.IP "" 0 | ||
. | ||
.SH "EXAMPLE" | ||
Create settings to prevent answering questions: | ||
. | ||
.IP "" 4 | ||
. | ||
.nf | ||
|
||
$ 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 | ||
. | ||
.fi | ||
. | ||
.IP "" 0 | ||
. | ||
.P | ||
Fork expect\.js: | ||
. | ||
.IP "" 4 | ||
|
@@ -102,6 +166,9 @@ $ git fork | |
.SH "AUTHOR" | ||
Written by Andrew Griffiths <\fImail@andrewgriffithsonline\.com\fR> | ||
. | ||
.P | ||
Github Enterprise support and settings by Gerard Hickey <\fIhickey@kinetic\-compute\.com\fR> | ||
. | ||
.SH "REPORTING BUGS" | ||
<\fIhttps://github\.com/tj/git\-extras/issues\fR> | ||
. | ||
|
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 not be saved as git config values instead of | ||
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. And here as well: |
||
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 prefer let curl ask for my password instead of passing it in the option.
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.
Understandable. Although one is already being asked for the MFA code. Does that make sense to be asked for the MFA code before the password?
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.
@hickey
I think the order is not critical. Just because let curl ask for your password is simpler.