From f249ad2f014d410aaac761dace1bec5e17e7f829 Mon Sep 17 00:00:00 2001 From: Cosmin Apreutesei Date: Mon, 6 Apr 2015 21:51:51 +0300 Subject: [PATCH] unimportant --- .multigit/.exclude | 4 - git | 218 ++++++++++++++++++++++----------- git.cmd | 296 ++++----------------------------------------- 3 files changed, 171 insertions(+), 347 deletions(-) diff --git a/.multigit/.exclude b/.multigit/.exclude index 7fa913c..8c0d942 100644 --- a/.multigit/.exclude +++ b/.multigit/.exclude @@ -1,7 +1,3 @@ # .gitignore file for multigit, auto-configured on first clone. * -!/.multigit/ -!/.multigit/.exclude -!/git -!/git.cmd diff --git a/git b/git index 217e241..1151373 100755 --- a/git +++ b/git @@ -1,6 +1,5 @@ #!/bin/sh - usage() { [ "$1" ] && { echo @@ -9,32 +8,32 @@ usage() { exit } echo - echo " Multigit 0.1 - git wrapper for working with overlaid repos." + echo " Multigit 1.0 - git wrapper for working with overlaid repos." echo " Written by Cosmin Apreutesei. Public Domain." + echo " See https://github.com/capr/multigit for info." echo - echo " USAGE:" + echo " USAGE: $ZERO ..." echo - echo " $0 ls-all list all known packages" - echo " $0 ls-uncloned list not yet cloned packages" - echo " $0 ls-cloned list cloned packages" - echo " $0 ls-modified list packages that were modified locally" - echo " $0 ls-unpushed list packages that are ahead of origin" - echo " $0 ls-untracked list files untracked by any repo" - echo " $0 ls-double-tracked list files tracked by multiple repos" - echo " $0 clone [origin | url] clone a package" - echo " $0 clone-all [fetch-options] clone all uncloned packages" - echo " $0 unclone remove a cloned package from disk (!)" - echo " $0 |--all up [message] add/commit/push combo" - echo " $0 |--all uptag update current tag to point to current commit" - echo " $0 |--all ver show package version" - echo " $0 |--all clear-history clear the entire history of the current branch (!)" - echo " $0 |--all update-perms chmod+x all .sh files in package (in git)" - echo " $0 |--all make-symlinks make symbolic links in .multigit/" - echo " $0 |--all make-hardlinks make hard links in .multigit/" - echo " $0 |--all command ... execute any git command on a package repo" - echo " $0 start a git subshell for a package repo" - echo " $0 platform show current platform" - echo " $0 [help|--help] this screen" + echo " ls-all list all known packages" + echo " ls-uncloned list not yet cloned packages" + echo " ls-cloned list cloned packages" + echo " ls-modified list packages that were modified locally" + echo " ls-unpushed list packages that are ahead of origin" + echo " ls-untracked list files untracked by any repo" + echo " ls-double-tracked list files tracked by multiple repos" + echo " clone [origin/]pkg | url ... clone packages" + echo " clone-all [fetch-options] clone all uncloned packages" + echo " unclone pkg1 ... remove cloned packages from disk (!)" + echo " pkg|--all up [message] add/commit/push combo" + echo " pkg|--all uptag update current tag to point to current commit" + echo " pkg|--all ver[sion] show package version" + echo " pkg|--all clear-history clear the entire history of the current branch (!)" + echo " pkg|--all update-perms chmod+x all .sh files in package (in git)" + echo " pkg|--all make-symlinks make symbolic links in .multigit/pkg" + echo " pkg|--all make-hardlinks make hard links in .multigit/pkg" + echo " pkg|--all command ... execute any git command on a package repo" + echo " pkg start a git subshell for a package repo" + echo " [help|--help] show this screen" echo exit } @@ -105,59 +104,132 @@ list_double_tracked() { } clone_all() { - export GIT_FETCH_OPTS="$@" + export MULTIGIT_FETCH_OPTS="$@" for package in `list_uncloned`; do "$0" clone "$package" done } -clone() { - [ "$1" ] || usage "Package name expected." - [ ! -d ".multigit/$1/.git" ] || usage "Package \"$1\" already cloned." +clone_one() { + local arg=$1 + local name + local origin + local rorigin + local url - if [ "$2" = "" ]; then - [ -f ".multigit/$1.origin" ] || usage "File not found \".multigit/$1.origin\"." - o=$(cat .multigit/$1.origin) - if [ -f .multigit/$o.baseurl ]; then - baseurl=$(cat .multigit/$o.baseurl); url=$baseurl$1 - else - url=$o - fi + # trim arg + arg=${arg# *} + arg=${arg%* } + + # check if the arg is a full url or just `[origin/]name` + if [ "${arg#*:}" != "$arg" ]; then + url=$arg + origin=$arg + name=${url##*/} + name=${name%.git} else - origin=$2 + name=${arg##*/} + origin=${arg%/*} + [ "$origin" = "$arg" ] && origin="" + fi + + # check that the name does not contain spaces or is made of slashes + [ "$arg" = "$1" -a "$name" ] || \ + usage "Invalid package name \"$1\"." + + # check that the package is not already cloned + [ -d ".multigit/$name/.git" ] && { + echo "ERROR: Already cloned: \"$name\"." + return + } + + # check for a registered origin + [ -f ".multigit/$name.origin" ] && \ + rorigin=$(cat .multigit/$name.origin) + + # decide the origin + if [ "$origin" ]; then + [ "$origin" = "$rorigin" ] || \ + echo "Cloning \"$name\" from different origin \"$origin\" (was \"$rorigin\")." + else + origin=$rorigin + [ "$origin" ] || { + echo "ERROR: Missing origin in \".multigit/$name.origin\"." + return + } + fi + + # find the origin url + if [ ! "$url" ]; then if [ -f ".multigit/$origin.baseurl" ]; then - baseurl=$(cat .multigit/$origin.baseurl); url=$baseurl$1 + local baseurl=$(cat .multigit/$origin.baseurl) + url=$baseurl$name else - url=$origin + # assume the origin on file is a full url: check if it is + if [ "${origin#*:}" != "$origin" ]; then + url=$origin + else + echo "ERROR: Unknown origin: \"$origin\"." + return + fi fi fi # set the .gitignore file for multigit on the first clone operation. git config core.excludesfile .multigit/.exclude - mkdir -p ".multigit/$1" - export GIT_DIR=".multigit/$1/.git" - + # finally, clone the package + mkdir -p ".multigit/$name" + export GIT_DIR=".multigit/$name/.git" git init git config --local core.worktree ../../.. - git config --local core.excludesfile ".multigit/$1.exclude" - git remote add origin "$url" - git fetch $GIT_FETCH_OPTS || { - rm -rf ".multigit/$1/.git" - usage "git fetch error." + git config --local core.excludesfile ".multigit/$name.exclude" + git remote add origin $url + git fetch $MULTIGIT_FETCH_OPTS || { + rm -rf ".multigit/$name/.git" + echo "ERROR: git fetch error." + return } git branch --track master origin/master git checkout - # register the package if new - [ "$origin" ] && echo $origin > .multigit/$1.origin + # make an "exclude-all" exclude file if one is not present + [ -f ".multigit/$name.exclude" ] || echo '*' > ".multigit/$name.exclude" + + # if fetch was successful, (re)register the origin for the package + if [ "$origin" != "$rorigin" ]; then + if [ "$rorigin" ]; then + echo "NOTE: Updating origin for \"$name\": \"$origin\" (was \"$rorigin\")" + else + echo "NOTE: Registering origin for \"$name\": $origin ($url)" + fi + echo $origin > ".multigit/$name.origin" + fi } -unclone() { - [ "$1" ] || usage "Missing package." - [ -d ".multigit/$1/.git" ] || usage "Package not found \"$1\"." +clone() { + [ "$1" ] || usage "Package name expected." + if [ $# = 1 ]; then + clone_one "$@" + else + while [ $# != 0 ]; do + clone_one "$1" + shift + done + fi +} - files="$(GIT_DIR=".multigit/$1/.git" git ls-tree -r --name-only HEAD)" +unclone_one() { + [ -d ".multigit/$1/.git" ] || { + echo "ERROR: package not found \"$1\"." + return + } + + # get tracked files for this package + files="$(GIT_DIR=".multigit/$1/.git" git ls-tree -r --name-only HEAD)" || { + echo "ERROR: could not get files for \"$1\"." + return + } # remove files for file in $files; do @@ -174,16 +246,21 @@ unclone() { # remove the git dir rm -rf ".multigit/$1/.git" rmdir ".multigit/$1" + + echo "Removed: \"$1\"." } -platform() { - [ "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64" ] && echo mingw64 || { - [ "$OSTYPE" = "msys" ] && echo mingw32 || { - local a=32 - [ "$(uname -m)" = "x86_64" ] && a=64 - [ "${OSTYPE#darwin}" != "$OSTYPE" ] && echo osx$a || echo linux$a - } - } +unclone() { + [ "$1" ] || usage "Package name expected." + [ "$GIT_DIR" ] && usage "Refusing to unclone from a subshell." + if [ $# = 1 ]; then + unclone_one "$@" + else + while [ $# != 0 ]; do + unclone_one "$1" + shift + done + fi } git_shell() { @@ -191,7 +268,12 @@ git_shell() { echo "Type \`exit' to exit subshell." git status -s echo - PS1="[$MULTIGIT_PACKAGE] \u@\h:\w\$ " $SHELL -i + if [ "$OSTYPE" = "msys" ]; then + export PROMPT="[$MULTIGIT_PACKAGE] $P$G" + exec "$COMSPEC" /k + else + PS1="[$MULTIGIT_PACKAGE] \u@\h:\w\$ " $SHELL -i + fi } git_up() { @@ -251,7 +333,7 @@ git_make_symlinks() { } git_cmd() { - [ "$1" = "--all" -o "$1" = "-a" ] && { + [ "$1" = "--all" ] && { shift [ "$@" ] || usage "Refusing to start a subshell for each package." foreach_cloned "$@" @@ -263,12 +345,12 @@ git_cmd() { export GIT_DIR=".multigit/$pkg/.git" export MULTIGIT_PACKAGE="$pkg" - [ -d "$GIT_DIR" ] || usage "Unknown package \"$pkg\"." + [ -d "$GIT_DIR" ] || usage "Unknown package: \"$pkg\"." [ "$1" ] || { git_shell; exit; } [ "$1" = "up" ] && { git_up "$2"; exit; } [ "$1" = "uptag" ] && { git_uptag; exit; } - [ "$1" = "ver" ] && { git_ver; exit; } + [ "$1" = "ver" -o "$1" = "version" ] && { git_ver; exit; } [ "$1" = "clear-history" ] && { git_clear_history; exit; } [ "$1" = "update-perms" ] && { git_update_perms; exit; } [ "$1" = "make-symlinks" ] && { git_make_symlinks; exit; } @@ -277,11 +359,10 @@ git_cmd() { git "$@" } +[ "$ZERO" ] || ZERO="$0" # for wrapping cd "$(dirname "$0")" || usage "Could not change dir to \"$(dirname "$0")\"." -[ "$1" ] || usage -[ "$1" = "help" ] && usage -[ "$1" = "--help" ] && usage +[ -z "$1" -o "$1" = "help" -o "$1" = "--help" ] && usage [ "$1" = "ls-all" ] && { list_known; exit; } [ "$1" = "ls-cloned" ] && { list_cloned; exit; } [ "$1" = "ls-uncloned" ] && { list_uncloned; exit; } @@ -292,6 +373,5 @@ cd "$(dirname "$0")" || usage "Could not change dir to \"$(dirname "$0")\"." [ "$1" = "clone" ] && { shift; clone "$@"; exit; } [ "$1" = "clone-all" ] && { shift; clone_all "$@"; exit; } [ "$1" = "unclone" ] && { shift; unclone "$@"; exit; } -[ "$1" = "platform" ] && { platform; exit; } git_cmd "$@" diff --git a/git.cmd b/git.cmd index f808dfd..3cab524 100644 --- a/git.cmd +++ b/git.cmd @@ -1,285 +1,33 @@ @echo off -goto begin - -:usage - if [%1] == [] goto usage1 - echo. - echo ERROR: %* - echo. - goto end -:usage1 - echo. - echo Multigit 0.1 - git wrapper for working with overlaid repos. - echo Written by Cosmin Apreutesei. Public Domain. - echo. - echo USAGE: - echo. - echo %Z% ls-all list all known packages - echo %Z% ls-uncloned list not yet cloned packages - echo %Z% ls-cloned list cloned packages - echo %Z% ls-modified list packages that were modified locally - echo %Z% ls-unpushed list packages that are ahead of origin - echo %Z% ls-untracked list files untracked by any repo (needs MSYS) - echo %Z% ls-double-tracked list files tracked by multiple repos (needs MSYS) - echo %Z% clone ^ ^[origin ^| url^] clone a package - echo %Z% clone-all [fetch-options] clone all uncloned packages - echo %Z% unclone ^ remove a cloned package from disk (!) - echo %Z% ^^|--all up ^[message^] add/commit/push combo - echo %Z% ^^|--all uptag update current tag to point to current commit - echo %Z% ^^|--all ver show package version - echo %Z% ^^|--all clear-history clear the entire history of the current branch (!) - echo %Z% ^^|--all update-perms chmod+x all .sh files in package (in git) - echo %Z% ^^|--all command ... execute any git command on a package repo - echo %Z% ^ start a git subshell for a package repo - echo %Z% platform show current platform - echo %Z% ^[help^|--help^] this screen - echo. - goto end - -:list_known - for %%f in (.multigit/*.origin) do call :list_known1 %%f - goto end -:list_known1 - set s=%1 - set s=%s:.origin=% - echo %s% - goto end - -:list_cloned - for %%f in (.multigit/*.origin) do call :list_cloned1 %%f - goto end -:list_cloned1 - set s=%1 - set s=%s:.origin=% - if exist .multigit/%s%/.git echo %s% - goto end - -:list_uncloned - for %%f in (.multigit/*.origin) do call :list_uncloned1 %%f - goto end -:list_uncloned1 - set s=%1 - set s=%s:.origin=% - if not exist .multigit/%s%/.git echo %s% - goto end - -:foreach_cloned - set MULTIGIT_PACKAGE1=MULTIGIT_PACKAGE - set GIT_DIR1=GIT_DIR - set GIT_DIR= - set MULTIGIT_PACKAGE= - for /f "tokens=* delims= " %%p in ('%Z% ls-cloned') do call %Z% %%p %* - set MULTIGIT_PACKAGE=MULTIGIT_PACKAGE1 - set GIT_DIR=GIT_DIR1 - goto end - -:list_modified - call :foreach_cloned status -s - goto end - -:list_unpushed - for /f "tokens=* delims= " %%p in ('%Z% ls-cloned') do call :list_unpushed1 %%p - goto end -:list_unpushed1 - set GIT_DIR=.multigit/%1/.git - set "cmd=git.exe rev-list HEAD...origin/master --count" - for /f "delims=" %%i in ('%cmd%') do if not "%%i" == "0" echo %1 - goto end - -:list_untracked - sh ./git ls-untracked - goto end - -:list_double_tracked - sh ./git ls-double-tracked - goto end - -:clone_all - set GIT_FETCH_OPTS=%* - for /f "tokens=* delims= " %%p in ('%Z% ls-uncloned') do call %Z% clone %%p - goto end - -:clone - if [%1] == [] call :usage Package name expected. & goto end - if exist .multigit/%1/.git/nul call :usage Pacakge "%1" is already cloned. & goto end - - if [%2] == [] ( - if not exist .multigit/%1.origin call :usage File not found ".multigit/%1.origin". & goto end - for /f "delims=" %%o in (.multigit/%1.origin) do ( - if exist .multigit/%%o.baseurl ( - for /f "delims=" %%u in (.multigit/%%o.baseurl) do set url=%%u%1 - ) else ( - set url=%%o - ) - ) - ) else ( - set origin=%2 - if exist .multigit/%origin%.baseurl ( - for /f "delims=" %%s in (.multigit/%origin%.baseurl) do set url=%%s%1 - ) else ( - set url=%origin% - ) - ) - - rem set the .gitignore file for multigit on the first clone operation. - git.exe config core.excludesfile .multigit/.exclude - - md .multigit\%1 - set GIT_DIR=.multigit/%1/.git - - git.exe init - git.exe config --local core.worktree ../../.. - git.exe config --local core.excludesfile .multigit/%1.exclude - git.exe remote add origin %url% - git.exe fetch %GIT_FETCH_OPTS% - if %errorlevel% neq 0 ( - rmdir .multigit/%1/.git /s /q - call :usage git fetch error. & goto end - ) - git.exe branch --track master origin/master - git.exe checkout - - rem register the package if new - if not [%origin%] == [] echo %origin% > .multigit/%1.origin - goto end - -:unclone - if [%1] == [] call :usage Missing package. & goto end - if not [%GIT_DIR%] == [] call :usage Cannot unclone from a subshell. & goto end - if not exist .multigit/%1/.git/nul call :usage Package not found "%1". & goto end - for /f "delims=" %%i in ('%Z% %1 ls-tree -r --name-only HEAD') do call :remove_file %%i - for /f "delims=" %%i in ('%Z% %1 ls-tree -r --name-only HEAD') do call :remove_empty_dir %%i - rd /S /Q .multigit\%1 - goto end -:remove_file - set file=%1 - set file=%file:/=\% - del %file% - goto end -:remove_empty_dir - set file="%~dp1" - set file=%file:/=\% - rd %file% 2>nul - goto end - -:platform - if [%PROCESSOR_ARCHITECTURE%] == [AMD64] echo mingw64 & goto end - if [%PROCESSOR_ARCHITEW6432%] == [AMD64] echo mingw64 & goto end - echo mingw32 - goto end - -:git_shell - echo Entering subshell: git commands will work on package "%MULTIGIT_PACKAGE%". - echo Type `exit' to exit subshell. - call git.exe status -s - set "PROMPT=[%MULTIGIT_PACKAGE%] $P$G" - cmd /k - goto end - -:git_up - set msg=%1 - if [%1] == [] set msg=unimportant - - git.exe add -A - git.exe commit -m %msg% - git.exe push - goto end - -:git_uptag - set "cmd=git.exe describe --tags --abbrev^=0" - for /f "delims=" %%i in ('%cmd%') do call :git_uptag1 %%i - goto end -:git_uptag1 - if [%1] == [] call :usage No current tag to update. Make a tag first. & goto end - git.exe tag -f %1 - git.exe push -f --tags - goto end - -:git_ver - set "s=%MULTIGIT_PACKAGE " - set "s=%s:~0,20%" - for /f "delims=" %%i in ('git.exe describe --tags --long --always') do echo %s%%%i - goto end - -:git_clear_history - set "cmd=git.exe rev-parse --abbrev-ref HEAD" - for /f "delims=" %%i in ('%cmd%') do call :git_clear_history1 %%i - goto end -:git_clear_history1 - git.exe checkout --orphan delete_me - git.exe add -A - git.exe commit -m "init (history cleared)" - git.exe branch -D %1 - git.exe branch -m %1 - goto end - -:git_update_perms - for /f "delims=" %%i in ('%Z% %MULTIGIT_PACKAGE% ls-files') do call :git_update_perms1 %%i %%~xi - goto end -:git_update_perms1 - if [%2] == [.sh] git.exe update-index --chmod=+x %1 - goto end - -:git_cmd - if [%1] == [--all] goto git_cmd_all - if [%1] == [-a] goto git_cmd_all - goto git_cmd_cont -:git_cmd_all - shift - if [%1] == [] call :usage Refusing to start a subshell for each package. & goto end - call :foreach_cloned %1 %2 %3 %4 %5 %6 %7 %8 %9 - goto end -:git_cmd_cont - set pkg=%MULTIGIT_PACKAGE% - if [%pkg%] == [] goto git_cmd1 - goto git_cmd2 -:git_cmd1 - set pkg=%1 - shift -:git_cmd2 - set GIT_DIR=.multigit/%pkg%/.git - set MULTIGIT_PACKAGE=%pkg% - if not exist %GIT_DIR%/nul call :usage Unknown package "%pkg%". & goto end - - if [%1] == [] call :git_shell & goto end - if [%1] == [up] call :git_up %2 & goto end - if [%1] == [uptag] call :git_uptag & goto end - if [%1] == [ver] call :git_ver & goto end - if [%1] == [clear-history] call :git_clear_history & goto end - if [%1] == [update-perms] call :git_update_perms & goto end - - call git.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 - goto end - -:main - if [%1] == [] call :usage & goto end - if [%1] == [help] call :usage & goto end - if [%1] == [--help] call :usage & goto end - if [%1] == [ls-all] call :list_known & goto end - if [%1] == [ls-cloned] call :list_cloned & goto end - if [%1] == [ls-uncloned] call :list_uncloned & goto end - if [%1] == [ls-modified] call :list_modified & goto end - if [%1] == [ls-unpushed] call :list_unpushed & goto end - if [%1] == [ls-untracked] call :list_untracked & goto end - if [%1] == [ls-double-tracked] call :list_double_tracked & goto end - if [%1] == [clone] call :clone %2 %3 & goto end - if [%1] == [clone-all] call :clone_all %2 %3 %4 %5 %6 %7 %8 %9 & goto end - if [%1] == [unclone] call :unclone %2 & goto end - if [%1] == [platform] call :platform & goto end - call :git_cmd %* - goto end - +setlocal enabledelayedexpansion +rem find sh.exe from a git installation and run our git wrapper with it. +rem for this to work git.exe must be in PATH and sh.exe must be in ../bin. :begin - setlocal - set Z=%0 + set ZERO=%0 pushd "%~dp0" if [%cd%\] == [%~dp0] goto callmain if [%cd%] == [%~dp0] goto callmain - call :usage Could not change dir to "%~dp0". & goto aftermain + echo ERROR: Could not change dir to "%~dp0" + goto aftermain + goto end :callmain call :main %* :aftermain popd endlocal - + goto end +:main + call :set_dir git.exe + if exist !dir! goto git_found + goto git_not_found +:set_dir + set dir=%~$PATH:1 + goto end +:git_found + set PATH=/usr/local/bin:/mingw/bin:/bin + "%dir:~0,-12%"\bin\sh.exe --norc ./git %* + goto end +:git_not_found + echo git.exe not found in PATH + goto end :end