diff --git a/.mailmap b/.mailmap index 1e66b4db2c319380410828aa4a5e91530e4775c3..65c64b49bd9b9775e4cd36883013fb6f27833634 100644 --- a/.mailmap +++ b/.mailmap @@ -1,2 +1,4 @@ -Richard Hartmann <richih.mailinglist@gmail.com> <richih+github.com@richih.org> +Richard Hartmann <richih@debian.org> <richih+github.com@richih.org> +Richard Hartmann <richih@debian.org> <richih.mailinglist@gmail.com> +Richard Hartmann <richih@debian.org> <RichiH@users.noreply.github.com> Alexander Skurikhin <a.skurihin@gmail.com> <a.skurihin@gmail.com> diff --git a/CONTRIBUTORS b/CONTRIBUTORS index abea9e09c8fa72f4120dd75aa764ac3fcecdb478..2dad8ed3f7ed610fac2812cbe68730758925e629 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,12 +1,18 @@ -Alphabetical list of everyone who ever committed to this repository +Alphabetical list of surnames of everyone who ever committed to this repository. +Auto-generated from tools/list_CONTRIBUTORS. +Eric Bouchut <ebouchut@gmail.com> +Dridi Boukelmoune <dridi.boukelmoune@gmail.com> Vincent Demeester <vincent@demeester.fr> Thomas Ferris Nicolaisen <tfnico@gmail.com> martin f. krafft <madduck@madduck.net> Alessandro Ghedini <alessandro@ghedini.me> Valentin Haenel <valentin.haenel@gmx.de> -Richard Hartmann <richih.mailinglist@gmail.com> +Richard Hartmann <richih@debian.org> +Gregor Jasny <gjasny@googlemail.com> +Caleb Maclennan <caleb@alerque.com> mek-apelsin <mek@pels.in> +Evan Pitstick <nerdx00@gmail.com> Dieter Plaetinck <dieter@plaetinck.be> Corey Quinn <corey@sequestered.net> Gernot Schulz <post@gernot-schulz.com> diff --git a/Makefile b/Makefile index cb112c72b619dec628d167f17f75630a99bb34fd..4ae8d889c5f1bd35c5fc915426e008418507d881 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,8 @@ PREFIX=/usr +DOCDIR_PREFIX=$(PREFIX)/share/doc +DOCDIR=$(DOCDIR_PREFIX)/$(self) +ZSHDIR=$(PREFIX)/share/zsh/vendor-completions +RONN ?= ronn self=vcsh manpages=$(self).1 @@ -11,16 +15,16 @@ install: all install -m 0755 $(self) $(DESTDIR)$(PREFIX)/bin install -d $(DESTDIR)$(PREFIX)/share/man/man1 install -m 0644 $(manpages) $(DESTDIR)$(PREFIX)/share/man/man1 - install -d $(DESTDIR)$(PREFIX)/share/doc/$(self) - install -m 0644 README.md $(DESTDIR)$(PREFIX)/share/doc/$(self) - install -m 0644 doc/hooks $(DESTDIR)$(PREFIX)/share/doc/$(self) - install -d $(DESTDIR)$(PREFIX)/share/zsh/vendor-completions - install -m 0644 _$(self) $(DESTDIR)$(PREFIX)/share/zsh/vendor-completions + install -d $(DESTDIR)$(DOCDIR) + install -m 0644 README.md $(DESTDIR)$(DOCDIR) + install -m 0644 doc/hooks $(DESTDIR)$(DOCDIR) + install -d $(DESTDIR)$(ZSHDIR) + install -m 0644 _$(self) $(DESTDIR)$(ZSHDIR) manpages: $(manpages) $(self).1: doc/$(self).1.ronn - ronn < doc/$(self).1.ronn > $(self).1 + $(RONN) < doc/$(self).1.ronn > $(self).1 || rm $(self).1 clean: rm -rf $(self).1 @@ -28,19 +32,19 @@ clean: uninstall: rm -rf $(DESTDIR)$(PREFIX)/bin/$(self) rm -rf $(DESTDIR)$(PREFIX)/share/man/man1/$(self).1 - rm -rf $(DESTDIR)$(PREFIX)/share/doc/$(self) - rm -rf $(DESTDIR)$(PREFIX)/share/zsh/vendor-completions/_$(self) + rm -rf $(DESTDIR)$(DOCDIR) + rm -rf $(DESTDIR)$(ZSHDIR)/_$(self) # Potentially harmful, used a non-standard option on purpose. # If PREFIX=/usr/local and that's empty... purge: uninstall rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(PREFIX)/bin/ rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(PREFIX)/share/man/man1/ - rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(PREFIX)/share/doc/ - rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(PREFIX)/share/zsh/vendor-completions/ + rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(DOCDIR_PREFIX) + rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(ZSHDIR) test: - if which git > /dev/null ; then :; else echo "'git' not found, exiting..."; exit 1; fi + @if which git > /dev/null ; then :; else echo "'git' not found, exiting..."; exit 1; fi moo: @if [ -x /usr/games/cowsay ]; then /usr/games/cowsay "I hope you're happy now..."; fi diff --git a/README.md b/README.md index a83325d979ee4482a828111802d7882a4dbe141c..6166a6740c58465cd703192ed2d9269e769bcf41 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,42 @@ vcsh - Version Control System for $HOME - multiple Git repositories in $HOME # Index -1. [Introduction](#introduction) -2. [30 second howto](#30-second-howto) -3. [Overview](#overview) -4. [Getting Started](#getting-started) -5. [Usage Exmaples](#usage-examples) +1. [30 second howto](#30-second-howto) +2. [Introduction](#introduction) +3. [Usage Exmaples](#usage-examples) +4. [Overview](#overview) +5. [Getting Started](#getting-started) 6. [Contact](#contact) +# 30 second howto + +While it may appear that there's an overwhelming amount of documentation and +while the explanation of the concepts behind `vcsh` needs to touch a few gory +details of `git` internals, getting started with `vcsh` is extremely simple. + +Let's say you want to version control your `vim` configuration: + + vcsh init vim + vcsh vim add ~/.vimrc ~/.vim + vcsh vim commit -m 'Initial commit of my Vim configuration' + # optionally push your files to a remote + vcsh vim remote add origin <remote> + vcsh vim push -u origin master + # from now on you can push additional commits like this + vcsh vim push + +If all that looks a _lot_ like standard `git`, that's no coincidence; it's +a design feature. + + # Introduction -[vcsh][vcsh] allows you to maintain several git repositories in one single +[vcsh][vcsh] allows you to maintain several Git repositories in one single directory. They all maintain their working trees without clobbering each other -or interfering otherwise. By default, all git repositories maintained via -`vcsh` are stored in `$HOME` but you can override this setting if you want to. +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 @@ -25,13 +47,7 @@ For example, you may not need to have your `mplayer` configuration on a server or available to root and you may want to maintain different configuration for `ssh` on your personal and your work machines. -`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 - -A lot of modern UNIX-based systems offer pacakges for `vcsh`. In case yours +A lot of modern UNIX-based systems offer packages for `vcsh`. In case yours does not read `INSTALL.md` for install instructions or `PACKAGING.md` to create a package, yourself. If you do end up packaging `vcsh` please let us know so we can give you your own packaging branch in the upstream repository. @@ -39,30 +55,59 @@ can give you your own packaging branch in the upstream repository. ## Talks Some people found it useful to look at slides and videos explaining how `vcsh` -works instead of working through the docs, first. -They can all be found [on the author's talk page][talks]. +works instead of working through the docs. +All slides, videos, and further information can be found +[on the author's talk page][talks]. -# 30 second howto +# Usage Examples -While it may appear that there's an overwhelming amount of documentation and -while the explanation of the concepts behind `vcsh` needs to touch a few gory -details of `git` internals, getting started with `vcsh` is extremely simple. +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. -Let's say you want to version control your `vim` configuration: + +## Initialize a new repository called "vim" vcsh init vim + +## Clone an existing repository + + vcsh clone <remote> <repository_name> + +## Add files to repository "vim" + vcsh vim add ~/.vimrc ~/.vim - vcsh vim commit -m 'Initial commit of my Vim configuration' - # optionally push your files to a remote + vcsh vim commit -m 'Update Vim configuration' + +## Add a remote for repository "vim" + vcsh vim remote add origin <remote> - vcsh vim push -u origin master - # from now on you can push additional commits like this + vcsh vim push origin master:master + vcsh vim branch --track master origin/master + +## Push to remote of repository "vim" + vcsh vim push -If all that looks a _lot_ like standard `git`, that's no coincidence; it's -a design feature. +## Pull from remote of repository "vim" + + vcsh vim pull + +## Show status of changed files in all repositories + vcsh status + +## Pull from all repositories + + vcsh pull + +## Push to all repositories + + vcsh push # Overview @@ -93,9 +138,12 @@ 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 [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 -The last logical step is to maintain all those new repositores with an automated -tool instead of tracking them by hand. 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. @@ -148,10 +196,10 @@ this repository and fork your own. [$XDG_CONFIG_HOME/vcsh/repo.d/zsh.git] checkout = vcsh clone 'git://github.com/RichiH/zshrc.git' zsh - update = vcsh run zsh git pull - push = vcsh run zsh git push - status = vcsh run zsh git status - gc = vcsh run zsh git gc + update = vcsh zsh pull + push = vcsh zsh push + status = vcsh zsh status + gc = vcsh zsh gc ### config.d @@ -168,9 +216,6 @@ you to conveniently run `mr up` etc. to manage all repositories. It looks like this: [DEFAULT] - jobs = 5 - # Use if your mr does not have vcsh support in mainline, yet - include = cat /usr/share/mr/vcsh include = cat ${XDG_CONFIG_HOME:-$HOME/.config}/mr/config.d/* ### repo.d @@ -185,7 +230,7 @@ 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. Optionally, merge your local and your global configs afterwards and push with -`vcsh run foo git push`. +`vcsh foo push`. ## Moving into a New Host @@ -196,10 +241,8 @@ configuration to a new host. 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. Make sure the line 'include = cat /usr/share/mr/vcsh' in .mrconfig points - to an existing file -4. Run mr to clone the repositories: `cd; mr update`. -5. Done. +3. Run mr to clone the repositories: `cd; mr update`. +4. Done. Hopefully the above could help explain how this approach saves time by @@ -260,18 +303,12 @@ and further documentation about the use of AUR is available #### From source -If your version of mr is older than version 1.07, make sure to put - - include = cat /usr/share/mr/vcsh - -into your .mrconfig . - # choose a location for your checkout - cd $HOME mkdir -p ~/work/git + cd ~/work/git git clone git://github.com/RichiH/vcsh.git cd vcsh - ln -s vcsh /usr/local/bin # or add it to your PATH + sudo ln -s vcsh /usr/local/bin # or add it to your PATH cd #### Clone the Template @@ -297,10 +334,10 @@ Now, it's time to edit the template config and fill it with your own remotes: And then create your own stuff: vcsh init foo - vcsh run foo git add -f bar baz quux - vcsh run foo git remote add origin git://quuux - vcsh run foo git commit - vcsh run foo git push + vcsh foo add bar baz quux + vcsh foo remote add origin git://quuux + vcsh foo commit + vcsh foo push cp $XDG_CONFIG_HOME/mr/available.d/mr.vcsh $XDG_CONFIG_HOME/mr/available.d/foo.vcsh vim $XDG_CONFIG_HOME/mr/available.d/foo.vcsh # add your own repo @@ -358,40 +395,6 @@ mr is used to actually retrieve configs, etc ~ % mr -j 5 up -# Usage Examples - -All examples in this section will use the short form of `vcsh` which is the -simplest way to interface with it. If you don't know what that means simply -ignore this fact for now and follow the examples. - -## Initialize a new repository "vim" - - vcsh init vim - -## Clone an existing repository - - vcsh clone <remote> <repository_name> - -## Add files to repository "vim" - - vcsh vim add ~/.vimrc ~/.vim - vcsh vim commit -m 'Update Vim configuration' - -## Add a remote for repository "vim" - - vcsh vim remote add origin <remote> - vcsh vim push origin master:master - vcsh vim branch --track master origin/master - -## Push to remote of repository "vim" - - vcsh vim push - -## Pull from remote of repository "vim" - - vcsh vim pull - - # mr usage ; will be factored out & rewritten ### Keeping repositories Up-to-Date @@ -408,13 +411,9 @@ Neat. After you have made some changes, for which you would normally use `git add` and `git commit`, use the vcsh wrapper (like above): - vcsh run foo git add -f bar baz quux - vcsh run foo git commit - vcsh run foo git push - -By the way, you'll have to use -f/--force flag with git-add because all files -will be ignored by default. This is to show you only useful output when running -git-status. A fix for this problem is being worked on. + vcsh foo add bar baz quux + vcsh foo commit + vcsh foo push ### Using vcsh without mr @@ -431,9 +430,9 @@ To clone a repository: `vcsh clone ssh://<remote>/zsh.git` To interact with a repository, use the regular Git commands, but prepend them with `vcsh run $repository_name`. For example: - vcsh run zsh git status - vcsh run zsh git add -f .zshrc - vcsh run zsh git commit + vcsh zsh status + vcsh zsh add .zshrc + vcsh zsh commit Obviously, without mr keeping repositories up-to-date, it will have to be done manually. Alternatively, you could try something like this: diff --git a/changelog b/changelog index 1f1d1e647aacb3f846147e0326fea449a729f682..b0bac5d205166c3e704c18b4c85c3ce10d0fe2e9 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,28 @@ +2013-12-14 Richard Hartmann <richih.mailinglist@gmail.com> + + * Release 1.20131214 + * Revert "Implement basename() in shell" + * Fix mktemp on OS X + * Fix variable assignment bug + * Support shortnames for commands + * Improve Makefile + * Improve documentation + * Various minor improvements + +2013-09-09 Richard Hartmann <richih.mailinglist@gmail.com> + + * Release 1.20130909 + * Add support for relative worktrees + +2013-08-29 Richard Hartmann <richih.mailinglist@gmail.com> + + * Release 1.20130829 + * Add support for `vcsh commit` + * Add support for `vcsh status <repo>` + * Add pre-/post-init hooks + * Documentation improvements + * Minor cleanups + 2013-07-24 Richard Hartmann <richih.mailinglist@gmail.com> * Release 1.20130724 diff --git a/debian/changelog b/debian/changelog index 9cef61cee2b41531d0e6e85ac4433257b60b5a22..a6d457bad3f0053bbe5569fa12257aafaf6b17ec 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,39 @@ +vcsh (1.20131214-1) unstable; urgency=low + + * New upstream release + + Release 1.20131214 + + Revert "Implement basename() in shell" + + Fix mktemp on OS X + + Fix variable assignment bug + + Support shortnames for commands + + Improve Makefile + + Improve documentation + + Various minor improvements + * Packaging changes + + Bump Standards-Version to 3.9.5 (no changes) + + -- Richard Hartmann <richih@debian.org> Sat, 14 Dec 2013 00:08:37 +0100 + +vcsh (1.20130909-1) unstable; urgency=low + + * New upstream release + + Add support for relative worktrees + * Packaging changes + + Start using dgit for actual releases + + -- Richard Hartmann <richih@debian.org> Mon, 09 Sep 2013 09:20:15 +0200 + +vcsh (1.20130829-1) unstable; urgency=low + + * New upstream release + + Add support for `vcsh commit` + + Add support for `vcsh status <repo>` + + Add pre-/post-init hooks + + Documentation improvements + + Minor cleanups + + -- Richard Hartmann <richih@debian.org> Thu, 29 Aug 2013 22:45:56 +0200 + vcsh (1.20130724-1~bpo70+1) wheezy-backports; urgency=low * Rebuild for wheezy-backports. diff --git a/debian/control b/debian/control index d80308325a98c09f9410fcc6952d7bad23e42fe9..fba181d22e10b6608a18b71234ad9d6ed80c2b6b 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: vcsh Maintainer: Richard Hartmann <richih@debian.org> Section: misc Priority: optional -Standards-Version: 3.9.4 +Standards-Version: 3.9.5 Build-Depends: debhelper (>= 7), git, ruby-ronn (>= 0.7.3) diff --git a/debian/gbp.conf b/debian/gbp.conf index a26b79618d3bd99afddfe85ab2a77d2904455bb8..f515fcc1f75eadcfdc181c416be6a51cc1b17923 100644 --- a/debian/gbp.conf +++ b/debian/gbp.conf @@ -4,7 +4,7 @@ debian-branch = debian-wheezy upstream-tag = v%(version)s debian-tag = debian/%(version)s -postbuild = lintian $GBP_CHANGES_FILE +postbuild = lintian -IE --pedantic $GBP_CHANGES_FILE color = on compression = xz compression-level = 9 diff --git a/doc/hooks b/doc/hooks index 3c72ef88e336f6eb8f109a6871aa7f2068eee469..54ff795611c0081e11eca8d16064f0f57f2ac60e 100644 --- a/doc/hooks +++ b/doc/hooks @@ -12,6 +12,8 @@ Available hooks are: * post-command * pre-enter * post-enter +* pre-init +* post-init * pre-pull * post-pull * pre-push diff --git a/doc/vcsh.1.ronn b/doc/vcsh.1.ronn index 9532e654278c1187eb0112b8d50769ed19156eea..56df4ed26e74cdbb7a4109056b8415570843d846 100644 --- a/doc/vcsh.1.ronn +++ b/doc/vcsh.1.ronn @@ -29,7 +29,7 @@ vcsh(1) - Version Control System for $HOME - multiple Git repositories in $HOME `vcsh` run <repo> <shell command> -`vcsh` status +`vcsh` status [<repo>] `vcsh` upgrade <repo> @@ -86,6 +86,9 @@ an interactive user. If you need to clone a bundle of repositories, look into the `post-clone-retired` hook. +* commit: + Commit in all repositories + * delete: Delete an existing repository. @@ -128,7 +131,7 @@ an interactive user. an interactive user. * status: - Show statuses of all vcsh repositories. + Show statuses of all/one vcsh repositories. * upgrade: Upgrade repository to currently recommended settings. @@ -181,6 +184,15 @@ Interesting knobs you can turn: Defaults to <exact>. +* <$VCSH_VCSH_WORKTREE>: + Can be <absolute>, or <relative>. + + <absolute> will set an absolute path; defaulting to <$HOME>. + + <relative> will set a path relative to <$GIT_DIR>. + + Defaults to <absolute>. + Less interesting knobs you could turn: * <$VCSH_DEBUG>: @@ -226,9 +238,12 @@ 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. -Available hooks are <pre-enter>, <post-enter>, <pre-run>, <post-run>, -<pre-upgrade>, and <post-upgrade>. If you need more, vcsh is trivial to patch, -but please let upstream know so we can ship them by default. +Available hooks are <pre-clone>, <post-clone>, <post-clone-retired>, +<pre-command>, <post-command>, <pre-enter>, <post-enter>, <pre-init>, +<post-init>, <pre-pull>, <post-pull>, <pre-push>, <post-push>, <pre-run>, +<post-run>, <pre-upgrade>, and <post-upgrade>. +If you need more, vcsh is trivial to patch, but please let upstream know so +we can ship them by default. ## DETAILED HOWTO AND FURTHER READING @@ -279,7 +294,7 @@ This manpage and `vcsh` itself were written by Richard "RichiH" Hartmann. ## COPYRIGHT -Copyright 2011-2013 Richard Hartmann <richih.mailinglist@gmail.com> +Copyright 2011-2013 Richard Hartmann <richih@debian.org> Licensed under the GNU GPL version 2 or higher. diff --git a/tools/list_CONTRIBUTORS b/tools/list_CONTRIBUTORS index 351820564a77614b5b10f335d38cf5ba549d76fa..2954f583ab23df5fc286f7ee270d324f333b39df 100755 --- a/tools/list_CONTRIBUTORS +++ b/tools/list_CONTRIBUTORS @@ -1,5 +1,6 @@ #!/bin/sh -echo 'Alphabetical list of everyone who ever committed to this repository +echo 'Alphabetical list of surnames of everyone who ever committed to this repository. +Auto-generated from tools/list_CONTRIBUTORS. ' git shortlog -se --all | cut -f1 --complement | sort -u -k2 diff --git a/vcsh b/vcsh index f2bbd7a229c8211b9d79cb3bb0ee262f54a28eec..2b7528f2864986c0530334a23ee50c4c756274bf 100755 --- a/vcsh +++ b/vcsh @@ -1,7 +1,7 @@ #!/bin/sh # This program is licensed under the GNU GPL version 2 or later. -# (c) Richard "RichiH" Hartmann <richih.mailinglist@gmail.com>, 2011-2013 +# (c) Richard "RichiH" Hartmann <richih@debian.org>, 2011-2013 # For details, see LICENSE. To submit patches, you have to agree to # license your code under the GNU GPL version 2 or later. @@ -15,16 +15,8 @@ # This should always be the first line of code to facilitate debugging [ -n "$VCSH_DEBUG" ] && set -vx -basename() { - # Implemented in shell to avoid spawning another process - local file - file="${1##*/}" - [ -z "$2" ] || file="${file%$2}" - echo "$file" -} - SELF=$(basename $0) -VERSION='1.20130724' +VERSION='1.20131214' fatal() { echo "$SELF: fatal: $1" >&2 @@ -38,9 +30,11 @@ while getopts "c:dv" flag; do if [ "$1" = '-d' ] || [ "$1" = '--debug' ]; then set -vx VCSH_DEBUG=1 + echo "debug mode on" echo "$SELF $VERSION" elif [ "$1" = '-v' ];then VCSH_VERBOSE=1 + echo "verbose mode on" echo "$SELF $VERSION" elif [ "$1" = '-c' ];then VCSH_OPTION_CONFIG=$OPTARG @@ -79,6 +73,15 @@ fi [ -z "$VCSH_HOOK_D" ] && VCSH_HOOK_D="$XDG_CONFIG_HOME/vcsh/hooks-enabled" [ -z "$VCSH_BASE" ] && VCSH_BASE="$HOME" [ -z "$VCSH_GITIGNORE" ] && VCSH_GITIGNORE='exact' +[ -z "$VCSH_WORKTREE" ] && VCSH_WORKTREE='absolute' + +if [ ! "x$VCSH_GITIGNORE" = 'xexact' ] && [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && [ ! "x$VCSH_GITIGNORE" = 'xrecursive' ]; then + fatal "'\$VCSH_GITIGNORE' must equal 'exact', 'none', or 'recursive'" 1 +fi + +if [ ! "x$VCSH_WORKTREE" = 'xabsolute' ] && [ ! "x$VCSH_WORKTREE" = 'xrelative' ]; then + fatal "'\$VCSH_WORKTREE' must equal 'absolute', or 'relative'" 1 +fi help() { @@ -92,6 +95,7 @@ help() { commands: clone <remote> \\ [<repo>] Clone from an existing repository + commit Commit in all repositories delete <repo> Delete an existing repository enter <repo> Enter repository; spawn new instance of \$SHELL help Display this help text @@ -106,7 +110,7 @@ help() { <newname> Rename repository run <repo> \\ <command> Use this repository - status Show statuses of all vcsh repositories + status [<repo>] Show statuses of all/one vcsh repositories upgrade <repo> Upgrade repository to currently recommended settings version Print version information which <substring> Find substring in name of any tracked file @@ -147,17 +151,29 @@ clone() { for object in $(git ls-tree -r origin/master | awk '{print $4}'); do [ -e "$object" ] && error "'$object' exists." && - VCSH_CONFLICT=1; + VCSH_CONFLICT=1 done [ "$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.\n" 17 + Once this situation has been resolved, run 'vcsh run $VCSH_REPO_NAME git pull' to finish cloning." 17 git merge origin/master hook post-clone retire hook post-clone-retired } +commit() { + hook pre-commit + for VCSH_REPO_NAME in $(list); do + echo "$VCSH_REPO_NAME: " + export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" + use + git commit --untracked-files=no --quiet + echo + done + hook post-commit +} + delete() { cd "$VCSH_BASE" || fatal "could not enter '$VCSH_BASE'" 11 use @@ -197,12 +213,13 @@ hook() { } init() { + hook pre-init [ ! -e "$GIT_DIR" ] || fatal "'$GIT_DIR' exists" 10 - export GIT_WORK_TREE="$VCSH_BASE" - mkdir -p "$GIT_WORK_TREE" || fatal "could not create '$GIT_WORK_TREE'" 50 - cd "$GIT_WORK_TREE" || fatal "could not enter '$GIT_WORK_TREE'" 11 + mkdir -p "$VCSH_BASE" || fatal "could not create '$VCSH_BASE'" 50 + cd "$VCSH_BASE" || fatal "could not enter '$VCSH_BASE'" 11 git init upgrade + hook post-init } list() { @@ -252,7 +269,6 @@ push() { } retire() { - unset GIT_WORK_TREE unset VCSH_DIRECTORY } @@ -264,7 +280,7 @@ rename() { # Now that the repository has been renamed, we need to fix up its configuration # Overwrite old name.. GIT_DIR="$GIT_DIR_NEW" - $VCSH_REPO_NAME="$VCSH_REPO_NAME_NEW" + VCSH_REPO_NAME="$VCSH_REPO_NAME_NEW" # ..and clobber all old configuration upgrade } @@ -277,28 +293,43 @@ run() { } status() { - for VCSH_REPO_NAME in $(list); do - echo "$VCSH_REPO_NAME:" + if [ ! "x$VCSH_REPO_NAME" = "x" ]; then export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" use git status --short --untracked-files='no' - echo - done + 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' + echo + done + fi } upgrade() { hook pre-upgrade - use - git config core.worktree "$GIT_WORK_TREE" + # fake-bare repositories are not bare, actually. Set this to false + # because otherwise Git complains "fatal: core.bare and core.worktree + # do not make sense" + git config core.bare false + # core.worktree may be absolute or relative to $GIT_DIR, depending on + # user preference + if [ ! "x$VCSH_WORKTREE" = 'xabsolute' ]; then + git config core.worktree $(cd $GIT_DIR && GIT_WORK_TREE="$VCSH_BASE" git rev-parse --show-cdup) + elif [ ! "x$VCSH_WORKTREE" = 'xrelative' ]; then + 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' + use [ -e "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" ] && git add -f "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" hook post-upgrade } use() { git_dir_exists - export GIT_WORK_TREE="$(git config --get core.worktree)" export VCSH_DIRECTORY="$VCSH_REPO_NAME" } @@ -326,7 +357,11 @@ write_gitignore() { file="$new" done; done | sort -u) - tempfile=$(mktemp) || fatal "could not create tempfile" 51 + + # Contrary to GNU mktemp, mktemp on BSD/OSX requires a template for temp files + # Use the template GNU mktemo defaults to + tempfile=$(mktemp tmp.XXXXXXXXXX) || fatal "could not create tempfile" 51 + echo '*' > "$tempfile" || fatal "could not write to '$tempfile'" 57 for gitignore in $gitignores; do echo "$gitignore" | sed 's@^@!/@' >> "$tempfile" || fatal "could not write to '$tempfile'" 57 @@ -347,48 +382,70 @@ write_gitignore() { fatal "could not move '$tempfile' to '$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME'" 53 } +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 fi -if [ "$1" = 'clone' ]; then - [ -z "$2" ] && fatal "$1: please specify a remote" 1 - export VCSH_COMMAND="$1" +export VCSH_COMMAND="$1" + +[ "$VCSH_COMMAND" = 'clon' ] || [ "$VCSH_COMMAND" = 'clo' ] || [ "$VCSH_COMMAND" = 'cl' ] && VCSH_COMMAND='clone' +[ "$VCSH_COMMAND" = 'commi' ] || [ "$VCSH_COMMAND" = 'comm' ] || [ "$VCSH_COMMAND" = 'com' ] || [ "$VCSH_COMMAND" = 'co' ] && VCSH_COMMAND='commit' +[ "$VCSH_COMMAND" = 'delet' ] || [ "$VCSH_COMMAND" = 'dele' ] || [ "$VCSH_COMMAND" = 'del' ] || [ "$VCSH_COMMAND" = 'de' ] && VCSH_COMMAND='delete' +[ "$VCSH_COMMAND" = 'ente' ] || [ "$VCSH_COMMAND" = 'ent' ] || [ "$VCSH_COMMAND" = 'en' ] && VCSH_COMMAND='enter' +[ "$VCSH_COMMAND" = 'hel' ] || [ "$VCSH_COMMAND" = 'he' ] && VCSH_COMMAND='help' +[ "$VCSH_COMMAND" = 'ini' ] || [ "$VCSH_COMMAND" = 'in' ] && VCSH_COMMAND='init' +[ "$VCSH_COMMAND" = 'pul' ] && VCSH_COMMAND='pull' +[ "$VCSH_COMMAND" = 'pus' ] && VCSH_COMMAND='push' +[ "$VCSH_COMMAND" = 'renam' ] || [ "$VCSH_COMMAND" = 'rena' ] || [ "$VCSH_COMMAND" = 'ren' ] || [ "$VCSH_COMMAND" = 're' ] && VCSH_COMMAND='rename' +[ "$VCSH_COMMAND" = 'ru' ] && VCSH_COMMAND='run' +[ "$VCSH_COMMAND" = 'statu' ] || [ "$VCSH_COMMAND" = 'stat' ] || [ "$VCSH_COMMAND" = 'sta' ] || [ "$VCSH_COMMAND" = 'st' ] && VCSH_COMMAND='status' +[ "$VCSH_COMMAND" = 'upgrad' ] || [ "$VCSH_COMMAND" = 'upgra' ] || [ "$VCSH_COMMAND" = 'upgr' ] || [ "$VCSH_COMMAND" = 'upg' ] && VCSH_COMMAND='upgrade' +[ "$VCSH_COMMAND" = 'versio' ] || [ "$VCSH_COMMAND" = 'versi' ] || [ "$VCSH_COMMAND" = 'vers' ] || [ "$VCSH_COMMAND" = 'ver' ] || [ "$VCSH_COMMAND" = 've' ] && VCSH_COMMAND='version' +[ "$VCSH_COMMAND" = 'whic' ] || [ "$VCSH_COMMAND" = 'whi' ] || [ "$VCSH_COMMAND" = 'wh' ] && VCSH_COMMAND='which' +[ "$VCSH_COMMAND" = 'write' ] || [ "$VCSH_COMMAND" = 'writ' ] || [ "$VCSH_COMMAND" = 'wri' ] || [ "$VCSH_COMMAND" = 'wr' ] && VCSH_COMMAND='write-gitignore' + + +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) + [ -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" -elif [ "$1" = 'version' ]; then +elif [ "$VCSH_COMMAND" = 'version' ]; then echo "$SELF $VERSION" + git version exit -elif [ "$1" = 'which' ]; then - [ -z "$2" ] && fatal "$1: please specify a filename" 1 - [ -n "$3" ] && fatal "$1: too many parameters" 1 - export VCSH_COMMAND="$1" +elif [ "$VCSH_COMMAND" = 'which' ]; then + [ -z "$2" ] && fatal "$VCSH_COMMAND: please specify a filename" 1 + [ -n "$3" ] && fatal "$VCSH_COMMAND: too many parameters" 1 export VCSH_COMMAND_PARAMETER="$2" -elif [ "$1" = 'delete' ] || - [ "$1" = 'enter' ] || - [ "$1" = 'init' ] || - [ "$1" = 'list-tracked-by' ] || - [ "$1" = 'rename' ] || - [ "$1" = 'run' ] || - [ "$1" = 'upgrade' ] || - [ "$1" = 'write-gitignore' ]; then - [ -z $2 ] && fatal "$1: please specify repository to work on" 1 - [ "$1" = 'rename' -a -z "$3" ] && fatal "$1: please specify a target name" 1 - [ "$1" = 'run' -a -z "$3" ] && fatal "$1: please specify a command" 1 - export VCSH_COMMAND="$1" +elif [ "$VCSH_COMMAND" = 'delete' ] || + [ "$VCSH_COMMAND" = 'enter' ] || + [ "$VCSH_COMMAND" = 'init' ] || + [ "$VCSH_COMMAND" = 'list-tracked-by' ] || + [ "$VCSH_COMMAND" = 'rename' ] || + [ "$VCSH_COMMAND" = 'run' ] || + [ "$VCSH_COMMAND" = 'upgrade' ] || + [ "$VCSH_COMMAND" = 'write-gitignore' ]; then + [ -z $2 ] && fatal "$VCSH_COMMAND: please specify repository to work on" 1 + [ "$VCSH_COMMAND" = 'rename' -a -z "$3" ] && fatal "$VCSH_COMMAND: please specify a target name" 1 + [ "$VCSH_COMMAND" = 'run' -a -z "$3" ] && fatal "$VCSH_COMMAND: please specify a command" 1 export VCSH_REPO_NAME="$2" export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" [ "$VCSH_COMMAND" = 'rename' ] && { export VCSH_REPO_NAME_NEW="$3"; export GIT_DIR_NEW="$VCSH_REPO_D/$VCSH_REPO_NAME_NEW.git"; } [ "$VCSH_COMMAND" = 'run' ] && shift 2 -elif [ "$1" = 'list' ] || - [ "$1" = 'list-tracked' ] || - [ "$1" = 'pull' ] || - [ "$1" = 'push' ] || - [ "$1" = 'status' ]; then - export VCSH_COMMAND="$1" +elif [ "$VCSH_COMMAND" = 'commit' ] || + [ "$VCSH_COMMAND" = 'list' ] || + [ "$VCSH_COMMAND" = 'list-tracked' ] || + [ "$VCSH_COMMAND" = 'pull' ] || + [ "$VCSH_COMMAND" = 'push' ]; then + : +elif [ "$VCSH_COMMAND" = 'status' ]; then + export VCSH_REPO_NAME="$2" elif [ -n "$2" ]; then export VCSH_COMMAND='run' export VCSH_REPO_NAME="$1" @@ -396,7 +453,7 @@ elif [ -n "$2" ]; then [ -d $GIT_DIR ] || { help; exit 1; } shift 1 set -- "git" "$@" -elif [ -n "$1" ]; then +elif [ -n "$VCSH_COMMAND" ]; then export VCSH_COMMAND='enter' export VCSH_REPO_NAME="$1" export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" @@ -419,7 +476,7 @@ check_dir() { if [ -e "$check_directory" ]; then fatal "'$check_directory' exists but is not a directory" 13 else - info "attempting to create '$check_directory'" + verbose "attempting to create '$check_directory'" mkdir -p "$check_directory" || fatal "could not create '$check_directory'" 50 fi fi