-
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
git-force-clone #591
git-force-clone #591
Changes from 1 commit
e476562
ad5365f
2137124
6e87dc3
5550cfa
71a1281
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 |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
- [`git extras`](#git-extras) | ||
- [`git feature|refactor|bug|chore`](#git-featurerefactorbugchore) | ||
- [`git fork`](#git-fork) | ||
- [`git force-clone`](#git-force-clone) | ||
- [`git fresh-branch`](#git-fresh-branch) | ||
- [`git gh-pages`](#git-gh-pages) | ||
- [`git graft`](#git-graft) | ||
|
@@ -344,6 +345,21 @@ upstream [email protected]:LearnBoost/expect.js (fetch) | |
upstream [email protected]:LearnBoost/expect.js (push) | ||
``` | ||
|
||
## git force-clone | ||
|
||
If the clone target directory exists, reset its contents to a clone of the | ||
remote. | ||
|
||
``` bash | ||
$ git force-clone [-b {branch_name}] {remote_url} {destination_path} | ||
$ git force-clone -b master https://github.com/tj/git-extras ./target-directory | ||
``` | ||
|
||
**CAUTION**: If the repository exists, this will destroy *all* local changes | ||
to the repository - changed files will be reset and local branches will be | ||
removed. | ||
|
||
[More information](man/git-force-clone.md). | ||
|
||
## git release | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#! /usr/bin/env bash | ||
|
||
set -euo pipefail | ||
|
||
_usage() { | ||
echo " | ||
Usage: | ||
git-force-clone -b branch remote_url destination_path | ||
|
||
Example: | ||
git-force-clone -b master [email protected]:me/repo.git ./repo_dir | ||
|
||
Provides the basic functionality of `git clone`, but if the destination | ||
repository already exists it will force-reset it to resemble a clone of the | ||
remote. | ||
|
||
Because it doesn't actually delete the directory, it is usually significantly | ||
faster than the alternative of deleting the directory and cloning the | ||
repository from scratch. | ||
|
||
**CAUTION**: If the repository exists, this will destroy *all* local work: | ||
changed files will be reset, local branches and other remotes will be removed. | ||
|
||
OPTIONS: | ||
-b, --branch The branch to pull from the remote (default: master) | ||
-h, --help Display this help message | ||
" | ||
} | ||
|
||
_check() { | ||
if [ -z "$1" ]; then | ||
echo "Error: Missing ${2}" | ||
_usage | ||
exit 1 | ||
fi | ||
} | ||
|
||
main() { | ||
while [[ -n "${1:-}" ]] && [[ "${1:0:1}" == "-" ]]; do | ||
case $1 in | ||
-b | --branch ) | ||
branch=${2:-} | ||
;; | ||
-h | --help ) | ||
_usage | ||
exit 0 | ||
;; | ||
* ) | ||
if [[ "${1:0:1}" == '-' ]]; then | ||
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. Is this check duplicate? 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. Yep. I'll remove. |
||
echo "Error: Invalid option: $1" >>/dev/stderr | ||
_usage | ||
exit 1 | ||
fi | ||
;; | ||
esac | ||
shift | ||
done | ||
|
||
remote_url=${1:-} | ||
destination_path=${2:-} | ||
|
||
_check "${remote_url}" "remote_url" | ||
_check "${destination_path}" "destination_path" | ||
|
||
if [ -d "${destination_path}/.git" ]; then | ||
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. What about existing directory which is not git repo? 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. This tool provides a solution just for existing git repos. If it's anything else, I figure it makes sense to pass it through to the standard 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. @nottrobin 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. @spacewander Yep fair enough, I'll do that. 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. Okay I've done that. |
||
( | ||
cd ${destination_path} | ||
|
||
# Delete all remotes | ||
for remote in `git remote`; do | ||
git remote rm ${remote} | ||
done | ||
|
||
# Add origin | ||
git remote add origin ${remote_url} | ||
git fetch origin | ||
|
||
# Set default branch | ||
if [ -z "${branch:-}" ]; then | ||
branch=`git remote show origin | grep -oP '(?<=HEAD branch: )[^ ]+$'` | ||
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. A
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. Cool I'll add this. |
||
git remote set-head origin ${branch} | ||
else | ||
git remote set-head origin -a | ||
fi | ||
|
||
# Make sure current branch is clean | ||
git clean -fd | ||
git reset --hard HEAD | ||
|
||
# Get on the desired branch | ||
git checkout ${branch} | ||
git reset --hard origin/${branch} | ||
|
||
# Delete all other branches | ||
branches=`git branch | grep -v \* | xargs` | ||
if [ -n "${branches}" ]; then | ||
git branch -D ${branches} | ||
fi | ||
) | ||
elif [ -n "${branch:-}" ]; then | ||
git clone -b ${branch} ${remote_url} ${destination_path} | ||
else | ||
git clone ${remote_url} ${destination_path} | ||
fi | ||
} | ||
|
||
main "$@" | ||
|
||
exit 0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
.\" generated with Ronn/v0.7.3 | ||
.\" http://github.com/rtomayko/ronn/tree/0.7.3 | ||
. | ||
.TH "GIT\-FORCE\-CLONE" "1" "2016-10-28" "" "Git Extras" | ||
. | ||
.SH "NAME" | ||
\fBgit\-force\-clone\fR \- overwrite local repositories with clone | ||
. | ||
.SH "SYNOPSIS" | ||
\fBforce\-clone \-\-help\fR \fBforce\-clone {remote_url} {destination_path}\fR \fBforce\-clone \-\-branch {branch_name} {remote_url} {destination_path}\fR | ||
. | ||
.SH "DESCRIPTION" | ||
Provides the basic functionality of \fBgit clone\fR, but if the destination repository already exists it will force\-reset it to resemble a clone of the remote\. | ||
. | ||
.P | ||
Because it doesn\'t actually delete the directory, it is usually significantly faster than the alternative of deleting the directory and cloning the repository from scratch\. | ||
. | ||
.P | ||
\fBCAUTION\fR: If the repository exists, this will destroy \fIall\fR local work: changed files will be reset, local branches and other remotes will be removed\. | ||
. | ||
.SH "PROCESS" | ||
If \fBtarget\-directory\fR doesn\'t exist then this will simply be passed through to \fBgit clone\fR, which will clone remote\. | ||
. | ||
.P | ||
If \fBtarget\-directory\fR \fIdoes\fR exist then this will: | ||
. | ||
.IP "\(bu" 4 | ||
Remove all remotes | ||
. | ||
.IP "\(bu" 4 | ||
Set the origin remote to \fB{remote_url}\fR and fetch the remote | ||
. | ||
.IP "\(bu" 4 | ||
Discover the default branch, if no branch was specified | ||
. | ||
.IP "\(bu" 4 | ||
Check out the selected branch | ||
. | ||
.IP "\(bu" 4 | ||
Delete all other local branches | ||
. | ||
.IP "" 0 | ||
. | ||
.SH "OPTIONS" | ||
\fB{remote_url}\fR \- The URL for a git remote repository of which to make a clone\. \fB{destination_path}\fR \- A path to the directory to clone into\. \fB\-\-branch {branch_name}\fR \- After cloning, checkout this branch\. | ||
. | ||
.SH "EXAMPLES" | ||
\fBgit\-force\-clone \-b master git@github\.com:me/repo\.git \./repo_dir\fR | ||
. | ||
.SH "AUTHOR" | ||
Written by Robin Winslow \fIrobin@robinwinslow\.co\.uk\fR\. | ||
. | ||
.SH "REPORTING BUGS" | ||
\fIhttps://github\.com/tj/git\-extras/issues\fR | ||
. | ||
.SH "SEE ALSO" | ||
\fIhttps://github\.com/tj/git\-extras\fR |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
git-force-clone(1) -- overwrite local repositories with clone | ||
=== | ||
|
||
## SYNOPSIS | ||
|
||
`force-clone --help` | ||
`force-clone {remote_url} {destination_path}` | ||
`force-clone --branch {branch_name} {remote_url} {destination_path}` | ||
|
||
## DESCRIPTION | ||
|
||
Provides the basic functionality of `git clone`, but if the destination | ||
repository already exists it will force-reset it to resemble a clone of the | ||
remote. | ||
|
||
Because it doesn't actually delete the directory, it is usually significantly | ||
faster than the alternative of deleting the directory and cloning the | ||
repository from scratch. | ||
|
||
**CAUTION**: If the repository exists, this will destroy *all* local work: | ||
changed files will be reset, local branches and other remotes will be removed. | ||
|
||
## PROCESS | ||
|
||
If `target-directory` doesn't exist then this will simply be passed through to | ||
`git clone`, which will clone remote. | ||
|
||
If `target-directory` *does* exist then this will: | ||
|
||
- Remove all remotes | ||
- Set the origin remote to `{remote_url}` and fetch the remote | ||
- Discover the default branch, if no branch was specified | ||
- Check out the selected branch | ||
- Delete all other local branches | ||
|
||
## OPTIONS | ||
|
||
`{remote_url}` - The URL for a git remote repository of which to make a clone. | ||
`{destination_path}` - A path to the directory to clone into. | ||
`--branch {branch_name}` - After cloning, checkout this branch. | ||
|
||
## EXAMPLES | ||
|
||
`git-force-clone -b master [email protected]:me/repo.git ./repo_dir` | ||
|
||
## AUTHOR | ||
|
||
Written by Robin Winslow <[email protected]>. | ||
|
||
## REPORTING BUGS | ||
|
||
<https://github.com/tj/git-extras/issues> | ||
|
||
## SEE ALSO | ||
|
||
<https://github.com/tj/git-extras> |
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.
Is a
shift
missing?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.
It does
shift
at the end of the whole case block, which seems to work. Why do I need it in here?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.
Sorry I understand now - it needs to shift two values. I'll update.