unimportant

This commit is contained in:
Cosmin Apreutesei
2015-04-06 21:51:51 +03:00
parent d7df5ef9b6
commit f249ad2f01
3 changed files with 171 additions and 347 deletions
-4
View File
@@ -1,7 +1,3 @@
# .gitignore file for multigit, auto-configured on first clone.
*
!/.multigit/
!/.multigit/.exclude
!/git
!/git.cmd
+149 -69
View File
@@ -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 <package> [origin | url] clone a package"
echo " $0 clone-all [fetch-options] clone all uncloned packages"
echo " $0 unclone <package> remove a cloned package from disk (!)"
echo " $0 <package>|--all up [message] add/commit/push combo"
echo " $0 <package>|--all uptag update current tag to point to current commit"
echo " $0 <package>|--all ver show package version"
echo " $0 <package>|--all clear-history clear the entire history of the current branch (!)"
echo " $0 <package>|--all update-perms chmod+x all .sh files in package (in git)"
echo " $0 <package>|--all make-symlinks make symbolic links in .multigit/<package>"
echo " $0 <package>|--all make-hardlinks make hard links in .multigit/<package>"
echo " $0 <package>|--all command ... execute any git command on a package repo"
echo " $0 <package> 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 "$@"
+22 -274
View File
@@ -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 ^<package^> ^[origin ^| url^] clone a package
echo %Z% clone-all [fetch-options] clone all uncloned packages
echo %Z% unclone ^<package^> remove a cloned package from disk (!)
echo %Z% ^<package^>^|--all up ^[message^] add/commit/push combo
echo %Z% ^<package^>^|--all uptag update current tag to point to current commit
echo %Z% ^<package^>^|--all ver show package version
echo %Z% ^<package^>^|--all clear-history clear the entire history of the current branch (!)
echo %Z% ^<package^>^|--all update-perms chmod+x all .sh files in package (in git)
echo %Z% ^<package^>^|--all command ... execute any git command on a package repo
echo %Z% ^<package^> 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