diff --git a/.gitignore b/.gitignore index 7567c757ac02695448c2261b78265f9ffc03dae7..d7b62d259e31fa883396a50f7c98df38780996d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -vcsh.1 *.patch *.swp +.swp *.bak diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 2dad8ed3f7ed610fac2812cbe68730758925e629..cbb144acb3f0530feb6874aa3baa2921d2e6c92b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -3,19 +3,27 @@ Auto-generated from tools/list_CONTRIBUTORS. Eric Bouchut <ebouchut@gmail.com> Dridi Boukelmoune <dridi.boukelmoune@gmail.com> +Rob Cornish <jrmcornish@gmail.com> Vincent Demeester <vincent@demeester.fr> Thomas Ferris Nicolaisen <tfnico@gmail.com> martin f. krafft <madduck@madduck.net> Alessandro Ghedini <alessandro@ghedini.me> +Mikhail Gusarov <dottedmag@dottedmag.net> Valentin Haenel <valentin.haenel@gmx.de> Richard Hartmann <richih@debian.org> Gregor Jasny <gjasny@googlemail.com> +Errietta Kostala <errietta@errietta.me> Caleb Maclennan <caleb@alerque.com> +Markus Martin <markus@archwyrm.net> mek-apelsin <mek@pels.in> Evan Pitstick <nerdx00@gmail.com> Dieter Plaetinck <dieter@plaetinck.be> Corey Quinn <corey@sequestered.net> +Pavlos Ratis <dastergon@gentoo.org> Gernot Schulz <post@gernot-schulz.com> +Dato Simó <dato@net.com.org.es> Alexander Skurikhin <a.skurihin@gmail.com> Jonathan Sternberg <jonathansternberg@gmail.com> Frank Terbeck <ft@bewatermyfriend.org> +Aaron VonderHaar <gruen0aermel@gmail.com> +Tony <zearin@gonk.net> diff --git a/Makefile b/Makefile index 4ae8d889c5f1bd35c5fc915426e008418507d881..b40c618fa851f98247fa8840679ecbbb2bf606a4 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ RONN ?= ronn self=vcsh manpages=$(self).1 -all=test manpages +all=test all: $(all) diff --git a/README.md b/README.md index 57f56ed773586ae1becf75c2549d694b1c179041..785b36ca83348a59198671c10f8ca5e091932fee 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ directory. They all maintain their working trees without clobbering each other or interfering otherwise. By default, all Git repositories maintained via `vcsh` store the actual files in `$HOME` but you can override this setting if you want to. + All this means that you can have one repository per application or application family, i.e. `zsh`, `vim`, `ssh`, etc. This, in turn, allows you to clone custom sets of configurations onto different machines or even for different @@ -64,9 +65,11 @@ All slides, videos, and further information can be found There are three different ways to interact with `vcsh` repositories; this section will only show the simplest and easiest way. + Certain more advanced use cases require the other two ways, but don't worry about this for now. If you never even bother playing with the other two modes you will still be fine. + `vcsh enter` and `vcsh run` will be covered in later sections. @@ -111,18 +114,17 @@ symbolic links in `$HOME`; it puts the actual files right into `$HOME`. As `vcsh` allows you to put an arbitrary number of distinct repositories into your `$HOME`, you will end up with a lot of repositories very quickly. -To manage both `vcsh` and other repositories, we suggest using [mr](mr). `mr` -takes care of pulling in and pushing out new data for a variety of version -control systems. +`vcsh` was designed with [myrepos][myrepos], a tool to manage Multiple +Repositories, in mind and the two integrate very nicely. The myrepos tool +(`mr`) has native support for `vcsh` repositories and the configuration for +myrepos is just another set of files that you cat track with `vcsh` like any +other. This makes setting up any new machine a breeze. It can take literally +less than five minutes to go from standard installation to fully set up system. -`vcsh` was designed with [mr][mr], a tool to manage Multiple Repositories, in -mind and the two integrate very nicely. `mr` has native support for `vcsh` -repositories and to `vcsh`, `mr` is just another configuration to track. -This make setting up any new machine a breeze. It takes literally less than -five minutes to go from standard installation to fully set up system - -This is where `mr` comes in. While the use of `mr` is technically -optional, but it will be an integral part of the proposed system that follows. +We suggest using [myrepos][myrepos] to manage both `vcsh` and other repositories. The +`mr` utility takes care of pulling in and pushing out new data for a variety of +version control systems. While the use of myrepos is technically optional, it will +be an integral part of the proposed system that follows. ## Default Directory Layout @@ -162,14 +164,14 @@ To illustrate, this is what a possible directory structure looks like. ### available.d -The files you see in $XDG\_CONFIG\_HOME/mr/available.d are mr configuration files -that contain the commands to manage (checkout, update etc.) a single -repository. vcsh repo configs end in .vcsh, git configs end in .git, etc. This -is optional and your preference. For example, this is what a zsh.vcsh -with read-only access to my zshrc repo looks likes. I.e. in this specific -example, push can not work as you will be using the author's repository. This -is for demonstration, only. Of course, you are more than welcome to clone from -this repository and fork your own. +The files you see in $XDG\_CONFIG\_HOME/mr/available.d are myrepos +configuration files that contain the commands to manage (checkout, update +etc.) a single repository. vcsh repo configs end in .vcsh, git configs end +in .git, etc. This is optional and your preference. For example, this is +what a zsh.vcsh with read-only access to my zshrc repo looks likes. I.e. in +this specific example, push can not work as you will be using the author's +repository. This is for demonstration, only. Of course, you are more than +welcome to clone from this repository and fork your own. [$XDG_CONFIG_HOME/vcsh/repo.d/zsh.git] checkout = vcsh clone 'git://github.com/RichiH/zshrc.git' zsh @@ -181,7 +183,7 @@ this repository and fork your own. ### config.d $XDG\_CONFIG\_HOME/mr/available.d contains *all available* repositories. Only -files/links present in mr/config.d, however, will be used by mr. That means +files/links present in mr/config.d, however, will be used by myrepos. That means that in this example, only the zsh, gitconfigs, tmux and vim repositories will be checked out. A simple `mr update` run in $HOME will clone or update those four repositories listed in config.d. @@ -201,8 +203,9 @@ $XDG\_CONFIG\_HOME/vcsh/repo.d is the directory where all git repositories which are under vcsh's control are located. Since their working trees are configured to be in $HOME, the files contained in those repositories will be put in $HOME directly. -Of course, [mr] [mr] will work with this layout if configured according to this -document (see above). + +Of course, [myrepos][myrepos] will work with this layout if configured according to +this document (see above). vcsh will check if any file it would want to create exists. If it exists, vcsh will throw a warning and exit. Move away your old config and try again. @@ -214,17 +217,17 @@ Optionally, merge your local and your global configs afterwards and push with To illustrate further, the following steps could move your desired configuration to a new host. -1. Clone the mr repository (containing available.d, config.d etc.); for +1. Clone the myrepos repository (containing available.d, config.d etc.); for example: `vcsh clone git://github.com/RichiH/vcsh_mr_template.git mr` 2. Choose your repositories by linking them in config.d (or go with the default you may have already configured by adding symlinks to git). -3. Run mr to clone the repositories: `cd; mr update`. +3. Run myrepos to clone the repositories: `cd; mr update`. 4. Done. Hopefully the above could help explain how this approach saves time by 1. making it easy to manage, clone and update a large number of repositories - (thanks to mr) and + (thanks to myrepos) and 2. making it unnecessary to create symbolic links in $HOME (thanks to vcsh). If you want to give vcsh a try, follow the instructions below. @@ -255,16 +258,16 @@ Make sure none of the following files and directories exist for your test All of the files are part of the template repository, the directory is where the template will be stored. - apt-get install mr - ### Install vcsh #### Debian -If you are using Debian Squeeze, you will need to enable backports. -From Wheezy onwards, you can install it directly: +If you are using Debian Squeeze, you will need to enable backports and the +package name for myrepos will be 'mr'. + +From Wheezy onwards, you can install both directly: - apt-get install vcsh + apt-get install myrepos vcsh #### Gentoo @@ -272,28 +275,49 @@ To install vcsh in Gentoo Linux just give the following command as root: emerge dev-vcs/vcsh +Note the portage package for myrepos still has the old project name: + + emerge dev-vcs/mr + #### Arch Linux -vcsh is availabe via [AUR](https://aur.archlinux.org/packages.php?ID=54164) -and further documentation about the use of AUR is available -[on Arch's wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository). +vcsh is available via this [AUR](https://aur.archlinux.org/packages/vcsh/) +package. Likewise myrepos is available [here](https://aur.archlinux.org/packages/myrepos/). +You may install both useing your favorite AUR helper. e.g. with yaourt: + + yaourt -Sya myrepos vcsh - cd /var/abs/local/ - wget https://aur.archlinux.org/packages/vc/vcsh-git/vcsh-git.tar.gz - tar xfz vcsh-git.tar.gz - cd vcsh-git - makepkg -s - pacman -U vcsh*.pkg.tar.xz +Or you can do it yourself manually using the documentation on installing AUR packages +[on Arch's wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages). + +If you prefer to use the devel package that installs the git HEAD version it +is available [here](https://aur.archlinux.org/packages/vcsh-git/). + +#### Mac OSX + +Formulas are available for vcsh as well as git and myrepos through [homebrew](http://brew.sh). The +vcsh formula is set to depend on myrepos, so you only need one install command: + + brew install vcsh #### From source +To install the latest version from git: + # choose a location for your checkout mkdir -p ~/work/git cd ~/work/git git clone git://github.com/RichiH/vcsh.git cd vcsh - sudo ln -s vcsh /usr/local/bin # or add it to your PATH - cd + sudo ln -s vcsh /usr/local/bin # or add it to your PATH + +For myrepos: + + # use checkout location from above + cd ~/work/git + git clone git://myrepos.branchable.com/ myrepos + cd myrepos + make install #### Clone the Template @@ -354,14 +378,14 @@ copy mine verbatim, either is fine. sudo ln -s ~/work/git/vcsh/vcsh /usr/bin/local hash -r -Grab my mr config. see below for details on how I set this up +Grab my myrepos config. see below for details on how I set this up vcsh clone ssh://<remote>/mr.git cd $XDG_CONFIG_HOME/mr/config.d/ ln -s ../available.d/* . -mr is used to actually retrieve configs, etc +myrepos is used to actually retrieve configs, etc ~ % cat ~/.mrconfig [DEFAULT] @@ -379,7 +403,7 @@ mr is used to actually retrieve configs, etc ~ % mr -j 5 up -# mr usage ; will be factored out & rewritten +# myrepos usage ; will be factored out & rewritten ### Keeping repositories Up-to-Date @@ -399,11 +423,11 @@ and `git commit`, use the vcsh wrapper (like above): vcsh foo commit vcsh foo push -### Using vcsh without mr +### Using vcsh without myrepos -vcsh encourages you to use [mr][mr]. It helps you manage a large number of +vcsh encourages you to use [myrepos][myrepos]. It helps you manage a large number of repositories by running the necessary vcsh commands for you. You may choose not -to use mr, in which case you will have to run those commands manually or by +to use myrepos, in which case you will have to run those commands manually or by other means. @@ -418,7 +442,7 @@ with `vcsh run $repository_name`. For example: vcsh zsh add .zshrc vcsh zsh commit -Obviously, without mr keeping repositories up-to-date, it will have to be done +Obviously, without myrepos keeping repositories up-to-date, it will have to be done manually. Alternatively, you could try something like this: for repo in `vcsh list`; do @@ -438,7 +462,7 @@ community around the general idea of version controlling your (digital) life. * Pull requests or issues on [https://github.com/RichiH/vcsh][vcsh] -[mr]: http://kitenet.net/~joey/code/mr/ +[myrepos]: http://myrepos.branchable.com/ [talks]: http://richardhartmann.de/talks/ [vcsh]: https://github.com/RichiH/vcsh [vcs-home-list]: http://lists.madduck.net/listinfo/vcs-home diff --git a/changelog b/changelog index dc578c6f6686ca8d107bc505f22d41b07543bfab..b5d6e781d69660d80d5796071733dacefbfddbc2 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,16 @@ +2014-03-13 Richard Hartmann <richih.mailinglist@gmail.com> + + * Release 1.20140313 -- the "Git won a prize" edition + * Initialize repos with --shared=0600 + * Fix cloning from some spefically-named remotes + * Support custom gitattribute files + * Support filenames with whitespace in gitignores + * Pass out git exit codes + * Switch to static, pre-built manpage + * Improve documentation + * Use more portable find(1) syntax + * Various minor improvements + 2013-12-29 Richard Hartmann <richih.mailinglist@gmail.com> * Release 1.20131229 diff --git a/doc/hooks b/doc/hooks index 54ff795611c0081e11eca8d16064f0f57f2ac60e..282ee86265c765c7a457234931aaed000ae913aa 100644 --- a/doc/hooks +++ b/doc/hooks @@ -14,6 +14,12 @@ Available hooks are: * post-enter * pre-init * post-init +* pre-merge + Use this hook to detect and handle merge conflicts before vcsh's native code + finds and errors on them. This is useful for allowing clones on top of existing + files. +* post-merge + Use this hook to finish handling any merge conflicts found in the pre-merge hook. * pre-pull * post-pull * pre-push diff --git a/doc/sample_hooks/post-merge-unclobber b/doc/sample_hooks/post-merge-unclobber new file mode 100755 index 0000000000000000000000000000000000000000..2b8f286053b445324ae31694f8559c6b90a130b0 --- /dev/null +++ b/doc/sample_hooks/post-merge-unclobber @@ -0,0 +1,10 @@ +#!/bin/sh + +# This finds objects that the pre-merge script moved out of the way to +# avoid conflicts when running `vcsh clone` and moves them back to their +# original places. The result is that the Git repository gets checked out +# without error and the pre-existing files end up back in the working +# directory. Git and thus vcsh now see these as un-staged changes to the +# working branch and you can deal with them as usual. + +find . -name '*.vcsh-unclobber' -execdir rename .vcsh-unclobber '' {} \; diff --git a/doc/sample_hooks/pre-merge-unclobber b/doc/sample_hooks/pre-merge-unclobber new file mode 100755 index 0000000000000000000000000000000000000000..52610962e611b9bafde5c3fe5f2f70423ed91c39 --- /dev/null +++ b/doc/sample_hooks/pre-merge-unclobber @@ -0,0 +1,11 @@ +#!/bin/sh + +# This code does amost exactly what the native vcsh sanity checking code +# does except that on finding a potential merge conflict, it moves existing +# files out of the way temporarily. Merging (part of `vcsh clone`) happens +# cleanly, and a post-merge hook can be used to figure out what to do with +# the now-renamed files. + +for object in $(git ls-tree -r origin/master | awk '{print $4}'); do + [ -e "$object" ] && mv "$object" "$object.vcsh-unclobber" +done diff --git a/doc/vcsh.1.ronn b/doc/vcsh.1.ronn index 56df4ed26e74cdbb7a4109056b8415570843d846..05da4fad8bfe18dce47ab8aaa2c3dc9f9c619275 100644 --- a/doc/vcsh.1.ronn +++ b/doc/vcsh.1.ronn @@ -171,6 +171,15 @@ executed in the context of your shell. Interesting knobs you can turn: +* <$VCSH_GITATTRIBUTES>: + Can be <none>, or any other value. + + <none> will not maintain Git attributes in a special location. + + If set to any other value, repo-specific gitattributes files will be maintained. + + Defaults to <none>. + * <$VCSH_GITIGNORE>: Can be <exact>, <none>, or <recursive>. diff --git a/vcsh b/vcsh index 9f413f6c67fa1c468c07259ed29e768c0f2c298b..d39f41581da5ab93442e7073bd6eb3189730d571 100755 --- a/vcsh +++ b/vcsh @@ -15,8 +15,12 @@ # This should always be the first line of code to facilitate debugging [ -n "$VCSH_DEBUG" ] && set -vx + +# If '.git-HEAD' is appended to the version, you are seeing an unreleased +# version of vcsh; the master branch is supposed to be clean at all times +# so you can most likely just use it nonetheless +VERSION='1.20140313' SELF=$(basename $0) -VERSION='1.20131229' fatal() { echo "$SELF: fatal: $1" >&2 @@ -70,9 +74,10 @@ fi # Read defaults : ${VCSH_REPO_D:=$XDG_CONFIG_HOME/vcsh/repo.d} -: ${VCSH_HOOK_D:=$XDH_CONFIG_HOME/vcsh/hooks-enabled} +: ${VCSH_HOOK_D:=$XDG_CONFIG_HOME/vcsh/hooks-enabled} : ${VCSH_BASE:=$HOME} : ${VCSH_GITIGNORE:=exact} +: ${VCSH_GITATTRIBUTES:=none} : ${VCSH_WORKTREE:=absolute} if [ ! "x$VCSH_GITIGNORE" = 'xexact' ] && [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && [ ! "x$VCSH_GITIGNORE" = 'xrecursive' ]; then @@ -148,15 +153,17 @@ clone() { exit fi git fetch - for object in $(git ls-tree -r origin/master | awk '{print $4}'); do + hook pre-merge + git ls-tree -r --name-only origin/master | (while read object; do [ -e "$object" ] && error "'$object' exists." && VCSH_CONFLICT=1 done - [ "$VCSH_CONFLICT" = '1' ] && + [ "$VCSH_CONFLICT" = '1' ]) && fatal "will stop after fetching and not try to merge! Once this situation has been resolved, run 'vcsh run $VCSH_REPO_NAME git pull' to finish cloning." 17 git merge origin/master + hook post-merge hook post-clone retire hook post-clone-retired @@ -169,6 +176,7 @@ commit() { export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" use git commit --untracked-files=no --quiet + VCSH_COMMAND_RETURN_CODE=$? echo done hook post-commit @@ -217,7 +225,7 @@ init() { [ ! -e "$GIT_DIR" ] || fatal "'$GIT_DIR' exists" 10 mkdir -p "$VCSH_BASE" || fatal "could not create '$VCSH_BASE'" 50 cd "$VCSH_BASE" || fatal "could not enter '$VCSH_BASE'" 11 - git init + git init --shared=0600 upgrade hook post-init } @@ -251,6 +259,7 @@ pull() { export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" use git pull + VCSH_COMMAND_RETURN_CODE=$? echo done hook post-pull @@ -263,6 +272,7 @@ push() { export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" use git push + VCSH_COMMAND_RETURN_CODE=$? echo done hook post-push @@ -289,6 +299,7 @@ run() { hook pre-run use "$@" + VCSH_COMMAND_RETURN_CODE=$? hook post-run } @@ -297,12 +308,14 @@ status() { export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" use git status --short --untracked-files='no' + VCSH_COMMAND_RETURN_CODE=$? else for VCSH_REPO_NAME in $(list); do echo "$VCSH_REPO_NAME:" export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" use git status --short --untracked-files='no' + VCSH_COMMAND_RETURN_CODE=$? echo done fi @@ -322,9 +335,11 @@ upgrade() { git config core.worktree "$VCSH_BASE" fi [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && git config core.excludesfile ".gitignore.d/$VCSH_REPO_NAME" - git config vcsh.vcsh 'true' + [ ! "x$VCSH_GITATTRIBUTES" = 'xnone' ] && git config core.attributesfile ".gitattributes.d/$VCSH_REPO_NAME" + git config vcsh.vcsh 'true' use [ -e "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" ] && git add -f "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" + [ -e "$VCSH_BASE/.gitattributes.d/$VCSH_REPO_NAME" ] && git add -f "$VCSH_BASE/.gitattributes.d/$VCSH_REPO_NAME" hook post-upgrade } @@ -350,6 +365,8 @@ write_gitignore() { use cd "$VCSH_BASE" || fatal "could not enter '$VCSH_BASE'" 11 + OLDIFS="$IFS" + IFS=$(printf '\n\t') gitignores=$(for file in $(git ls-files); do while true; do echo $file; new="${file%/*}" @@ -370,6 +387,7 @@ write_gitignore() { { echo "$gitignore/*" | sed 's@^@!/@' >> "$tempfile" || fatal "could not write to '$tempfile'" 57; } fi done + IFS="$OLDIFS" if diff -N "$tempfile" "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" > /dev/null; then rm -f "$tempfile" || error "could not delete '$tempfile'" exit @@ -383,7 +401,7 @@ write_gitignore() { fatal "could not move '$tempfile' to '$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME'" 53 } -debug `git version` +debug $(git version) if [ ! "x$VCSH_GITIGNORE" = 'xexact' ] && [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && [ ! "x$VCSH_GITIGNORE" = 'xrecursive' ]; then fatal "'\$VCSH_GITIGNORE' must equal 'exact', 'none', or 'recursive'" 1 @@ -412,7 +430,7 @@ esac if [ "$VCSH_COMMAND" = 'clone' ]; then [ -z "$2" ] && fatal "$VCSH_COMMAND: please specify a remote" 1 GIT_REMOTE="$2" - [ -n "$3" ] && VCSH_REPO_NAME="$3" || VCSH_REPO_NAME=$(basename "$GIT_REMOTE" .git) + [ -n "$3" ] && VCSH_REPO_NAME="$3" || VCSH_REPO_NAME=$(basename "${GIT_REMOTE#*:}" .git) [ -z "$VCSH_REPO_NAME" ] && fatal "$VCSH_COMMAND: could not determine repository name" 1 export VCSH_REPO_NAME export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" @@ -486,6 +504,7 @@ check_dir() { check_dir "$VCSH_REPO_D" [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && check_dir "$VCSH_BASE/.gitignore.d" +[ ! "x$VCSH_GITATTRIBUTES" = 'xnone' ] && check_dir "$VCSH_BASE/.gitattributes.d" verbose "$VCSH_COMMAND begin" export VCSH_COMMAND=$(echo $VCSH_COMMAND | sed 's/-/_/g') @@ -493,3 +512,4 @@ hook pre-command $VCSH_COMMAND "$@" hook post-command verbose "$VCSH_COMMAND end, exiting" +exit $VCSH_COMMAND_RETURN_CODE diff --git a/vcsh.1 b/vcsh.1 new file mode 100644 index 0000000000000000000000000000000000000000..4c77838c2fca10ffd27c9e0cb87c05fed88d8ffc --- /dev/null +++ b/vcsh.1 @@ -0,0 +1,347 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "VCSH" "1" "March 2014" "" "" +. +.SH "NAME" +\fBvcsh\fR \- Version Control System for $HOME \- multiple Git repositories in $HOME +. +.SH "SYNOPSIS" +\fBvcsh\fR [\fIoptions\fR] \fIcommand\fR +. +.P +\fBvcsh\fR clone \fIurl\fR [\fIrepo\fR] +. +.P +\fBvcsh\fR delete \fIrepo\fR +. +.P +\fBvcsh\fR enter \fIrepo\fR +. +.P +\fBvcsh\fR help +. +.P +\fBvcsh\fR init \fIrepo\fR +. +.P +\fBvcsh\fR list +. +.P +\fBvcsh\fR list\-tracked +. +.P +\fBvcsh\fR list\-tracked\-by \fIrepo\fR +. +.P +\fBvcsh\fR pull +. +.P +\fBvcsh\fR push +. +.P +\fBvcsh\fR rename \fIrepo\fR \fInewname\fR +. +.P +\fBvcsh\fR run \fIrepo\fR \fIshell command\fR +. +.P +\fBvcsh\fR status [\fIrepo\fR] +. +.P +\fBvcsh\fR upgrade \fIrepo\fR +. +.P +\fBvcsh\fR version +. +.P +\fBvcsh\fR which \fIsubstring\fR +. +.P +\fBvcsh\fR write\-gitignore \fIrepo\fR +. +.P +\fBvcsh\fR \fIrepo\fR \fIgit command\fR +. +.P +\fBvcsh\fR \fIrepo\fR +. +.SH "DESCRIPTION" +\fBvcsh\fR allows you to have several \fBgit\fR(1) repositories, all maintaining their working trees in $HOME without clobbering each other\. That, in turn, means you can have one repository per config set (zsh, vim, ssh, etc), picking and choosing which configs you want to use on which machine\. +. +.P +\fBvcsh\fR is using a technique called fake bare Git repositories, keeping \fI$GIT_DIR\fR in a different directory from \fI$GIT_WORK_TREE\fR which is pointed to \fI$HOME\fR\. +. +.P +The use of symlinks is not needed in this setup, making for a cleaner setup\. +. +.P +\fBvcsh\fR was designed with \fBmr\fR(1) in mind so you might want to install it alongside vcsh\. That being said, you can easily use \fBvcsh\fR without \fBmr\fR if you prefer\. +. +.P +A sample configuration for \fBvcsh\fR and \fBmr\fR can be found at \fIhttps://github\.com/RichiH/vcsh_mr_template\fR and used with \fBvcsh clone https://github\.com/RichiH/vcsh_mr_template mr\fR\. +. +.P +Please note that you can always use a path instead of a name for \fIrepo\fR\. This is needed to support mr and other scripts properly and of no concern to an interactive user\. +. +.SH "OPTIONS" +. +.TP +\-c +Source \fIfile\fR prior to other configuration files +. +.TP +\-d +Enable debug mode +. +.TP +\-v +Enable verbose mode +. +.SH "COMMANDS" +. +.TP +clone +Clone an existing repository\. +. +.IP +If you need to clone a bundle of repositories, look into the \fBpost\-clone\-retired\fR hook\. +. +.TP +commit +Commit in all repositories +. +.TP +delete +Delete an existing repository\. +. +.TP +enter +Enter repository; spawn new \fI$SHELL\fR\. +. +.TP +help +Display help\. +. +.TP +init +Initialize an empty repository\. +. +.TP +list +List all local vcsh repositories\. +. +.TP +list\-tracked +List all files tracked by vcsh\. +. +.TP +list\-tracked\-by +List files tracked by a repository\. +. +.TP +pull +Pull from all vcsh remotes\. +. +.TP +push +Push to all vcsh remotes\. +. +.TP +rename +Rename a repository\. +. +.TP +run +Run command with \fI$GIT_DIR\fR and \fI$GIT_WORK_TREE\fR set\. Allows you to run any and all commands without any restrictions\. Use with care\. +. +.IP +Please note that there is a somewhat magic feature for run\. Instead of \fIrepo\fR it accepts \fIpath\fR, as well\. Anything that has a slash in it will be assumed to be a path\. \fBvcsh run\fR will then operate on this directory instead of the one normally generated from the repository\'s name\. This is needed to support mr and other scripts properly and of no concern to an interactive user\. +. +.TP +status +Show statuses of all/one vcsh repositories\. +. +.TP +upgrade +Upgrade repository to currently recommended settings\. +. +.TP +version +Print version information\. +. +.TP +which \fIsubstring\fR +Find \fIsubstring\fR in name of any tracked file\. +. +.TP +write\-gitignore +Write \.gitignore\.d/\fIrepo\fR via \fBgit ls\-files\fR\. +. +.TP +\fIrepo\fR \fIgitcommand\fR +Shortcut to run \fBvcsh\fR on a repo\. Will prepend \fBgit\fR to \fIcommand\fR\. +. +.TP +\fIrepo\fR +Shortcut to run \fBvcsh enter <repo>\fR\. +. +.SH "ENVIRONMENT" +As noted earlier, \fBvcsh\fR will set \fI$GIT_DIR\fR and \fI$GIT_WORK_TREE\fR to the appropriate values for fake bare Git repositories\. +. +.SH "CONFIG" +There are several ways to turn the various knobs on \fBvcsh\fR\. In order of ascending precedence, they are: +. +.IP "\(bu" 4 +\fBVARIABLE=foo vcsh\fR +. +.IP "\(bu" 4 +</etc/vcsh/config> +. +.IP "\(bu" 4 +<$XDG_CONFIG_HOME/vcsh/config> +. +.IP "\(bu" 4 +\fBvcsh \-c <file>\fR +. +.IP "" 0 +. +.P +Please note that those files are sourced\. Any and all commands will be executed in the context of your shell\. +. +.P +Interesting knobs you can turn: +. +.TP +\fI$VCSH_GITATTRIBUTES\fR +Can be \fInone\fR, or any other value\. +. +.IP +\fInone\fR will not maintain Git attributes in a special location\. +. +.IP +If set to any other value, repo\-specific gitattributes files will be maintained\. +. +.IP +Defaults to \fInone\fR\. +. +.TP +\fI$VCSH_GITIGNORE\fR +Can be \fIexact\fR, \fInone\fR, or \fIrecursive\fR\. +. +.IP +\fIexact\fR will seed the repo\-specific ignore file with all file and directory names which \fBgit ls\-files\fR returns\. +. +.IP +\fInone\fR will not write any ignore file\. +. +.IP +\fIrecursive\fR will descend through all directories recursively additionally to the above\. +. +.IP +Defaults to \fIexact\fR\. +. +.TP +\fI$VCSH_VCSH_WORKTREE\fR +Can be \fIabsolute\fR, or \fIrelative\fR\. +. +.IP +\fIabsolute\fR will set an absolute path; defaulting to \fI$HOME\fR\. +. +.IP +\fIrelative\fR will set a path relative to \fI$GIT_DIR\fR\. +. +.IP +Defaults to \fIabsolute\fR\. +. +.P +Less interesting knobs you could turn: +. +.TP +\fI$VCSH_DEBUG\fR +Enter debug mode\. +. +.TP +\fI$XDG_CONFIG_HOME\fR +As specified in the \'XDG Base Directory Specification\', see \fIhttp://standards\.freedesktop\.org/basedir\-spec/basedir\-spec\-latest\.html\fR +. +.IP +Defaults to <$HOME/\.config>\. +. +.TP +\fI$VCSH_REPO_D\fR +The directory where repositories are read from and stored\. +. +.IP +Defaults to <$XDG_CONFIG_HOME/vcsh/repo\.d>\. +. +.TP +\fI$VCSH_HOOK_D\fR +The directory where hooks are read from\. +. +.IP +Defaults to <$XDG_CONFIG_HOME/vcsh/hooks\-enabled>\. +. +.TP +\fI$VCSH_BASE\fR +The directory where repositories are checked out to\. +. +.IP +Defaults to \fI$HOME\fR\. +. +.SH "HOOK SYSTEM" +\fBvcsh\fR provides a hook system\. Hook scripts must be executable and should be placed in <$XDG_CONFIG_HOME/vcsh/hooks\-available>\. From there, they can be soft\-linked into <$XDG_CONFIG_HOME/vcsh/hooks\-enabled>; \fBvcsh\fR will only execute hooks that are in this directory\. +. +.P +Hooks follow a simple format\. \fIpre\-run\fR will be run before anything is run\. If you want to have more than one script for a certain hook, just append any kind of string to order them\. A system of \fIpre\-run\fR, <pre\-run\.10>, <pre\-run\.20> etc is suggested; other options would be \fIpre\-run\-10\fR or <pre\-run\.sh>\. A dot after the hook name is optional\. +. +.P +If you want to create hooks for a specific \fIvcsh\fR repository, simply prepend the repository\'s name, followed by a dot, i\.e\. <zsh\.pre\-run>\. Otherwise, the same rules as above apply\. The dot between the repository\'s name and the hook is mandatory, though\. +. +.P +Available hooks are \fIpre\-clone\fR, \fIpost\-clone\fR, \fIpost\-clone\-retired\fR, \fIpre\-command\fR, \fIpost\-command\fR, \fIpre\-enter\fR, \fIpost\-enter\fR, \fIpre\-init\fR, \fIpost\-init\fR, \fIpre\-pull\fR, \fIpost\-pull\fR, \fIpre\-push\fR, \fIpost\-push\fR, \fIpre\-run\fR, \fIpost\-run\fR, \fIpre\-upgrade\fR, and \fIpost\-upgrade\fR\. If you need more, vcsh is trivial to patch, but please let upstream know so we can ship them by default\. +. +.SH "DETAILED HOWTO AND FURTHER READING" +Manpages are often short and sometimes useless to glean best practices from\. While the author tried to avoid this in this case, manpages can not cover detailed howtos\. +. +.P +This software also comes with a file called <README\.md>\. It contains various approaches to setting up and using vcsh\. You can view the file it as plain text or render it into various other formats via Markdown\. +. +.P +On Debian\-based systems, this file can be found in </usr/share/doc/vcsh>\. +. +.SH "SECURITY CONSIDERATIONS" +\fBvcsh\fR allows you to execute arbitrary commands via \fBvcsh run\fR\. For example, adding a \fBsudo\fR(8) rule for \fBvcsh\fR would be pretty stupid\. +. +.P +Additionally, vcsh will source, i\.e\. execute, all files listed in \fICONFIG\fR\. You can put any and all commands into these config files and they will be executed\. +. +.SH "BUGS" +None are known at this time, but reports and/or patches are more than welcome\. +. +.SH "INTEROPERABILITY" +If you rely on \fBgit submodule\fR use \fBgit\fR 1\.7\.12 or later\. Earlier versions do not clean internal variables properly before descending into submodules, resulting in unhappy end users\. +. +.SH "HISTORY" +Like most people, the author initially made do with a single repository for all config files, all of which were soft\-linked into \fI$HOME\fR\. +. +.P +Martin F\. Krafft aka madduck came up with the concept of fake bare Git repositories\. +. +.P +vcsh was initally written by madduck\. This version is a re\-implementation from scratch with a lot more features\. madduck graciously agreed to let the author take over the name\. +. +.SH "AUTHOR" +This manpage and \fBvcsh\fR itself were written by Richard "RichiH" Hartmann\. +. +.SH "COPYRIGHT" +Copyright 2011\-2013 Richard Hartmann \fIrichih@debian\.org\fR +. +.P +Licensed under the GNU GPL version 2 or higher\. +. +.P +https://github\.com/RichiH/vcsh +. +.SH "SEE ALSO" +\fBgit\fR(1), \fBmr\fR(1)