mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
commit
db62a6d95c
16
Commands.md
16
Commands.md
|
|
@ -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 git@github.com:LearnBoost/expect.js (fetch)
|
|||
upstream git@github.com:LearnBoost/expect.js (push)
|
||||
```
|
||||
|
||||
## git force-clone
|
||||
|
||||
If the clone target directory exists and is a git repository, 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
|
||||
|
||||
|
|
|
|||
108
bin/git-force-clone
Executable file
108
bin/git-force-clone
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
#! /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 git@github.com:me/repo.git ./repo_dir
|
||||
|
||||
Provides the basic functionality of 'git clone', but if the destination git
|
||||
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:-}
|
||||
shift
|
||||
;;
|
||||
-h | --help )
|
||||
_usage
|
||||
exit 0
|
||||
;;
|
||||
* )
|
||||
echo "Error: Invalid option: $1" >>/dev/stderr
|
||||
_usage
|
||||
exit 1
|
||||
;;
|
||||
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
|
||||
(
|
||||
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=`LC_ALL=C git remote show origin | grep -oP '(?<=HEAD branch: )[^ ]+$'`
|
||||
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
|
||||
|
|
@ -259,7 +259,6 @@ _git-feature() {
|
|||
esac
|
||||
}
|
||||
|
||||
|
||||
_git-graft() {
|
||||
_arguments \
|
||||
':src-branch-name:__gitex_branch_names' \
|
||||
|
|
@ -373,6 +372,7 @@ zstyle ':completion:*:*:git:*' user-commands \
|
|||
effort:'show effort statistics on file(s)' \
|
||||
extras:'awesome git utilities' \
|
||||
feature:'create/merge feature branch' \
|
||||
force-clone:'overwrite local repositories with clone' \
|
||||
fork:'fork a repo on github' \
|
||||
fresh-branch:'create fresh branches' \
|
||||
gh-pages:'create the github pages branch' \
|
||||
|
|
|
|||
57
man/git-force-clone.1
Normal file
57
man/git-force-clone.1
Normal file
|
|
@ -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-29" "" "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 git 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 or isn\'t a git repository then the arguments will simply be passed through to \fBgit clone\fR\.
|
||||
.
|
||||
.P
|
||||
If \fBtarget\-directory\fR exists and is a git repository 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 local git repository location 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
|
||||
144
man/git-force-clone.html
Normal file
144
man/git-force-clone.html
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv='content-type' value='text/html;charset=utf8'>
|
||||
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
|
||||
<title>git-force-clone(1) - overwrite local repositories with clone</title>
|
||||
<style type='text/css' media='all'>
|
||||
/* style: man */
|
||||
body#manpage {margin:0}
|
||||
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
|
||||
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
|
||||
.mp h2 {margin:10px 0 0 0}
|
||||
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
|
||||
.mp h3 {margin:0 0 0 4ex}
|
||||
.mp dt {margin:0;clear:left}
|
||||
.mp dt.flush {float:left;width:8ex}
|
||||
.mp dd {margin:0 0 0 9ex}
|
||||
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
|
||||
.mp pre {margin-bottom:20px}
|
||||
.mp pre+h2,.mp pre+h3 {margin-top:22px}
|
||||
.mp h2+pre,.mp h3+pre {margin-top:5px}
|
||||
.mp img {display:block;margin:auto}
|
||||
.mp h1.man-title {display:none}
|
||||
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
|
||||
.mp h2 {font-size:16px;line-height:1.25}
|
||||
.mp h1 {font-size:20px;line-height:2}
|
||||
.mp {text-align:justify;background:#fff}
|
||||
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
|
||||
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
|
||||
.mp u {text-decoration:underline}
|
||||
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
|
||||
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
|
||||
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
|
||||
.mp b.man-ref {font-weight:normal;color:#434241}
|
||||
.mp pre {padding:0 4ex}
|
||||
.mp pre code {font-weight:normal;color:#434241}
|
||||
.mp h2+pre,h3+pre {padding-left:0}
|
||||
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
|
||||
ol.man-decor {width:100%}
|
||||
ol.man-decor li.tl {text-align:left}
|
||||
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
|
||||
ol.man-decor li.tr {text-align:right;float:right}
|
||||
</style>
|
||||
</head>
|
||||
<!--
|
||||
The following styles are deprecated and will be removed at some point:
|
||||
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
|
||||
|
||||
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
|
||||
.man-navigation should be used instead.
|
||||
-->
|
||||
<body id='manpage'>
|
||||
<div class='mp' id='man'>
|
||||
|
||||
<div class='man-navigation' style='display:none'>
|
||||
<a href="#NAME">NAME</a>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a>
|
||||
<a href="#PROCESS">PROCESS</a>
|
||||
<a href="#OPTIONS">OPTIONS</a>
|
||||
<a href="#EXAMPLES">EXAMPLES</a>
|
||||
<a href="#AUTHOR">AUTHOR</a>
|
||||
<a href="#REPORTING-BUGS">REPORTING BUGS</a>
|
||||
<a href="#SEE-ALSO">SEE ALSO</a>
|
||||
</div>
|
||||
|
||||
<ol class='man-decor man-head man head'>
|
||||
<li class='tl'>git-force-clone(1)</li>
|
||||
<li class='tc'>Git Extras</li>
|
||||
<li class='tr'>git-force-clone(1)</li>
|
||||
</ol>
|
||||
|
||||
<h2 id="NAME">NAME</h2>
|
||||
<p class="man-name">
|
||||
<code>git-force-clone</code> - <span class="man-whatis">overwrite local repositories with clone</span>
|
||||
</p>
|
||||
|
||||
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
||||
|
||||
<p><code>force-clone --help</code>
|
||||
<code>force-clone {remote_url} {destination_path}</code>
|
||||
<code>force-clone --branch {branch_name} {remote_url} {destination_path}</code></p>
|
||||
|
||||
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
||||
|
||||
<p>Provides the basic functionality of <code>git clone</code>, but if the destination git
|
||||
repository already exists it will force-reset it to resemble a clone of the
|
||||
remote.</p>
|
||||
|
||||
<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>
|
||||
|
||||
<p><strong>CAUTION</strong>: If the repository exists, this will destroy <em>all</em> local work:
|
||||
changed files will be reset, local branches and other remotes will be removed.</p>
|
||||
|
||||
<h2 id="PROCESS">PROCESS</h2>
|
||||
|
||||
<p>If <code>target-directory</code> doesn't exist or isn't a git repository then the
|
||||
arguments will simply be passed through to <code>git clone</code>.</p>
|
||||
|
||||
<p>If <code>target-directory</code> exists and is a git repository then this will:</p>
|
||||
|
||||
<ul>
|
||||
<li>Remove all remotes</li>
|
||||
<li>Set the origin remote to <code>{remote_url}</code> and fetch the remote</li>
|
||||
<li>Discover the default branch, if no branch was specified</li>
|
||||
<li>Check out the selected branch</li>
|
||||
<li>Delete all other local branches</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="OPTIONS">OPTIONS</h2>
|
||||
|
||||
<p><code>{remote_url}</code> - The URL for a git remote repository of which to make a clone.
|
||||
<code>{destination_path}</code> - A path to the local git repository location to clone into.
|
||||
<code>--branch {branch_name}</code> - After cloning, checkout this branch.</p>
|
||||
|
||||
<h2 id="EXAMPLES">EXAMPLES</h2>
|
||||
|
||||
<p><code>git-force-clone -b master git@github.com:me/repo.git ./repo_dir</code></p>
|
||||
|
||||
<h2 id="AUTHOR">AUTHOR</h2>
|
||||
|
||||
<p>Written by Robin Winslow <a href="mailto:robin@robinwinslow.co.uk" data-bare-link="true">robin@robinwinslow.co.uk</a>.</p>
|
||||
|
||||
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
|
||||
|
||||
<p><a href="https://github.com/tj/git-extras/issues" data-bare-link="true">https://github.com/tj/git-extras/issues</a></p>
|
||||
|
||||
<h2 id="SEE-ALSO">SEE ALSO</h2>
|
||||
|
||||
<p><a href="https://github.com/tj/git-extras" data-bare-link="true">https://github.com/tj/git-extras</a></p>
|
||||
|
||||
|
||||
<ol class='man-decor man-foot man foot'>
|
||||
<li class='tl'></li>
|
||||
<li class='tc'>2016-10-29</li>
|
||||
<li class='tr'>git-force-clone(1)</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
56
man/git-force-clone.md
Normal file
56
man/git-force-clone.md
Normal file
|
|
@ -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 git
|
||||
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 or isn't a git repository then the
|
||||
arguments will simply be passed through to `git clone`.
|
||||
|
||||
If `target-directory` exists and is a git repository 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 local git repository location to clone into.
|
||||
`--branch {branch_name}` - After cloning, checkout this branch.
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
`git-force-clone -b master git@github.com:me/repo.git ./repo_dir`
|
||||
|
||||
## AUTHOR
|
||||
|
||||
Written by Robin Winslow <robin@robinwinslow.co.uk>.
|
||||
|
||||
## REPORTING BUGS
|
||||
|
||||
<https://github.com/tj/git-extras/issues>
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
<https://github.com/tj/git-extras>
|
||||
Loading…
Reference in a new issue