Skip to content

Commit

Permalink
git-force-clone
Browse files Browse the repository at this point in the history
All files for git-force-clone, a command for overwriting local repos when closing repositories.
  • Loading branch information
nottrobin committed Oct 28, 2016
1 parent 779f467 commit 9fe6d7d
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 1 deletion.
16 changes: 16 additions & 0 deletions Commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down
107 changes: 107 additions & 0 deletions bin/git-force-clone
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#! /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
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
(
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: )[^ ]+$'`
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
)
else
git clone -b ${branch} ${remote_url} ${destination_path}
fi
}

main "$@"

exit 0
2 changes: 1 addition & 1 deletion etc/git-extras-completion.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ _git-feature() {
esac
}


_git-graft() {
_arguments \
':src-branch-name:__gitex_branch_names' \
Expand Down Expand Up @@ -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' \
Expand Down
57 changes: 57 additions & 0 deletions man/git-force-clone.1
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
Empty file added man/git-force-clone.html
Empty file.
56 changes: 56 additions & 0 deletions man/git-force-clone.md
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>

0 comments on commit 9fe6d7d

Please sign in to comment.