├── .bash_profile ├── .git-completion.bash ├── .gitattributes ├── .gitignore ├── .gitignore_global ├── .gitsecret ├── .DS_Store ├── keys │ ├── mapping.cfg │ ├── pubring.kbx │ ├── pubring.kbx~ │ └── trustdb.gpg └── paths │ └── mapping.cfg ├── LICENSE ├── README.md ├── alias-functions.sh ├── aliases.sh ├── competent-hoover-f47adf.netlify.com_2018-08-27_09-31-30.report.html ├── configs ├── java-junit4-maven.xml ├── java-mockito-maven.xml ├── java-testng-maven.xml ├── junit5-maven.xml ├── limit.maxfiles.plist ├── limit.maxproc.plist └── soton-test-python-installation.py ├── create-conflict.sh ├── extract-sample.sh ├── fake-bash.bat ├── foundation-website-init.sh ├── git-basics.env ├── git-basics.sh ├── git-client-config.ps1 ├── git-custom-commands ├── git-c ├── git-echo ├── git-squash └── graph-dag ├── git-flow-create.sh ├── git-hooks-install.ps1 ├── git-hooks-install.sh ├── git-imerge-conflict1-create.sh ├── git-patch.sh ├── git-sample-repo-create.ps1 ├── git-sample-repo-create.sh ├── git-sisters-update.ps1 ├── git-sisters-update.sh ├── git-stash.sh ├── git-upload-new.ps1 ├── github_img_to_cloudinary.py ├── gitlab-on-pi3.sh ├── gup.sh ├── hooks ├── commit-msg ├── post-checkout ├── post-commit ├── post-merge ├── pre-commit.dateverif.sh ├── pre-commit.shellcheck.sh ├── pre-push └── prepare-commit-msg ├── mac-install-all.sh ├── mac-prompt.bash ├── my_github_accts.csv ├── my_github_accts_vars.sh ├── my_ps_functions.ps1 ├── node-test1 ├── .gitignore ├── .jshintrc ├── README.md ├── index-error.js ├── index-valid.js ├── index.js └── package.json ├── ps-auto-log.ps1 ├── secrets.sh ├── sonar1.sh ├── temp.py ├── tests ├── .DS_Store ├── HelloWorld.scala ├── chrome-google-search-quit.py ├── chrome-headless.py ├── chrome_github_login.py ├── chrome_pycon_search.py ├── firefox-google-search.py ├── firefox_github_ssh_add.py ├── firefox_pycon_search.py ├── firefox_unittest.py ├── jenkins_secret_setup.py ├── phantomjs-duck-search-1120x550.py ├── phantomjs-duck.py ├── phantomjs-smoke.js └── timestamps.py └── wm-ps-utils.psm1 /.bash_profile: -------------------------------------------------------------------------------- 1 | PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/local/share/dotnet 2 | # Note colons separate items in $PATH. 3 | # /usr/local/bin before usr/bin so Homebrew stuff is found first 4 | # alias fix_brew='sudo chown -R $USER /usr/local/'export PATH="/usr/local/bin:$PATH" 5 | # For homebrew: 6 | # $(brew --prefix)/sbin 7 | 8 | # For use in brew cask install xxx 9 | export HOMEBREW_CASK_OPTS="--appdir=~/Applications" 10 | #export HOMEBREW_CASK_OPTS="--appdir=~/Applications --caskroom=~/Caskroom" 11 | 12 | parse_git_branch() { 13 | git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/' 14 | } 15 | export PS1="\w\[\033[33m\]\$(parse_git_branch)\[\033[00m\] $ " 16 | #export PS1="\u@\h \[\033[32m\]\w\[\033[33m\]\$(parse_git_branch)\[\033[00m\] $ " 17 | #PS1='\u \W$(__git_ps1)\$ ' 18 | 19 | alias wm='cd ~/gits/wilsonmar/wilsonmar.github.io/_posts;git status -s -b' 20 | alias wf='cd ~/gits/wilsonmar/futures;git status -s -b' 21 | alias aih='iothub-explorer' 22 | 23 | alias bs='bundle exec jekyll serve --config _config.yml,_config_dev.yml' 24 | 25 | alias myip="ifconfig en0 | grep inet | grep -v inet6 | cut -d ' ' -f2" 26 | alias last20='stat -f "%m%t%Sm %N" /tmp/* | sort -rn | head -20 | cut -f2-' 27 | 28 | export GPG_TTY=$(tty) 29 | 30 | # Load the shell dotfiles, and then some: 31 | # * ~/.path can be used to extend `$PATH`. 32 | # * ~/.extra can be used for other settings you don’t want to commit. 33 | for file in ~/.{path,bash_prompt,exports,aliases,functions,extra}; do 34 | [ -r "$file" ] && [ -f "$file" ] && source "$file"; 35 | done; 36 | unset file; 37 | 38 | # Case-insensitive globbing (used in pathname expansion) 39 | shopt -s nocaseglob; 40 | 41 | # Append to the Bash history file, rather than overwriting it 42 | shopt -s histappend; 43 | 44 | # Autocorrect typos in path names when using `cd` 45 | shopt -s cdspell; 46 | 47 | # Enable some Bash 4 features when possible: 48 | # * `autocd`, e.g. `**/qux` will enter `./foo/bar/baz/qux` 49 | # * Recursive globbing, e.g. `echo **/*.txt` 50 | for option in autocd globstar; do 51 | shopt -s "$option" 2> /dev/null; 52 | done; 53 | 54 | # Copied from https://github.com/wilsonmar/git-utilities: 55 | export PATH="$HOME/gits:$PATH" 56 | export PATH="$HOME/gits/wilsonmar/git-utilities/git-custom-commands:$PATH" 57 | export WM="$HOME/gits/wilsonmar/wilsonmar.github.io" 58 | # Add tab completion for many Bash commands 59 | if which brew &> /dev/null && [ -f "$(brew --prefix)/share/bash-completion/bash_completion" ]; then 60 | source "$(brew --prefix)/share/bash-completion/bash_completion"; 61 | elif [ -f /etc/bash_completion ]; then 62 | source /etc/bash_completion; 63 | fi; 64 | # Enable tab completion for `g` by marking it as an alias for `git` 65 | if type _git &> /dev/null && [ -f /usr/local/etc/bash_completion.d/git-completion.bash ]; then 66 | complete -o default -o nospace -F _git g; 67 | fi; 68 | 69 | 70 | # https://gist.github.com/sindresorhus/98add7be608fad6b5376a895e5a59972 71 | 72 | # Add tab completion for SSH hostnames based on ~/.ssh/config, ignoring wildcards 73 | [ -e "$HOME/.ssh/config" ] && complete -o "default" -o "nospace" -W "$(grep "^Host" ~/.ssh/config | grep -v "[?*]" | cut -d " " -f2- | tr ' ' '\n')" scp sftp ssh; 74 | 75 | # Add tab completion for `defaults read|write NSGlobalDomain` 76 | # You could just use `-g` instead, but I like being explicit 77 | complete -W "NSGlobalDomain" defaults; 78 | 79 | # Add `killall` tab completion for common apps 80 | complete -o "nospace" -W "Contacts Calendar Dock Finder Mail Safari iTunes SystemUIServer Terminal Twitter" killall; 81 | 82 | # For Ruby: 83 | #export PATH="$PATH:$HOME/.rvm/gems/ruby-2.3.1/bin" 84 | export LC_ALL=en_US.utf-8 85 | #export PATH="$HOME/.rbenv/bin:$PATH" 86 | #eval "$(rbenv init -)" 87 | 88 | # Go installs packages in the first in this path of go source, separated by colons. See https://wilsonmar.github.io/golang 89 | export GOPATH="$HOME/gopkgs" 90 | export GOHOME="$HOME/gits/wilsonmar/golang-samples" 91 | #export GOROOT=/usr/local/Cellar/go/1.8.1 # Homebrew https://dave.cheney.net/2013/06/14/you-dont-need-to-set-goroot-really 92 | #export PATH=$PATH:$GOROOT/bin 93 | 94 | # Since which maven doesn't work: 95 | export M2_HOME=/usr/local/Cellar/maven/3.5.0/libexec 96 | export M2=$M2_HOME/bin 97 | export PATH=$PATH:$M2_HOME/bin 98 | 99 | complete -C aws_completer aws 100 | export AWS_DEFAULT_REGION=us-west-2 101 | export EC2_URL=https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Instances:sort=instanceId 102 | 103 | export PATH="$PATH:$HOME/onpath/sonar-scanner/bin" 104 | export PATH="$PATH:$HOME/.google-cloud-sdk/bin" 105 | # source '/Users/mac/lib/azure-cli/az.completion' 106 | 107 | # Following https://wilsonmar/github.io/jmeter-install :: 108 | export PATH="/usr/local/Cellar/jmeter/3.3/libexec/bin:$PATH" 109 | export JMETER_HOME=/usr/local/Cellar/jmeter/3.3/libexec # if installed using Homebrew 110 | 111 | export ANDROID_SDK_ROOT="/usr/local/share/android-sdk" 112 | export ANT_HOME=/usr/local/opt/ant 113 | export PATH=$ANT_HOME/bin:$PATH 114 | 115 | export MAVEN_HOME=/usr/local/opt/maven 116 | export PATH=$MAVEN_HOME/bin:$PATH 117 | 118 | export GRADLE_HOME=/usr/local/opt/gradle 119 | export PATH=$GRADLE_HOME/bin:$PATH 120 | 121 | export ANDROID_HOME=/usr/local/opt/android-sdk 122 | export ANDROID_NDK_HOME=/usr/local/opt/android-ndk 123 | export PATH=$PATH:$ANDROID_HOME/tools 124 | export PATH=$PATH:$ANDROID_HOME/platform-tools 125 | export PATH=$PATH:$ANDROID_HOME/build-tools/19.1.0 126 | if [ -f /Users/wilsonmar/.git-completion.bash ]; then 127 | . /Users/wilsonmar/.git-completion.bash 128 | fi 129 | 130 | # mac-bash-profile.txt in https://github.com/wilsonmar/git-utilities 131 | # For paste into ~/.bash_profile 132 | 133 | alias c="clear" 134 | alias p="pwd" 135 | alias sbp='source ~/.bash_profile' 136 | alias rs='exec -l $SHELL' 137 | 138 | alias dir='ls -alr' 139 | alias ll='ls -FalhG' 140 | 141 | alias gs='git status -s -b' 142 | alias grm='git rm $(git ls-files --deleted)' 143 | alias gb='git branch -avv' 144 | function gd() { # get dirty 145 | [[ $(git status 2> /dev/null | tail -n1) != *"working directory clean"* ]] && echo "*" 146 | } 147 | function parse_git_branch() { 148 | git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1$(gd)/" 149 | } 150 | alias get='git pull' 151 | alias gf='git fetch;git diff master..origin/master' 152 | alias gmo='git merge origin/master' 153 | alias ga='git add .' 154 | alias gc='git commit -m' # requires you to type a commit message 155 | alias gl='clear;git status;git log --pretty=format:"%h %s %ad" --graph --since=1.days --date=relative;git log --show-signature -n 1' 156 | alias gbs='git status;git add . -A;git commit -m"Update";git push' 157 | function gas() { git status ; git add . -A ; git commit -m "$1" ; git push; } 158 | alias gp='git push' 159 | 160 | # For more Mac aliases, see https://gist.github.com/natelandau/10654137 161 | # described at https://natelandau.com/my-mac-osx-bash_profile/ 162 | # https://github.com/clvv/fasd 163 | 164 | alias p4merge='/Applications/p4merge.app/Contents/MacOS/p4merge' 165 | export EDITOR="/usr/local/bin/mate -w" 166 | alias sts='open -a "/Applications/STS.app"' 167 | alias eclipse='open "/Applications/Eclipse.app"' 168 | alias subl='open -a "/Applications/Sublime Text.app"' 169 | alias textedit='open -a "/Applications/TextEdit.app"' 170 | export PATH="$PATH:/usr/local/bin/chromedriver" 171 | alias macvim='open -a "/Applications/MacVim.app"' 172 | alias tf="terraform $1" 173 | alias tfa="terraform apply" 174 | alias tfd="terraform destroy" 175 | alias tfs="terraform show" 176 | export CLICOLOR=1 177 | export ARCHFLAGS="-arch x86_64" 178 | alias idea='open -a "/Applications/IntelliJ IDEA CE.app"' 179 | export alias python=/usr/local/bin/python2.7 180 | export PATH="/usr/local/opt/python/libexec/bin:/usr/local/opt/gradle/bin:/usr/local/opt/maven/bin:/usr/local/opt/ant/bin:/usr/local/Cellar/jmeter/3.3/libexec/bin:/Users/wilsonmar/gits/wilsonmar/git-utilities/git-custom-commands:/Users/wilsonmar/gits:/usr/local/bin:/usr/bin:/bin:/sbin:/usr/local/share/dotnet:/usr/local/Cellar/maven/3.5.0/libexec/bin:/Users/wilsonmar/onpath/sonar-scanner/bin:/Users/wilsonmar/.google-cloud-sdk/bin:/usr/local/opt/android-sdk/tools:/usr/local/opt/android-sdk/platform-tools:/usr/local/opt/android-sdk/build-tools/19.1.0:/usr/local/bin/chromedriver" 181 | alias gcs='cd ~/.google-cloud-sdk;ls' 182 | export NVM_DIR="/Users/wilsonmar/.nvm" 183 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://github.com/alexkaratarakis/gitattributes for templates 2 | # .gitattributes specifies handling of line endings automatically for files detected as text 3 | # and leave all files detected as binary untouched: 4 | * text=auto 5 | # The above will handle all files NOT found below: 6 | # These files are text and should be normalized (Convert crlf => lf) 7 | *.gitattributes text 8 | .gitignore text 9 | *.md text 10 | *.psd filter=lfs diff=lfs merge=lfs -text 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore file 2 | 3 | *.log 4 | secrets.sh 5 | .gitsecret/ 6 | temp 7 | tempfile 8 | temp.sh 9 | foo 10 | mac-git-install.log 11 | 12 | sisters 13 | git-sample-repo 14 | 15 | # For more see https://gitignore.com 16 | ############# Mac OS ################### 17 | .DS_Store 18 | .DS_S* 19 | Desktop.ini 20 | 21 | # Files that might appear on external disks: 22 | .Spotlight-V100 23 | .Trashes 24 | 25 | # Thumbnail cache files: 26 | ._* 27 | Thumbs.db 28 | 29 | 30 | # Thanks to https://github.com/anirbanroydas/DevOps/blob/master/.gitignore 31 | ############# Python ################### 32 | 33 | # Byte-compiled / optimized / DLL files 34 | __pycache__/ 35 | *.py[cod] 36 | *$py.class 37 | 38 | # C extensions: 39 | *.so 40 | 41 | # Distribution / packaging: 42 | .Python 43 | env/ 44 | build/ 45 | develop-eggs/ 46 | dist/ 47 | downloads/ 48 | eggs/ 49 | .eggs/ 50 | lib/ 51 | lib64/ 52 | parts/ 53 | sdist/ 54 | var/ 55 | *.egg-info/ 56 | .installed.cfg 57 | *.egg 58 | 59 | # PyInstaller: 60 | # Usually these files are written by a python script from a template 61 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 62 | *.manifest 63 | *.spec 64 | 65 | # Installer logs: 66 | pip-log.txt 67 | pip-delete-this-directory.txt 68 | 69 | # Unit test / coverage reports: 70 | htmlcov/ 71 | .tox/ 72 | .coverage 73 | .coverage.* 74 | .cache 75 | nosetests.xml 76 | coverage.xml 77 | *,cover 78 | 79 | # Translations: 80 | *.mo 81 | *.pot 82 | 83 | # Django stuff: 84 | *.log 85 | 86 | # Sphinx documentation: 87 | docs/_build/ 88 | docs/_static/ 89 | docs/_templates/ 90 | 91 | # PyBuilder: 92 | target/ 93 | 94 | #IPython Notebook: 95 | .ipynb_checkpoints 96 | 97 | #pyenv: 98 | .python-version 99 | 100 | # windows related: 101 | # *.bat 102 | 103 | # backup files: 104 | *.bak 105 | 106 | 107 | ################### Node js ################################3 108 | 109 | # Logs: 110 | logs 111 | *.log 112 | npm-debug.log* 113 | 114 | # Runtime data: 115 | pids 116 | *.pid 117 | *.seed 118 | *.pid.lock 119 | 120 | # Distribution / packaging: 121 | build/ 122 | 123 | # Directory for instrumented libs generated by jscoverage/JSCover: 124 | lib-cov 125 | 126 | # Coverage directory used by tools like istanbul: 127 | coverage 128 | 129 | # nyc test coverage: 130 | .nyc_output 131 | 132 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files): 133 | .grunt 134 | 135 | # node-waf configuration: 136 | .lock-wscript 137 | 138 | # Compiled binary addons (http://nodejs.org/api/addons.html): 139 | build/Release 140 | 141 | # Dependency directories: 142 | node_modules 143 | jspm_packages 144 | 145 | # Optional npm cache directory: 146 | .npm 147 | 148 | # Optional eslint cache: 149 | .eslintcache 150 | 151 | # Optional REPL history: 152 | .node_repl_history 153 | 154 | .gitsecret/keys/random_seed 155 | -------------------------------------------------------------------------------- /.gitignore_global: -------------------------------------------------------------------------------- 1 | # .gitignore file 2 | 3 | *.log 4 | secrets.sh 5 | .gitsecret/ 6 | temp 7 | tempfile 8 | temp.sh 9 | foo 10 | mac-git-install.log 11 | 12 | sisters 13 | git-sample-repo 14 | geckodriver.log 15 | 16 | # For more see https://gitignore.com 17 | ############# Mac OS ################### 18 | .DS_Store 19 | .DS_S* 20 | Desktop.ini 21 | 22 | # Files that might appear on external disks: 23 | .Spotlight-V100 24 | .Trashes 25 | 26 | # Thumbnail cache files: 27 | ._* 28 | Thumbs.db 29 | 30 | 31 | # Thanks to https://github.com/anirbanroydas/DevOps/blob/master/.gitignore 32 | ############# Python ################### 33 | 34 | # Byte-compiled / optimized / DLL files 35 | __pycache__/ 36 | *.py[cod] 37 | *$py.class 38 | 39 | # C extensions: 40 | *.so 41 | 42 | # Distribution / packaging: 43 | .Python 44 | env/ 45 | build/ 46 | develop-eggs/ 47 | dist/ 48 | downloads/ 49 | eggs/ 50 | .eggs/ 51 | lib/ 52 | lib64/ 53 | parts/ 54 | sdist/ 55 | var/ 56 | *.egg-info/ 57 | .installed.cfg 58 | *.egg 59 | 60 | # PyInstaller: 61 | # Usually these files are written by a python script from a template 62 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 63 | *.manifest 64 | *.spec 65 | 66 | # Installer logs: 67 | pip-log.txt 68 | pip-delete-this-directory.txt 69 | 70 | # Unit test / coverage reports: 71 | htmlcov/ 72 | .tox/ 73 | .coverage 74 | .coverage.* 75 | .cache 76 | nosetests.xml 77 | coverage.xml 78 | *,cover 79 | 80 | # Translations: 81 | *.mo 82 | *.pot 83 | 84 | # Django stuff: 85 | *.log 86 | 87 | # Sphinx documentation: 88 | docs/_build/ 89 | docs/_static/ 90 | docs/_templates/ 91 | 92 | # PyBuilder: 93 | target/ 94 | 95 | #IPython Notebook: 96 | .ipynb_checkpoints 97 | 98 | #pyenv: 99 | .python-version 100 | 101 | # windows related: 102 | # *.bat 103 | 104 | # backup files: 105 | *.bak 106 | 107 | 108 | ################### Node js ################################3 109 | 110 | # Logs: 111 | logs 112 | *.log 113 | npm-debug.log* 114 | 115 | # Runtime data: 116 | pids 117 | *.pid 118 | *.seed 119 | *.pid.lock 120 | 121 | # Distribution / packaging: 122 | build/ 123 | 124 | # Directory for instrumented libs generated by jscoverage/JSCover: 125 | lib-cov 126 | 127 | # Coverage directory used by tools like istanbul: 128 | coverage 129 | 130 | # nyc test coverage: 131 | .nyc_output 132 | 133 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files): 134 | .grunt 135 | 136 | # node-waf configuration: 137 | .lock-wscript 138 | 139 | # Compiled binary addons (http://nodejs.org/api/addons.html): 140 | build/Release 141 | 142 | # Dependency directories: 143 | node_modules 144 | jspm_packages 145 | 146 | # Optional npm cache directory: 147 | .npm 148 | 149 | # Optional eslint cache: 150 | .eslintcache 151 | 152 | # Optional REPL history: 153 | .node_repl_history 154 | 155 | .gitsecret/keys/random_seed 156 | -------------------------------------------------------------------------------- /.gitsecret/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wilsonmar/git-utilities/21f7b904833a57289bab6ee144e5ec7185361144/.gitsecret/.DS_Store -------------------------------------------------------------------------------- /.gitsecret/keys/mapping.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wilsonmar/git-utilities/21f7b904833a57289bab6ee144e5ec7185361144/.gitsecret/keys/mapping.cfg -------------------------------------------------------------------------------- /.gitsecret/keys/pubring.kbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wilsonmar/git-utilities/21f7b904833a57289bab6ee144e5ec7185361144/.gitsecret/keys/pubring.kbx -------------------------------------------------------------------------------- /.gitsecret/keys/pubring.kbx~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wilsonmar/git-utilities/21f7b904833a57289bab6ee144e5ec7185361144/.gitsecret/keys/pubring.kbx~ -------------------------------------------------------------------------------- /.gitsecret/keys/trustdb.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wilsonmar/git-utilities/21f7b904833a57289bab6ee144e5ec7185361144/.gitsecret/keys/trustdb.gpg -------------------------------------------------------------------------------- /.gitsecret/paths/mapping.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wilsonmar/git-utilities/21f7b904833a57289bab6ee144e5ec7185361144/.gitsecret/paths/mapping.cfg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2018 Wilson Mar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /alias-functions.sh: -------------------------------------------------------------------------------- 1 | # alias-functions.txt in https://github.com/wilsonmar/git-utilities 2 | # For concatenating/pasting into ~/.bash_profile 3 | # on MacOS only, not in git bash for windows. 4 | 5 | function gd() { # get dirty 6 | [[ $(git status 2> /dev/null | tail -n1) != *"working directory clean"* ]] && echo "*" 7 | } 8 | function gas() { git status ; git add . -A ; git commit -m "$1" ; git push; } 9 | function gsa() { git stash save "$1" -a; git stash list; } # -a = all (untracked, ignored) 10 | 11 | 12 | # color code next line based on previous commands return code.. 13 | bash_prompt_command() 14 | { 15 | RTN=$? 16 | prevCmd=$(prevCmd $RTN) 17 | } 18 | PROMPT_COMMAND=bash_prompt_command 19 | prevCmd() 20 | { 21 | if [ $1 == 0 ] ; then 22 | echo $GREEN 23 | else 24 | echo $RED 25 | fi 26 | } 27 | if [ $(tput colors) -gt 0 ] ; then 28 | RED=$(tput setaf 1) 29 | GREEN=$(tput setaf 2) 30 | RST=$(tput op) 31 | fi 32 | export PS1="[e[36m]u.h.W[e[0m][$prevCmd]>[$RST]" 33 | 34 | #For use on Mac only (not Windows Git Bash): 35 | function parse_git_branch() { 36 | git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1$(gd)/" 37 | } 38 | # This enables: 39 | #export PS1="\n \w\[\033[33m\] \$(parse_git_branch)\[\033[00m\]\n$ " 40 | # instead of: 41 | export PS1="\n\n \w\[\033[33m\] \n$ " 42 | 43 | # On Mac only: 44 | # alias ss="/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background &" 45 | 46 | ### Get os name via uname ### 47 | _myos="$(uname)" 48 | 49 | ### add alias as per os using $_myos ### 50 | case $_myos in 51 | Linux) alias foo='/path/to/linux/bin/foo';; 52 | FreeBSD|OpenBSD) alias foo='/path/to/bsd/bin/foo' ;; 53 | SunOS) alias foo='/path/to/sunos/bin/foo' ;; 54 | *) ;; 55 | esac 56 | 57 | 58 | # To convert between number bases: 59 | d2b() { 60 | [ -z "$1" ] && echo "usage: d2b decnumber" && return 1 61 | echo "obase=2; $1" | bc 62 | } 63 | d2h() { 64 | [ -z "$1" ] && echo "usage: d2h decnumber" && return 1 65 | echo "obase=16; $1" | bc 66 | } 67 | h2b() { 68 | [ -z "$1" ] && echo "usage: h2b hexnumber" && return 1 69 | echo "obase=2; ibase=16; " `echo $1 | tr '[a-zxX]*' '[A-Z00]'` | bc 70 | } 71 | h2d() { 72 | [ -z "$1" ] && echo "usage: h2d hexnumber" && return 1 73 | echo "ibase=16; " `echo $1 | tr '[a-zxX]*' '[A-Z00]'` | bc 74 | } 75 | b2d() { 76 | [ -z "$1" ] && echo "usage: b2d binnumber" && return 1 77 | echo "ibase=2; $1" | bc 78 | } 79 | b2h() { 80 | [ -z "$1" ] && echo "usage: b2h binnumber" && return 1 81 | echo "obase=16; ibase=2; $1" | bc 82 | } 83 | -------------------------------------------------------------------------------- /aliases.sh: -------------------------------------------------------------------------------- 1 | # aliases.sh in https://github.com/wilsonmar/git-utilities 2 | # NOTE: Functions are in functions.sh for Mac only. 3 | # Both called from ~/.bash_profile for Bash or ~/.zshrc for zsh 4 | # on both MacOS and git bash on Windows. 5 | 6 | EDITOR="code" # code = Visual Studio Code; subl = Sublime Text 7 | alias edit="code" # change this, not your habitual editor name 8 | alias ebp="$EDITOR ~/.bash_profile && source ~/.bash_profile" 9 | alias sbp='source ~/.bash_profile' 10 | alias rs='exec -l $SHELL' 11 | 12 | alias ..='cd ..' 13 | alias c="clear" # screen 14 | alias h='history' 15 | alias x='exit' 16 | alias p="pwd" # present working directory 17 | 18 | alias kp="ps auxwww" # the "kp" alias ("que pasa") 19 | alias j='jobs -l' 20 | 21 | alias now='date +"%Y-%m-%d %T +%s"' 22 | 23 | # Only on MacOS, not git bash on Windows MINGW64: 24 | #if [ "$(uname)" == "Darwin" ]; then # it's on a Mac: 25 | # alias vers="sw_vers" 26 | # function gd() { # get dirty 27 | # [[ $(git status 2> /dev/null | tail -n1) != *"working directory clean"* ]] && echo "*" 28 | # } 29 | # function gas() { git status ; git add . -A ; git commit -m "$1" ; git push; } 30 | # function gsa() { git stash save "$1" -a; git stash list; } # -a = all (untracked, ignored) 31 | #fi 32 | 33 | alias cf="find . -print | wc -l" # count files in folder. 34 | alias lf="ls -p" # list folders only 35 | alias dir='ls -alrT' # for windows habits 36 | alias l='ls -FalhGT' # T for year 37 | alias ll='ls -FalhGT' # T for year 38 | alias lt="ls -ltaT" # list by date 39 | # Last 30 files updated anywhere: 40 | alias f50='stat -f "%m%t%Sm %N" /tmp/* | sort -rn | head -50 | cut -f2- 2>/dev/null' 41 | 42 | # catn filename to show text file without comment (#) lines: 43 | alias catn="grep -Ev '''^(#|$)'''" 44 | 45 | # wireless en0, wired en1: PRIVATE_IP address: 46 | alias en0="ipconfig getifaddr en0" # like 172.20.1.91 or 192.168.1.253 47 | #alias myip="ifconfig en0 | grep inet | grep -v inet6 | cut -d ' ' -f2" 48 | # ip route get 1 | awk '{print $NF;exit}' 49 | 50 | # These all return the public ip like https://www.whatismyip.com/: 51 | alias pubip="curl -s ifconfig.me" # public IP 52 | alias ipinfo="curl ipinfo.io" # returns JSON containing country and zip of IP 53 | #alias pubip="curl https://checkip.amazonaws.com" # public IP 54 | #alias mac="curl http://canhazip.com" # public IP 55 | 56 | alias aam='open -a "/Applications/Utilities/Activity Monitor.app"' # See CPU usage by app 57 | alias ramfree="top -l 1 -s 0 | grep PhysMem" # PhysMem: 30G used (3693M wired), 1993M unused. 58 | alias spacefree="du -h | awk 'END{print $1}'" 59 | alias wanip4='dig @resolver1.opendns.com ANY myip.opendns.com +short' 60 | alias wanip6='dig @resolver1.opendns.com AAAA myip.opendns.com +short -6' 61 | 62 | alias ddk="killall com.docker.osx.hyperkit.linux" # docker restart 63 | alias dps="docker ps" # docker processes list 64 | alias dcl="docker container ls -aq" # docker list active container 65 | alias dsa="docker stop $(docker container ls -aq )" # docker stop active container 66 | alias dpa="docker container prune --force" # Remove all stopped containers 67 | alias dpx="docker rm -v $(docker ps -aq -f status=exited)" # Remove stopped containers 68 | 69 | alias ga='git add . -A' # --patch 70 | alias gb='git branch -avv' 71 | alias gbs='git status -s -b;git add . -A;git commit --quiet -m"Update";git push' 72 | alias get='git fetch;' # git pull + merge 73 | alias gf='git fetch origin master;git diff master..origin/master' 74 | alias gfu='git fetch upstream;git diff HEAD @{u} --name-only' 75 | alias gc='git commit -m --quiet' # requires you to type a commit message 76 | alias gcm='git checkout master' 77 | alias gl='git log --pretty=format:"%h %s %ad" --graph --since=1.days --date=relative;git log --show-signature -n 1' 78 | alias gl1="git log --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative" 79 | alias gl2="git log --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative" 80 | alias gmo='git merge origin/master' 81 | alias gmf='git merge --no-ff' 82 | alias gp='git push' 83 | alias gpom='git push -u origin master' 84 | alias grm='git rm $(git ls-files --deleted)' 85 | alias gri='git rebase -i' 86 | alias grl='git reflog -n 7' 87 | alias grh='git reset --hard' 88 | alias grl='git reflog -n 7' 89 | alias grv='git remote -v' 90 | alias gsl='git config user.email;git status -s -b; git stash list' 91 | alias gss='git stash show' 92 | alias hb="hub browse" 93 | alias grx="rm .git/merge" # Remove merge 94 | alias gsk="gpg --list-secret-keys --keyid-format LONG" 95 | alias gst="gpg show-ref --tags" 96 | 97 | alias tf="terraform $1" # provide a parameter 98 | alias tfa="terraform apply" 99 | alias tfd="terraform destroy" 100 | alias tfs="terraform show" 101 | 102 | alias ven="virtualenv venv" 103 | alias vbc="source venv/bin/activate" 104 | alias vde="deactivate" 105 | 106 | #if command -v docker >/dev/null; then # installed in /usr/local/bin/docker 107 | # echo "Docker installed, so ..." 108 | # alias dockx="docker stop $(docker ps -a -q);docker rm -f $(docker ps -a -q)" 109 | #fi 110 | # See https://github.com/ysmike/dotfiles/blob/master/bash/.aliases 111 | # More: https://www.cyberciti.biz/tips/bash-aliases-mac-centos-linux-unix.html 112 | 113 | alias wmx='cd $HOME/gits/wilsonmar' 114 | alias wmf='cd $HOME/gits/wilsonmar/futures' 115 | alias wmo='cd $HOME/gits/wilsonmar/wilsonmar.github.io/_posts' 116 | alias wmb='cd $HOME/gits/wilsonmar/DevSecOps/bash' 117 | alias wmp='cd $HOME/gits/wilsonmar/python-samples' 118 | alias wmg='cd $HOME/gits/wilsonmar/golang-samples' 119 | -------------------------------------------------------------------------------- /configs/java-junit4-maven.xml: -------------------------------------------------------------------------------- 1 | 2 | junit 3 | junit 4 | 4.8.2 5 | test 6 | -------------------------------------------------------------------------------- /configs/java-mockito-maven.xml: -------------------------------------------------------------------------------- 1 | 2 | org.mockito 3 | mockito-core 4 | 1.9.5 5 | test 6 | -------------------------------------------------------------------------------- /configs/java-testng-maven.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | jcenter 4 | bintray 5 | http://jcenter.bintray.com 6 | 7 | 8 | 9 | 10 | org.testng 11 | testng 12 | 6.10 13 | test 14 | -------------------------------------------------------------------------------- /configs/junit5-maven.xml: -------------------------------------------------------------------------------- 1 | 2 | org.junit.jupiter 3 | junit-jupiter-engine 4 | 5.1.0 5 | test 6 | -------------------------------------------------------------------------------- /configs/limit.maxfiles.plist: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Label 7 | limit.maxfiles 8 | ProgramArguments 9 | 10 | launchctl 11 | limit 12 | maxfiles 13 | 65536 14 | 65536 15 | 16 | RunAtLoad 17 | 18 | ServiceIPC 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /configs/limit.maxproc.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | limit.maxproc 7 | ProgramArguments 8 | 9 | launchctl 10 | limit 11 | maxproc 12 | 2048 13 | 2048 14 | 15 | RunAtLoad 16 | 17 | ServiceIPC 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /configs/soton-test-python-installation.py: -------------------------------------------------------------------------------- 1 | # Python program that can be executed to report whether particular 2 | # python packages are available on the system. 3 | 4 | import math 5 | import os 6 | import sys 7 | 8 | 9 | def test_is_python_35(): 10 | major = sys.version_info.major 11 | minor = sys.version_info.minor 12 | if major == 3: 13 | pass 14 | else: 15 | print("You are running Python {}, but we need Python {}.".format(major, 3)) 16 | print("Download and install the Anaconda distribution for Python 3.") 17 | print("Stopping here.") 18 | 19 | # Let's stop here 20 | sys.exit(1) 21 | return None 22 | # assert major == 3, "Stopping here - we need Python 3." 23 | 24 | if minor >= 5: 25 | print("Testing Python version-> py{}.{} OK".format(major, minor)) 26 | else: 27 | print("Warning: You should be running Python 3.5 or newer, " + 28 | "you have Python {}.{}.".format(major, minor)) 29 | 30 | 31 | def test_numpy(): 32 | try: 33 | import numpy as np 34 | except ImportError: 35 | print("Could not import numpy -> numpy failed") 36 | return None 37 | # Simple test 38 | a = np.arange(0, 100, 1) 39 | assert np.sum(a) == sum(a) 40 | print("Testing numpy... -> numpy OK") 41 | 42 | 43 | def test_scipy(): 44 | try: 45 | import scipy 46 | except ImportError: 47 | print("Could not import 'scipy' -> scipy failed") 48 | return None 49 | # Simple test 50 | import scipy.integrate 51 | assert abs(scipy.integrate.quad(lambda x: x * x, 0, 6)[0] - 72.0) < 1e-6 52 | print("Testing scipy ... -> scipy OK") 53 | 54 | 55 | def test_pylab(): 56 | """Actually testing matplotlib, as pylab is part of matplotlib.""" 57 | try: 58 | import pylab 59 | except ImportError: 60 | print("Could not import 'matplotlib/pylab' -> failed") 61 | return None 62 | # Creata plot for testing purposes 63 | xvalues = [i * 0.1 for i in range(100)] 64 | yvalues = [math.sin(x) for x in xvalues] 65 | pylab.plot(xvalues, yvalues, "-o", label="sin(x)") 66 | pylab.legend() 67 | pylab.xlabel('x') 68 | testfilename='pylab-testfigure.png' 69 | 70 | # check that file does not exist yet: 71 | if os.path.exists(testfilename): 72 | print("Skipping plotting to file as file {} exists already."\ 73 | .format(testfilename)) 74 | else: 75 | # Write plot to file 76 | pylab.savefig(testfilename) 77 | # Then check that file exists 78 | assert os.path.exists(testfilename) 79 | print("Testing matplotlib... -> pylab OK") 80 | os.remove(testfilename) 81 | 82 | 83 | def test_sympy(): 84 | try: 85 | import sympy 86 | except ImportError: 87 | print("Could not import 'sympy' -> fail") 88 | return None 89 | # simple test 90 | x = sympy.Symbol('x') 91 | my_f = x ** 2 92 | assert sympy.diff(my_f,x) == 2 * x 93 | print("Testing sympy -> sympy OK") 94 | 95 | 96 | def test_pytest(): 97 | try: 98 | import pytest 99 | except ImportError: 100 | print("Could not import 'pytest' -> fail") 101 | return None 102 | print("Testing pytest -> pytest OK") 103 | 104 | 105 | if __name__ == "__main__": 106 | 107 | print("Running using Python {}".format(sys.version)) 108 | test_is_python_35() 109 | test_numpy() 110 | test_scipy() 111 | test_pylab() 112 | test_sympy() 113 | test_pytest() 114 | -------------------------------------------------------------------------------- /create-conflict.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # From https://gist.github.com/JonathanMH/397fc427842614dd4803 3 | # Described in https://jonathanmh.com/how-to-create-a-git-merge-conflict/ 4 | mkdir git-repo 5 | cd git-repo 6 | git init 7 | touch my_code.sh 8 | git add my_code.sh 9 | echo "echo Hello" > my_code.sh 10 | git commit -am 'initial' 11 | git checkout -b new_branch 12 | echo "echo \"Hello World\"" > my_code.sh 13 | git commit -am 'first commit on new_branch' 14 | git checkout master 15 | echo "echo \"Hello World!\"" > my_code.sh 16 | git commit -am 'second commit on master' 17 | git merge new_branch -------------------------------------------------------------------------------- /extract-sample.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # extract-sample.sh 3 | 4 | echo "sec rsa2048/7FA75CBDD0C5721D 2018-03-22 [SC]" | awk -v FS="(rsa2048/| )" '{print $2}' 5 | 6 | echo "------------" 7 | echo 'abcdefg'|tail -c +2|head -c 3 8 | # output bcd 9 | echo "------------" 10 | 11 | fancy_echo "more:" 12 | asd=someletter8/12345_eleters.ext 13 | echo `expr $asd : '.*8/\(.*\)_'` 14 | echo "------------" 15 | 16 | str="/Users/wilsonmar/.gnupg/pubring.kbx 17 | sec rsa2048/7FA75CBDD0C5721D 2018-03-22 [SC] 18 | 12776C492E6CF8C725B2235C7FA75CBDD0C5721D 19 | uid [ultimate] Wilson Mar (2 long enough passphrase) 20 | ssb rsa2048/066F92FE88317144 2018-03-22 [E]" 21 | echo "Extract GPG list between \"rsa2048/\" and \" 2018\" onward:" 22 | str=${str#*rsa2048/} 23 | str=${str%2018*} 24 | 25 | echo " " 26 | echo "Expected:" 27 | echo "KEY=7FA75CBDD0C5721D" 28 | echo " " 29 | echo "Actual:" 30 | echo "KEY=$str" 31 | 32 | echo " " 33 | echo "Note: text after 7FA75CBDD0C5721D should be gone." 34 | 35 | 36 | echo "------------" 37 | # https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable 38 | FOO=' test test test ' 39 | FOO_NO_TRAIL_SPACE="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')" 40 | echo -e "FOO_NO_TRAIL_SPACE='${FOO_NO_TRAIL_SPACE}'" 41 | # > FOO_NO_TRAIL_SPACE=' test test test' 42 | echo -e "length(FOO_NO_TRAIL_SPACE)==${#FOO_NO_TRAIL_SPACE}" 43 | # > length(FOO_NO_TRAIL_SPACE)==15 44 | -------------------------------------------------------------------------------- /fake-bash.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: From https://github.com/wilsonmar/git-utilities/fake-bash.bat 3 | :: Create macros to emulate Linux/Mac BASH commands: 4 | 5 | DOSKEY ls=dir /X 6 | DOSKEY pwd=chdir 7 | DOSKEY ps=tasklist $* 8 | DOSKEY cat=type $1 | more 9 | 10 | :: If Sublime Text editor has been installed: 11 | set PATH=%PATH%;"C:\Program Files\Sublime Text 2\" 12 | DOSKEY subl=sublime_text $* 13 | -------------------------------------------------------------------------------- /foundation-website-init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # foundation-website-init.sh from http://github.com/wilsonmar/git-utilities 3 | # by Wilson Mar (wilsonmar@gmail.com, @wilsonmar) 4 | 5 | TZ=":UTC" date +%z 6 | NOW=$(date +%Y-%m-%d:%H:%M:%S%z) 7 | # 2016-09-16T05:26-06:00 vs UTC 8 | 9 | # Make the beginning of run easy to find: 10 | echo "**********************************************************" 11 | echo "******** $NOW Versions :" 12 | # After "brew install git" on Mac: 13 | git --version 14 | 15 | GITHUB_USER="hotwilson" 16 | REPONAME='website1' 17 | 18 | echo "******** GITHUB_USER=$GITHUB_USER " 19 | 20 | mkdir ~/gits/${GITHUB_USER} 21 | cd ~/gits/${GITHUB_USER} 22 | 23 | echo "******** STEP Delete \"$REPONAME\" remnant from previous run:" 24 | # set -x # xtrace command echo on (with ++ prefix). http://www.faqs.org/docs/abs/HTML/options.html 25 | # Remove folder if exists (no symbolic links are used here): 26 | if [ -d ${REPONAME} ]; then 27 | rm -rf ${REPONAME} 28 | fi 29 | 30 | CURRENTDIR=${PWD##*/} 31 | echo "CURRENTDIR=$CURRENTDIR" 32 | 33 | # exit #3 34 | 35 | 36 | # These can be run from any directory: 37 | # install node 38 | npm install -g foundation-cli 39 | npm i -g npm 40 | # Verify if foundation has been installed or abort: 41 | foundation -version 42 | 43 | # exit #4 44 | 45 | echo ${REPONAME} >website_name 46 | foundation new --framework sites --template zurb >> $fmt\\n" "$@" 34 | } 35 | function echo_g() { # echo fancy comment 36 | local fmt="$1"; shift 37 | printf " $fmt\\n" "$@" 38 | } 39 | function echo_c() { # echo command 40 | local fmt="$1"; shift 41 | printf "\\n $ $fmt\\n" "$@" 42 | } 43 | command_exists() { # newer than which {command} 44 | command -v "$@" > /dev/null 2>&1 45 | } 46 | 47 | clear 48 | 49 | # For Git on Windows, see http://www.rolandfg.net/2014/05/04/intellij-idea-and-git-on-windows/ 50 | TIME_START="$(date -u +%s)" 51 | #FREE_DISKBLOCKS_END=$(df | sed -n -e '2{p;q}' | cut -d' ' -f 6) # no longer works 52 | FREE_DISKBLOCKS_START="$(df -P | awk '{print $4}' | sed -n 2p)" # e.g. 342771200 from: 53 | # Filesystem 512-blocks Used Available Capacity Mounted on 54 | # /dev/disk1s1 976490568 611335160 342771200 65% / 55 | LOG_PREFIX=$(date +%Y-%m-%dT%H:%M:%S%z)-$((1 + RANDOM % 1000)) 56 | # ISO-8601 date plus RANDOM=$((1 + RANDOM % 1000)) # 3 digit random number. 57 | # LOGFILE="$0.$LOG_PREFIX.log" 58 | echo_f "1.1 $0 within $PWD " 59 | echo_g "starting at $LOG_PREFIX with $FREE_DISKBLOCKS_START blocks free ..." 60 | 61 | ### OS detection: 62 | echo_c "uname -a" 63 | unamestr=$( uname ) 64 | echo "$unamestr" 65 | UNAME_PREFIX="${unamestr%%-*}" 66 | platform='unknown' 67 | if [[ "$unamestr" == 'Darwin' ]]; then 68 | platform='macos' 69 | elif [[ "$unamestr" == 'Linux' ]]; then 70 | platform='linux' 71 | elif [[ "$unamestr" == 'FreeBSD' ]]; then 72 | platform='freebsd' 73 | elif [[ "$UNAME_PREFIX" == 'MINGW64_NT' ]]; then # MINGW64_NT-6.1 or MINGW64_NT-10 for Windows 10 74 | platform='windows' # systeminfo on windows https://en.wikipedia.org/wiki/MinGW 75 | fi 76 | echo "Platform: $platform" 77 | 78 | 79 | if [[ $platform == 'macos' ]]; then 80 | 81 | echo_c "sw_vers" 82 | echo -e "$(sw_vers)" 83 | echo -e "/n$(xcode-select --version)" # Example: xcode-select version 2354. 84 | 85 | echo_f "1.2 Homebrew:" 86 | # Remove to be done manually. 87 | if ! command_exists brew ; then 88 | RUBY_VERSION="$(ruby --version)" 89 | echo_f "1.2 Installing homebrew using in-built $RUBY_VERSION ..." 90 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 91 | brew tap caskroom/cask 92 | else 93 | # Upgrade if run-time attribute contains "upgrade": 94 | if [[ "${RUNTYPE}" == *"update"* ]]; then 95 | BREW_VERSION="$(brew --version | grep "Homebrew ")" 96 | echo_f "1.2 Brew upgrading $BREW_VERSION ..." 97 | brew update 98 | fi 99 | fi 100 | echo "$(brew --version)" 101 | 102 | 103 | if ! command_exists git ; then 104 | if [[ $platform == 'macos' ]]; then 105 | echo_f "1.3 Installing git using Homebrew ..." 106 | brew install git 107 | fi 108 | fi 109 | GIT_VERSION="$( git --version )" 110 | echo_f "1.3 $GIT_VERSION installed ..." 111 | 112 | 113 | ## Based on https://hub.github.com/ 114 | if ! command_exists hub ; then 115 | if [[ $platform == 'macos' ]]; then 116 | echo_f "1.4a brew install hub # add-in to Git ..." 117 | brew install hub 118 | fi 119 | fi 120 | HUB_VERSION="$( hub version | grep "hub" )" 121 | echo_f "1.4a $HUB_VERSION already installed for Git to manage GitHub." 122 | 123 | # elif [[ $platform == 'linux' ]]; then 124 | # ubuntu 125 | # etc. 126 | 127 | fi 128 | 129 | 130 | ### 131 | cd ~/ 132 | echo_f "1.5 At $PWD ..." 133 | 134 | if [ ! -f "git-basics.env" ]; then 135 | echo_f "1.5 Downloading git-basics.env from GitHub ..." 136 | curl -O "https://raw.githubusercontent.com/wilsonmar/git-utilities/master/git-basics.env" 137 | # 15 bytes Received 138 | else 139 | echo_f "1.5 Using existing git-basics.env ..." 140 | fi 141 | echo_c "source git-basics.env" 142 | source git-basics.env 143 | 144 | echo "GITHOST=$GITHOST" # "github.com" or "gitlab.com" 145 | echo "MYACCT_USER_NAME=$MYACCT_USER_NAME" # "Wilson Mar" 146 | echo "MYACCT_USER_EMAIL=$MYACCT_USER_EMAIL" # "wilsonmar+GitHub@gmail.com" 147 | echo "WORKSPACE_FOLDER=$WORKSPACE_FOLDER" # git-basics-workspace" 148 | echo "MYACCT_USERID=$MYACCT_USERID" # wilsonmar 149 | #echo "MYACCT_PASSWORD should never be displayed. 150 | echo "SAMPLE_REPO=$SAMPLE_REPO" # local-init 151 | echo "OTHER_ACCT=$OTHER_ACCT" # hotwilson" 152 | echo "OTHER_REPO=$OTHER_REPO" # some-repo" 153 | echo "NEW_BRANCH=$NEW_BRANCH" # feat1" 154 | exit 155 | 156 | # Assign userid to be GitHub ID if not changed: 157 | MAC_USERID=$(id -un 2>/dev/null || true) # example: wilsonmar 158 | # echo "MAC_USERID=$MAC_USERID" 159 | if [[ "$MYACCT_USERID" != "wilsonmar" ]]; then # it was changed. 160 | echo_f "1.6 Hello $MYACCT_USERID" 161 | # elif [[ "$MAC_USERID" == *"$MYACCT"* ]]; then 162 | # echo_f "1.6 $MAC_USERID == $MYACCT" 163 | else 164 | echo_f "1.6 Assuming \"$MAC_USERID\" is your GitHub and Gmail account ..." 165 | MYACCT_USERID="$MAC_USERID" 166 | MYACCT_USER_NAME="$MAC_USERID" 167 | MYACCT_USER_EMAIL="$MAC_USERID@gmail.com" 168 | echo "MYACCT_USERID=$MYACCT_USERID" # wilsonmar 169 | echo "MYACCT_USER_NAME=$MYACCT_USER_NAME" # "Wilson Mar" 170 | echo "MYACCT_USER_EMAIL=$MYACCT_USER_EMAIL" # "wilsonmar+GitHub@gmail.com" 171 | fi 172 | 173 | 174 | echo_f "1.6 Create persistent folder git-scripts in $PWD ..." 175 | 176 | if [ ! -d "git-scripts" ]; then 177 | echo_c "mkdir git-scripts && cd git-scripts" 178 | mkdir git-scripts && cd git-scripts 179 | # else 180 | # # if flagged to do it: 181 | # rm -rf git-scripts 182 | # mkdir git-scripts 183 | fi 184 | 185 | 186 | ### 187 | # TODO: Replace if requested in env: 188 | if [ ! -f "git-basics.sh" ]; then 189 | echo_f "1.7 Downloading git-basics.sh from GitHub for next run ..." 190 | curl -O "https://raw.githubusercontent.com/wilsonmar/git-utilities/master/git-basics.sh" 191 | # 10835 bytes Received 192 | else 193 | echo_f "1.7 Using existing git-basics.sh ..." 194 | fi 195 | ls -al git-basics.sh 196 | 197 | 198 | #echo_f "1.8 To halt processing for customizations, press control+c or " 199 | #read -rsp $'1.8 press any key to continue default processing ...\n' -n 1 key 200 | # Comment the above two lines out when you're editing this script for local run. 201 | 202 | ALIAS_FILENAME="aliases.bash" 203 | if [ ! -f "$ALIAS_FILENAME" ]; then 204 | echo_f "1.9 Downloading $ALIAS_FILENAME from GitHub ..." 205 | curl -O "https://raw.githubusercontent.com/wilsonmar/git-utilities/master/$ALIAS_FILENAME" 206 | # 1727 bytes Received 207 | else 208 | echo_f "1.9 Using existing $ALIAS_FILENAME ..." 209 | fi 210 | 211 | BASHFILE="$HOME/.bash_profile" 212 | if [ ! -f "$BASHFILE" ]; then 213 | echo_f "1.10 $BASHFILE not found. Creating it ..." 214 | # echo "Created by git-basics.sh" >>$BASHFILE 215 | else 216 | echo_f "1.10 $BASHFILE found ..." 217 | ls -al "$BASHFILE" # 9462 bytes 218 | fi 219 | 220 | if grep "$ALIAS_FILENAME" "$BASHFILE" ; then # already in file: 221 | echo_f "1.11 $ALIAS_FILENAME already found in $BASHFILE." 222 | else 223 | echo_f "1.11 Concatenating aliases file $ALIAS_FILENAME into $BASHFILE ..." 224 | ls -al "$BASHFILE" 225 | ls -al "$ALIAS_FILENAME" 226 | echo "$ALIAS_FILENAME" >>"$BASHFILE" 227 | echo_c "source \"$BASHFILE\" " 228 | source "$BASHFILE" # requires password. 229 | # ./git-basics.sh: line 143: ~/.bash_profile: No such file or directory 230 | fi 231 | 232 | echo_f "1.12 Volatile WORKSPACE_FOLDER=$WORKSPACE_FOLDER ..." 233 | # Delete folder from last run: 234 | cd ~/ 235 | rm -rf "$WORKSPACE_FOLDER" 236 | mkdir "$WORKSPACE_FOLDER" 237 | cd "$WORKSPACE_FOLDER" 238 | echo_c "cd \$WORKSPACE_FOLDER" 239 | echo "at pwd=$PWD ..." 240 | 241 | 242 | echo_f "2.1 Git Config ..." 243 | 244 | echo_f "2.1 Attribution for git commits ..." 245 | echo_c "git config --global user.name \"MYACCT_USER_NAME\"" 246 | git config --global user.name "$MYACCT_USER_NAME" 247 | # git config --global user.name "wilson Mar" 248 | 249 | echo_c "git config --global user.email \"$MYACCT_USER_EMAIL\"" 250 | git config --global user.email "$MYACCT_USER_EMAIL" 251 | # git config --global user.email "wilsonmar+GitHub@gmail.com" 252 | 253 | echo_f "2.2 sample global git config..." 254 | echo_c "git config --global core.safecrlf false" 255 | git config --global core.safecrlf false 256 | 257 | echo_f "2.3 git config --list # (could be a long file) ..." 258 | # git config --list 259 | 260 | # difftool command (after installing DiffMerge) analyzes differences among 3 files 261 | # Per https://sourcegear.com/diffmerge/webhelp/sec__git__mac.html 262 | git config --global diff.tool diffmerge 263 | git config --global difftool.diffmerge.cmd "/usr/local/bin/diffmerge \"\$LOCAL\" \"\$REMOTE\"" 264 | git config --global merge.tool diffmerge 265 | git config --global mergetool.diffmerge.trustExitCode true 266 | git config --global mergetool.diffmerge.cmd \ 267 | "/usr/local/bin/diffmerge --merge --result=\"\$MERGED\" \ 268 | \"\$LOCAL\" \"\$BASE\" \"\$REMOTE\"" 269 | 270 | # Change the font size: 271 | # open -e "$HOME/Library/Preferences/SourceGear DiffMerge preferences" 272 | # [file] 273 | # Font:27:76:consolas 274 | 275 | echo_f "2.4 NO Create gits folder ..." 276 | 277 | echo_f "2.5 NO myacct container ..." 278 | 279 | 280 | 281 | echo_f "3.1 ssh-keygen is done manually, just once." 282 | 283 | echo_c "ls -a ~/.ssh" 284 | ls -a ~/.ssh 285 | 286 | echo_f "3.3 Manually delete $MYACCT_USERID/$OTHER_REPO so this script can create a new one ..." 287 | read -rsp $'Press any key after deleting the repo ...\n' -n 1 key 288 | 289 | echo_f "3.4 Use hub to clone \"$OTHER_ACCT/$OTHER_REPO\" ..." 290 | echo_c "cd && cd \"$WORKSPACE_FOLDER\" " 291 | cd && cd "$WORKSPACE_FOLDER" 292 | 293 | # Check if repo exists: if you have credentials for it: 294 | # git ls-remote "$OTHER_ACCT/$OTHER_REPO" -q 295 | # -q if for quieting list of hashes. 296 | # git ls-remote https://github.com/hotwilson/some-repo -q 297 | # Username for 'https://github.com': 298 | # echo $? 299 | # 0 means that the repo was found, otherwise you'll get a non-zero value. 300 | # See https://gist.github.com/salcode/342391ccbaa8cbf48567 = Notes for bash scripting git commands 301 | 302 | echo_c "hub clone \"$OTHER_ACCT/$OTHER_REPO\"" 303 | hub clone "$OTHER_ACCT/$OTHER_REPO" # hotwilson/some-repo" 304 | echo_c "cd \"$OTHER_REPO\" && PWD && git remote -v && ls -al ..." 305 | cd "$OTHER_REPO" 306 | echo "PWD=$PWD" 307 | git remote -v 308 | ls -al 309 | 310 | echo_f "3.5 Use hub to fork \"$OTHER_ACCT/$OTHER_REPO\" ..." 311 | echo_c "hub fork \"$OTHER_ACCT/$OTHER_REPO\"" 312 | hub fork "$OTHER_ACCT/$OTHER_REPO" 313 | 314 | echo_c "cd \"$OTHER_REPO\" && PWD && git remote -v && ls -al ..." 315 | cd "$OTHER_REPO" 316 | echo "PWD=$PWD" 317 | git remote -v 318 | ls -al 319 | 320 | echo_c "hub remote add \"$MYACCT_USERID\"" 321 | hub remote add "$MYACCT_USERID" # wilsonmar 322 | 323 | echo_c "git remote rename origin upstream" 324 | git remote rename origin upstream 325 | 326 | echo_c "git remote rename "$MYACCT_USERID" origin" 327 | git remote rename "$MYACCT_USERID" origin 328 | 329 | echo_c "git pull --all" 330 | git pull --all 331 | 332 | echo_f "3.5 git remote -v" 333 | git remote -v 334 | 335 | # 1. fork https://github.com/hotwilson/some-repo to wilsonmar 336 | 337 | #echo_f "4.2 git clone $MYACCT_USERID/$SAMPLE_REPO ..." 338 | # if RUNTYPE != "reuse" 339 | # git clone "git@github.com:$MYACCT_USERID/$SAMPLE_REPO" --depth=1 340 | 341 | echo_f "3.7 cd into repo $MYACCT_USERID/$SAMPLE_REPO ..." 342 | cd "$SAMPLE_REPO" 343 | echo "PWD=$PWD" 344 | 345 | echo_f "3.8 ls -al files and folders at $PWD ..." 346 | ls -al 347 | 348 | echo_f "3.9 git remote -v = remote ..." 349 | git remote -v 350 | 351 | echo_f "3.10 git branch -avv (to list master ..." 352 | git branch -avv 353 | 354 | 355 | echo_f "4.1 Checkout new branch ..." 356 | echo_c "git checkout -b \"$NEW_BRANCH\"" 357 | git checkout -b "$NEW_BRANCH" 358 | 359 | echo_f "4.2 git branch -avv" 360 | git branch -avv 361 | 362 | echo_f "4.3 Add and configure .gitignore file ..." 363 | 364 | echo_c "echo \"peace\" >newfile.md" 365 | echo "peace" >newfile.md 366 | 367 | if [ ! -d ".gitignore" ]; then # NOT found: 368 | echo_c "touch .gitignore" 369 | touch .gitignore 370 | fi 371 | 372 | if ! grep -q ".DS_Store" ".gitignore" ; then # NOT in file : 373 | echo_c "echo -e \".DS_Store\" >>.gitignore" 374 | echo -e "\n.DS_Store" >>.gitignore 375 | fi 376 | 377 | echo_f "4.4 tail -3 .gitignore to view last 3 lines of contents:" 378 | tail -3 .gitignore 379 | 380 | echo_f "4.5 git status -s -b [gsl]" 381 | git status -s -b 382 | 383 | 384 | echo_f "5.1 cat .git/config # attribution for local repo" 385 | cat .git/config 386 | 387 | echo_f "5.2 git diff --cached" 388 | git diff --cached 389 | 390 | echo_f "5.3 git add . -A " 391 | git add . -A 392 | 393 | echo_f "5.4 git diff --cached" 394 | git diff --cached 395 | 396 | echo_f "5.5 git status -s -b [gsl] again" 397 | git status -s -b 398 | 399 | echo_f "5.6 git log origin..HEAD" 400 | git log origin..HEAD 401 | 402 | echo_f "5.7 git commit -m\"Add .DS_Store to .gitignore @$OTHER_ACCT\" " 403 | git commit -m "Add .DS_Store to .gitignore @$OTHER_ACCT" 404 | 405 | echo_f "5.8 git reflog -5" 406 | git reflog -5 407 | 408 | echo_f "5.9 git log --oneline -5" # | tail -n 10 409 | git log --oneline -5 410 | # git log --pretty=format:"%h %s %ad" --graph --date=relative 411 | 412 | #echo_f "5.10 git rebase -i is optional" 413 | 414 | 415 | echo_f "6.1 git push origin $NEW_BRANCH" 416 | git push origin "$NEW_BRANCH" 417 | 418 | # TODO: Stop if above not successful. 419 | 420 | # To get rid of tag from prior run, manually delete repo and 421 | # Fork again. This is not working: 422 | #echo_f "6.2 git push --tag origin :v1.2.3 # : to remove tag in cloud" 423 | # git push --tag origin :v1.2.3 424 | 425 | echo_f "6.3 git tag -a v1.2.3 -m \"New version\" " 426 | git tag -a v1.2.3 -m "New version" 427 | # See annotated tag https://git-scm.com/book/en/v2/Git-Basics-Tagging 428 | 429 | echo_f "6.4 git push origin --tags" 430 | git push origin --tags 431 | 432 | # TODO: Stop if above not successful. 433 | 434 | echo_f "6.5 git checkout master " 435 | git checkout master 436 | 437 | echo_f "6.6 git branch -D feat1 # to remove locally" 438 | git branch -D "$NEW_BRANCH" 439 | 440 | echo_f "6.7 git push origin :feat1 # to remove in cloud" 441 | git push origin :"$NEW_BRANCH" 442 | 443 | 444 | # Check manually on GitHub for new tag. 445 | 446 | echo_f "7.1 On origin $MYACCT_USERID/$OTHER_REPO, create a Pull/Merge Request." 447 | echo_f "7.2 On upstream $OTHER_CCT/$OTHER_REPO, Squash and merge." 448 | echo_f "7.3 In upstream $OTHER_ACCT/$OTHER_REPO, Ask maintainter to make a change (add file)." 449 | read -rsp $'Press any key after creating a new file in that repo ...\n' -n 1 key 450 | # See https://unix.stackexchange.com/questions/134437/press-space-to-continue 451 | # See https://stackoverflow.com/questions/92802/what-is-the-linux-equivalent-to-dos-pause 452 | 453 | 454 | echo_f "8.2 git remote add upstream https://$GITHOST/$OTHER_ACCT/$OTHER_REPO ..." 455 | git remote add upstream "https://$GITHOST/$OTHER_ACCT/$OTHER_REPO" 456 | echo ">>> No output expected." 457 | 458 | echo_f "8.3 git remote -v " 459 | git remote -v 460 | 461 | echo_f "8.4a git fetch upstream master --dry-run # not all branches" 462 | git fetch upstream master --dry-run 463 | 464 | echo_f "8.4b git fetch upstream master # not all branches" 465 | git fetch upstream master 466 | 467 | echo_f "8.5 git checkout master " 468 | git checkout master 469 | 470 | echo_f "8.6 git diff HEAD @{u} --name-only" 471 | git diff HEAD @{u} --name-only 472 | 473 | echo_f "8.7 git merge upstream/master -m\"8.7\"" 474 | git merge upstream/master -m "8.7" 475 | 476 | echo_f "8.8 git push origin master" 477 | git push origin master 478 | 479 | 480 | echo_f "9.1 Change something on the origin in GitHub $MYACCT_USERID/$OTHER_REPO ..." 481 | read -rsp $'Press any key after adding a file ...\n' -n 1 key 482 | 483 | echo_f "9.2 git fetch origin" 484 | git fetch origin 485 | 486 | echo_f "9.3 git diff master..origin/master" 487 | git diff master..origin/master 488 | #gitk master..origin/master 489 | 490 | echo_f "9.4 git merge origin/master -m\"9.4 thank you\" --no-edit" 491 | git merge origin/master -m "9.4 thank you" --no-edit 492 | 493 | echo_f "9.5 git diff master..origin/master # again to verify" 494 | git diff master..origin/master 495 | 496 | FREE_DISKBLOCKS_END="$(df -P | awk '{print $4}' | sed -n 2p)" 497 | DIFF=$(((FREE_DISKBLOCKS_START-FREE_DISKBLOCKS_END)/2048)) 498 | # 380691344 / 182G = 2091710.681318681318681 blocks per GB 499 | # 182*1024=186368 MB 500 | # 380691344 / 186368 G = 2042 blocks per MB 501 | 502 | TIME_END=$(date -u +%s); 503 | DIFF=$((TIME_END-TIME_START)) 504 | MSG="End of script after $((DIFF/60))m $((DIFF%60))s seconds elapsed" 505 | echo_f "$MSG and $DIFF MB disk space consumed." 506 | #say "script ended." # through speaker 507 | -------------------------------------------------------------------------------- /git-client-config.ps1: -------------------------------------------------------------------------------- 1 | # git_client-config.ps1 within https://github.com/wilsonmar/git-utilities 2 | # for running under PowerShell on Mac or Windows 3 | # See https://www.develves.net/blogs/asd/articles/using-git-with-powershell-on-windows-10/ 4 | 5 | # Default is local: 6 | if( $args[0] -eq "global" ) { 7 | $GIT_GLOBAL = "--global" 8 | }else{ 9 | $GIT_GLOBAL = "" # local 10 | } 11 | 12 | echo "******** Running script file git_client-config.ps1" 13 | # Change string from "" to "--global" 14 | if( $GIT_GLOBAL -eq "--global" ) { 15 | echo "******** Creating $GIT_GLOBAL repo in $HOME home dir using git config commands" 16 | }else{ 17 | echo "******** Creating local ../.git/config file using git config commands" 18 | } 19 | 20 | # Verify settings: 21 | git config $GIT_GLOBAL core.filemode false 22 | 23 | # Using variables built into PowerShell: See https://help.github.com/articles/dealing-with-line-endings/ 24 | # See https://www.jetbrains.com/help/idea/2016.2/handling-lf-and-crlf-line-endings.html 25 | if( $IsWindows -eq $True ) { 26 | echo "******** Configuring git core.autocrlf for Windows!" 27 | git config $GIT_GLOBAL core.autocrlf true 28 | } 29 | if ( $IsOSX -eq $True){ 30 | echo "******** Configuring git core.autocrlf for Mac!" 31 | git config $GIT_GLOBAL core.autocrlf input 32 | } 33 | # see https://help.github.com/articles/dealing-with-line-endings/ 34 | # to remove files in Git's index and reset from HEAD to pick up new line endings. 35 | # On Git add . it is ok to see messages: 36 | # "warning: CRLF will be replaced by LF in file." 37 | 38 | git config $GIT_GLOBAL push.default simple 39 | 40 | git config $GIT_GLOBAL core.safecrlf true 41 | 42 | # On Unix systems, ignore ^M symbols created by Windows: 43 | # git config $GIT_GLOBAL core.whitespace cr-at-eol 44 | 45 | # Change default commit message editor program to Sublime Text (instead of vi): 46 | if ( $IsOSX -eq $True){ 47 | git config $GIT_GLOBAL core.editor "~/Sublime\ Text\ 3/sublime_text -w" 48 | #git config $GIT_GLOBAL core.editor=subl -w 49 | 50 | # On Unix systems, ignore ^M symbols created by Windows: 51 | git config core.whitespace cr-at-eol 52 | } 53 | 54 | # Allow all Git commands to use colored output, if possible: 55 | git config $GIT_GLOBAL color.ui auto 56 | git config $GIT_GLOBAL color.status always 57 | #color.branch.current=green bold 58 | #color.branch.remote=red bold 59 | #color.status.add=green bold 60 | #color.status.added=green bold 61 | #color.status.updated=green bold 62 | #color.status.changed=red bold 63 | #color.status.untracked=red bold 64 | 65 | # See https://git-scm.com/docs/pretty-formats : Add "| %G?" for signing 66 | # In Windows, double quotes are needed: 67 | git config $GIT_GLOBAL alias.l "log --pretty='%Cred%h%Creset %C(yellow)%d%Creset | %Cblue%s%Creset' --graph" 68 | # To see first 5 lines: git l -5 69 | 70 | git config $GIT_GLOBAL alias.s "status -s" 71 | #it config $GIT_GLOBAL alias.w "show -s --quiet --pretty=format:'%Cred%h%Creset | %Cblue%s%Creset | (%cr) %Cgreen<%ae>%Creset'" 72 | git config $GIT_GLOBAL alias.w "show -s --quiet --pretty=format:'%Cred%h%Creset | %Cblue%s%Creset'" 73 | git config $GIT_GLOBAL alias.ca "commit -a --amend -C HEAD" # (with no message) 74 | 75 | # Have git diff use mnemonic prefixes (index, work tree, commit, object) instead of standard a and b notation: 76 | git config $GIT_GLOBAL diff.mnemonicprefix true 77 | # See http://stackoverflow.com/questions/28017249/what-does-diff-mnemonicprefix-do 78 | # diff --git i/foo/bar.txt w/foo/bar.txt 79 | # index abcd123..1234abc 100644 80 | # --- i/foo/bar.txt 81 | # +++ w/foo/bar.txt 82 | # See https://git-scm.com/docs/diff-config 83 | 84 | # Save & Reuse Recorded Resolution of conflicted merges - https://git-scm.com/docs/git-rerere 85 | git config $GIT_GLOBAL rerere.enabled false 86 | # See https://chuva-inc.com/blog/fast-tip-enable-git-rerere-right-now 87 | 88 | # Disable “how to stage/unstage/add” hints given by git status: 89 | git config $GIT_GLOBAL advice.statusHints false 90 | 91 | # Allow git diff to do basic rename and copy detection: 92 | git config $GIT_GLOBAL diff.renames copies 93 | 94 | #Always show a diffstat at the end of a merge: 95 | git config $GIT_GLOBAL merge.stat true 96 | 97 | # git config $GIT_GLOBAL --list # Dump config $GIT_GLOBAL file 98 | 99 | -------------------------------------------------------------------------------- /git-custom-commands/git-c: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # git-c 3 | # quick add + commit message pre-pended with your user id (Mac) or User name (Windows) 4 | # by wilsonmar@gmail.com 310.320-7878 5 | # usage: git c "messge here" 6 | 7 | git add -A 8 | 9 | if [ "$(uname)" == "Darwin" ]; then # In Mac OS X platform: 10 | git commit --message="@${USER}: $1" 11 | 12 | elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then # In 32 bits Windows NT platform: 13 | # This not working yet: https://superuser.com/questions/1204589/how-to-use-windows-environment-variable-within-a-git-commit-message 14 | git commit --message="%COMPUTERNAME%: $1" 15 | elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then # In 64 bits Windows NT platform: 16 | git commit --message="%COMPUTERNAME%: $1" 17 | #git commit --message="{%COMPUTERNAME%}: $1" 18 | 19 | elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then # In GNU/Linux platform: 20 | # https://superuser.com/questions/944663/show-git-author-in-comments-while-writing-commit-message 21 | # From http://mfranc.com/tools/git-custom-command/ by Michal Franc 22 | # Show present working directory (PWD) 23 | git commit --message="@${PWD##*/}: $1" 24 | fi -------------------------------------------------------------------------------- /git-custom-commands/git-echo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # git-echo 3 | # From repo https://github.com/wilsonmar/git-utilities 4 | # A test program for git custom commands 5 | # Usage: git echo hello 6 | echo $1 7 | -------------------------------------------------------------------------------- /git-custom-commands/git-squash: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # git-squash 3 | # From https://coderwall.com/p/bt93ia/extend-git-with-custom-commands 4 | # Usage: git squash 3 5 | # squashes the last 3 commits (HEAD~3) 6 | 7 | source "$(git --exec-path)/git-sh-setup" 8 | 9 | USAGE="COMMITS" 10 | function _squash() { 11 | if [[ $# == 1 ]]; then 12 | if [[ -n $(git rev-parse --verify --quiet HEAD~$1) ]]; then 13 | git rebase -i HEAD~$1 14 | else 15 | die "HEAD~$1 does not exist" 16 | fi 17 | else 18 | usage 19 | fi 20 | } 21 | 22 | _squash $1 -------------------------------------------------------------------------------- /git-custom-commands/graph-dag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # graph-dag.sh 3 | # Draw a graphviz diagram of the Git DAG 4 | # See https://wilsonmar.github.io/git-utilities 5 | # 6 | # Labels consist of the short SHA1 and any refs. 7 | # Unreachable commits (ignoring the reflog) will be marked with an asterisk and 8 | # drawn with dashed lines. 9 | # 10 | # Largely stolen from https://git.wiki.kernel.org/index.php/ExampleScripts 11 | # 12 | # Usage: 13 | # git graph-dag HEAD~10.. | dot -Tpng | display -antialias 14 | # 15 | # Accepts any range or arguments that git rev-list accepts. 16 | 17 | set -e 18 | 19 | if [[ -z $@ ]] ; then 20 | echo -e "Usage: git graph-dag HEAD~10.. | dot -Tpng | display -antialias" 21 | exit 1 22 | fi 23 | 24 | echo "digraph lattice {" 25 | 26 | # Draw the DAG and connect parents 27 | git rev-list --parents "$@" | 28 | while read commit parents 29 | do 30 | for p in $parents 31 | do 32 | echo "n$commit -> n$p" 33 | done 34 | done 35 | 36 | # Make pretty labels with the short sha1 and any refs 37 | git rev-list --pretty=format:"%H %h %d" "$@" | awk ' 38 | BEGIN { 39 | command = "git fsck --unreachable --no-reflogs | cut -d\" \" -f3" 40 | while (command | getline unr) unreachable[unr] = 1 41 | close(command) 42 | } 43 | 44 | !/^commit/ { 45 | refs = "" 46 | for (i=3; i<=NF; i++) refs = refs " " $i 47 | 48 | unreachable[$1] == 1 ? isunr = 1 : isunr = 0 49 | 50 | printf "n%s [shape=Mrecord, style=%s, label=\"{%s%s}\"]\n", \ 51 | $1, \ 52 | isunr == 1 ? "dashed" : "filled", \ 53 | isunr == 1 ? "*" $2 : $2, \ 54 | refs == "" ? "" : refs 55 | }' 56 | 57 | echo "}" -------------------------------------------------------------------------------- /git-flow-create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ./git-flow-create.sh 3 | # Written by Wilson Mar (wilsonmar@gmail.com) 4 | # This creates the conditions for testing Michael Haggerty's "git imerge", 5 | # as described in https://wilsonmar.github.io/git-flow 6 | # cd 7 | 8 | # Before running this, copy this file to the folder where you want the test repo created, 9 | # then chmod 555 git-imerge-test-create.sh 10 | # Running this creates a folder above the script folder 11 | # and creates a file named somefile.txt in both the master branch and "branch1" branch. 12 | # This file is in https://github.com/wilsonmar/git-utilities/git-imerge-test-create.sh 13 | # Also see https://jonathanmh.com/how-to-create-a-git-merge-conflict/ 14 | # https://github.com/cirosantilli/test-git-conflict 15 | # uses ruby printf statements to generate file content. 16 | 17 | echo "## Navigating to working folder:" 18 | cd ~/gits/hotwilson 19 | pwd 20 | echo "## Deleting .git and files from previous run:" 21 | rm -rf git-utilities 22 | exit 23 | #echo "## This hangs if no internet is available:" 24 | #git clone https://github.com/wilsonmar/git-utilities 25 | #cd git-utilities 26 | #git branch -avv 27 | # git checkout master 28 | git checkout -b feat1 29 | echo "more stuff">>README.md 30 | git status 31 | git add README.md -A 32 | git commit -m"Update for show" 33 | git log --graph --oneline 34 | git reflog 35 | exit 36 | 37 | git push 38 | git tag v1.3.4 39 | git push --tags 40 | 41 | git remote add upstream https://github.com/wilsonmar/git-utilities 42 | # git pull --rebase 43 | git config --global pull.rebase true 44 | git fetch upstream 45 | git checkout master 46 | # git difftool 47 | git merge upstream/master 48 | cat README.md 49 | 50 | git request-pull v1.0 https://github.com/upstream/sisters master 51 | 52 | echo "## Working upstream:" 53 | git fetch --dry-run 54 | exit 55 | git log ^master origin/master 56 | git fetch upstream 57 | git checkout master 58 | #git pull --rebase --autostash 59 | git merge upstream/master 60 | cat README.md 61 | #git push -u origin master 62 | git config --global alias.up '!git fetch && git rebase --autostash FETCH_HEAD' 63 | git up 64 | 65 | -------------------------------------------------------------------------------- /git-hooks-install.ps1: -------------------------------------------------------------------------------- 1 | # git-hooks-install.ps1 2 | # by wilsonmar at gmail.com 3 | # After the repo is cloned, this PowerShell multi-platform script 4 | # copies scripts in the repo's hooks folder into the .git/hooks 5 | # and sets permissions. 6 | 7 | #echo "Remove *.sample files in .git/hooks ..." 8 | Remove-Item .git/hooks/*.sample 9 | 10 | #echo "Copy hooks/git-commit into .git/hooks ..." 11 | Copy-Item hooks/* .git/hooks 12 | #Copy-Item hooks/git-commit .git/hooks 13 | #Copy-Item hooks/git-push .git/hooks 14 | #Copy-Item hooks/git-rebase .git/hooks 15 | #Copy-Item hooks/prepare-commit-msg .git/hooks 16 | 17 | #echo "Change permissions ..." 18 | $SUBDIR=".git/hooks" 19 | Get-ChildItem "$SUBDIR" -Filter *.log | 20 | Foreach-Object { 21 | $content = Get-Content $_.FullName 22 | echo $content 23 | if( $IsWindows -eq $True ) { 24 | # attrib to set file permissions 25 | # icacls to set ownership in Access Control Lists 26 | } 27 | if ( $IsOSX -eq $True){ 28 | chmod +x $SUBDIR$content 29 | } 30 | } 31 | 32 | #echo "Change permissions ..." 33 | ls .git/hooks 34 | 35 | echo "Done with status $? (0=OK)." 36 | -------------------------------------------------------------------------------- /git-hooks-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # git-hooks-install.sh 4 | # by wilsonmar at gmail.com 5 | # After the repo is cloned, this bash script copies 6 | # scripts in the repo's hooks folder into the .git/hooks 7 | # and sets permissions. 8 | 9 | fancy_echo() { # to add blank line between echo statements: 10 | local fmt="$1"; shift 11 | # shellcheck disable=SC2059 12 | printf "\n$fmt\n" "$@" 13 | } 14 | 15 | fancy_echo "Remove *.sample files ..." 16 | del .git/hooks/*.sample 17 | 18 | fancy_echo "Copy hooks/git-commit into .git/hooks ..." 19 | cp hooks/prepare-commit-msg .git/hooks 20 | chmod +x .git/hooks/prepare-commit-msg 21 | 22 | #cp hooks/git-commit .git/hooks 23 | #chmod +x .git/hooks/git-commit 24 | 25 | cp hooks/git-push .git/hooks 26 | chmod +x .git/hooks/git-push 27 | 28 | cp hooks/git-rebase .git/hooks 29 | chmod +x .git/hooks/git-rebase 30 | 31 | ls .git/hooks 32 | 33 | fancy_echo "Done with status $? (0=OK)." 34 | -------------------------------------------------------------------------------- /git-imerge-conflict1-create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ./git-imerge-test-create.sh 3 | # Written by Wilson Mar (wilsonmar@gmail.com) 4 | # This creates the conditions for testing Michael Haggerty's "git imerge", 5 | # as described in https://wilsonmar.github.io/git-imerge 6 | # 7 | # Before running this, copy this file to the folder where you want the test repo created, 8 | # then chmod 555 git-imerge-test-create.sh 9 | # Running this creates a folder above the script folder 10 | # and creates a file named somefile.md in both the master branch and "feature1" branch. 11 | # This file is in https://github.com/wilsonmar/git-utilities/git-imerge-test-create.sh 12 | 13 | 14 | function conflict { # $1=letter $2=cnt number 15 | x="$1$2" 16 | if [ $x = B2 ]||[ $x = G7 ]||[ $x = I9 ]; then 17 | commit "$x feature1" $1 feature1 18 | commit "$x master" $2 master 19 | else 20 | commit "$x" $1 feature1 21 | commit "$x" $2 master 22 | fi 23 | } 24 | 25 | function commit { # $1=content, $2=msg 26 | echo "## Committing $1 :" 27 | git checkout $3 # $3=branch 28 | echo $1>>somefile.md 29 | git add somefile.md 30 | git commit -m"$2" 31 | #git log --name-status HEAD^..HEAD # TODO: show log of most recent commit 32 | } 33 | 34 | ########## 35 | 36 | #echo "## Change directory up to avoid using git-utilities own repo:" 37 | #cd .. 38 | #mkdir $1 39 | #cd $1 40 | 41 | echo "## Deleting .git and somefile.md from previous run:" 42 | rm -rf .git 43 | rm somefile.md 44 | 45 | echo "## Initializing repo with commit and branches:" 46 | git init 47 | touch somefile.md 48 | git add somefile.md 49 | git commit -m"0" 50 | git branch feature1 51 | git branch master 52 | git branch -avv 53 | 54 | echo "## Generating commits in branches:" 55 | letters=(A B C D E F G H I) # array 56 | cnt=1 57 | for i in ${letters[@]}; do 58 | conflict $i $cnt 59 | cnt=$((cnt+1)) # increment 60 | done 61 | 62 | echo "## Verifying contents of branch feature1 and file somefile.md:" 63 | git log --pretty=format:"%h %s %ad" --graph --since=1.days --date=relative; 64 | git checkout feature1 65 | cat somefile.md 66 | echo "## Verifying contents of branch master and file somefile.md:" 67 | git log --pretty=format:"%h %s %ad" --graph --since=1.days --date=relative; 68 | git checkout master 69 | cat somefile.md 70 | git branch -avv 71 | 72 | read -p "Press enter to continue" 73 | 74 | # You should now have: 75 | # 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 ' ← master 76 | # \ 77 | # A -- B -- C --- D --- E --- F --- G --- H --- I ← branch 78 | git checkout master 79 | git-imerge start --name=NAME --goal=full feature1 80 | #git imerge diagram --name=NAME 81 | # sed -i "" "s/B2 feature1/B2 master/g" somefile.md 82 | #awk '{gsub(/pattern/,"replacement")}' file 83 | # TODO: Remove <<<<<<< HEAD, =======, line, and >>>>>>> 865fba2c721d68aca6486499f5e9cb33f95f5311 84 | # git add . 85 | # git commit -m"Fix B2" 86 | # git imerge continue 87 | 88 | # TODO: Remove <<<<<<< HEAD, =======, line, and >>>>>>> 865fba2c721d68aca6486499f5e9cb33f95f5311 89 | # git add . 90 | # git commit -m"Fix G7" 91 | # git imerge continue 92 | 93 | # TODO: Remove <<<<<<< HEAD, =======, line, and >>>>>>> 865fba2c721d68aca6486499f5e9cb33f95f5311 94 | # git add . 95 | # git commit -m"Fix I9" 96 | # git imerge continue 97 | 98 | # git imerge finish --goal=merge 99 | # git imerge diagram --name=NAME 100 | -------------------------------------------------------------------------------- /git-patch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # git-patch.sh from https://github.com/wilsonmar/git-utilities 3 | # This creates a patch file from one repository and adds it to another repository. 4 | # Note: Creating a patch provides a log of exactly what is inserted into the target repo. 5 | # customized based on specification in file secrets.sh within the same repo. 6 | # TODO: https://wilsonmar.github.io/git-patch.md 7 | # sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/git-utilities/master/git-patch.sh)" 8 | 9 | # 1. Define variables containing the origin's repos. For example: 10 | 11 | REPO_FROM_CONTAINER="$HOME/temp/hotwilson" 12 | REPO_TO_CONTAINER="$HOME/temp/hotwilson" 13 | 14 | GIT_HOST_FROM="https://github.com" # git@github.com: for SSH 15 | GIT_HOST_TO="https://github.com" # git@github.com: for SSH 16 | 17 | REPO_FROM_ACCOUNT="wilsonmar" 18 | REPO_TO_ACCOUNT="github-candidate" 19 | 20 | REPO_NAME_FROM="devops-cert-activity-wilsonmar2" 21 | REPO_NAME_TO="devops-cert-activity-wilsonmar" 22 | 23 | SHA_TO="6e6d819" # least recent 6e6d819 24 | SHA_FROM="b0de12f" # most recent 25 | 26 | PATCH_FILE="0new-feature.patch" 27 | 28 | NEW_BRANCH_NAME="add from patch" 29 | 30 | # Feature flags: 31 | RELOAD_GITHUB_FROM="1" # 1=YES (remove folder from previous run), 0=No 32 | RELOAD_GITHUB_TO="1" # 1=YES, 0=No 33 | 34 | PAUSE_FOR_SHA="0" # 1=YES, 0=No () 35 | 36 | REMOVE_REPO_FROM_WHEN_DONE="0" # 0=No (default), "1"=Yes 37 | REMOVE_REPO_TO_WHEN_DONE="0" # 0=No (default), "1"=Yes 38 | 39 | # 2. Define utility functions: 40 | 41 | function echo_f() { # echo fancy comment 42 | local fmt="$1"; shift 43 | printf "\\n >>> $fmt\\n" "$@" 44 | } 45 | function echo_c() { # echo command 46 | local fmt="$1"; shift 47 | printf " $fmt\\n" "$@" 48 | } 49 | 50 | #4 Collect starting system information and display on console: 51 | TIME_START="$(date -u +%s)" 52 | #FREE_DISKBLOCKS_END=$(df | sed -n -e '2{p;q}' | cut -d' ' -f 6) # no longer works 53 | FREE_DISKBLOCKS_START="$(df -P | awk '{print $4}' | sed -n 2p)" # e.g. 342771200 from: 54 | # Filesystem 512-blocks Used Available Capacity Mounted on 55 | # /dev/disk1s1 976490568 611335160 342771200 65% / 56 | LOG_PREFIX=$(date +%Y-%m-%dT%H:%M:%S%z)-$((1 + RANDOM % 1000)) 57 | # ISO-8601 date plus RANDOM=$((1 + RANDOM % 1000)) # 3 digit random number. 58 | # LOGFILE="$0.$LOG_PREFIX.log" 59 | echo_f "STARTING $0 from within $PWD ##################################" 60 | echo_c "at $LOG_PREFIX with $FREE_DISKBLOCKS_START blocks free ..." 61 | 62 | # 3. Navigate to the origin's repo. For example: 63 | 64 | if [ ! -d "$REPO_FROM_CONTAINER" ]; then 65 | echo_f "Directory $REPO_FROM_CONTAINER not found. Making it ..." 66 | cd ~ 67 | mkdir "$REPO_FROM_CONTAINER" 68 | cd "$REPO_FROM_CONTAINER" 69 | else 70 | echo_f "Navigating from PWD=$PWD to $REPO_FROM_CONTAINER" 71 | cd ~ 72 | cd "$REPO_FROM_CONTAINER" 73 | fi 74 | 75 | if [ ! -d "$REPO_FROM_CONTAINER" ]; then 76 | echo_f "Error creating directory at PWD=$REPO_FROM_CONTAINER." 77 | exit 78 | else 79 | echo_c "Directories now:" 80 | ls -d */ 81 | fi 82 | 83 | # 4. Delete the folder for download again? 84 | 85 | echo_f "REPO_NAME_FROM=$REPO_NAME_FROM" 86 | if [ $RELOAD_GITHUB_FROM -eq "1" ]; then # 1=YES, 0=No 87 | rm -rf "$REPO_NAME_FROM" # remove ... 88 | echo_f "Cloning $GIT_HOST_FROM/$REPO_FROM_ACCOUNT/$REPO_NAME_FROM ..." 89 | git clone "$GIT_HOST_FROM/$REPO_FROM_ACCOUNT/$REPO_NAME_FROM" 90 | ls -l | egrep '^d' # list only folders using regular expression 91 | fi 92 | cd "$REPO_NAME_FROM" 93 | URL_FROM="$PWD" 94 | echo_f "Now at PWD=$URL_FROM" 95 | 96 | # 5. Pause or go to identify SHAs: 97 | 98 | if [ $PAUSE_FOR_SHA -eq "1" ]; then # 1=YES, 0=No 99 | # By default, pause and list SHA's. 100 | git log --oneline 101 | exit # to edit this script with SHA values. 102 | else 103 | echo_f "SHA_FROM=\"$SHA_FROM\" - SHA_TO=\"$SHA_TO\" " 104 | git log --oneline 105 | fi 106 | 107 | # 6. Create patch message file(s): 108 | 109 | echo_f "Creating git patch message file $PATCH_FILE ..." 110 | git format-patch "$SHA_FROM^..$SHA_TO" --stdout > "$PATCH_FILE" 111 | # See https://git-scm.com/docs/git-format-patch 112 | # NOTE: --stdout > 0new-feature.patch creates a single file from several patch files output. 113 | # See https://thoughtbot.com/blog/send-a-patch-to-someone-using-git-format-patch 114 | #git format-patch -1 # for just the lastest commit. See https://thoughtbot.com/blog/send-a-patch-to-someone-using-git-format-patch 115 | # -1 for a single commit SHA or 116 | # "$SHA_FROM^..$SHA_TO" for a range of commits. 117 | # 0001-.patch 118 | if [ ! -f "$PATCH_FILE" ]; then 119 | echo_f "File $PATCH_FILE not found. Aborting!" 120 | exit 121 | else 122 | ls -al *.patch 123 | fi 124 | 125 | # 7. Navigate to the target repo: 126 | 127 | cd .. 128 | echo_f "REPO_TO at $PWD/$REPO_NAME_TO" 129 | if [ $RELOAD_GITHUB_TO -eq "1" ]; then # 1=YES, 0=No 130 | rm -rf "$REPO_NAME_TO" # remove ... 131 | echo_f "Cloning $GIT_HOST_TO/$REPO_TO_ACCOUNT/$REPO_NAME_TO ..." 132 | git clone "$GIT_HOST_TO/$REPO_TO_ACCOUNT/$REPO_NAME_TO" 133 | 134 | echo_f "Directories within $REPO_TO_CONTAINER :" 135 | ls -l | egrep '^d' # list only folders using regular expression 136 | fi 137 | cd "$REPO_NAME_TO" 138 | echo_f "Now at PWD=$PWD" 139 | 140 | # 8. Verify .git/hooks actions listening: 141 | 142 | # See https://wilsonmar.github.io/git-hooks 143 | # applypatch-msg, pre-applypatch, and post-applypatch. 144 | if [ -f ".git/hooks/applypatch-msg" ]; then 145 | echo_f "Beware .git/hooks/applypatch-msg specifies:" 146 | cat .git/hooks/applypatch-msg 147 | fi 148 | 149 | if [ -f ".git/hooks/pre-applypath" ]; then 150 | echo_f "Beware .git/hooks/pre-applypath specifies:" 151 | cat .git/hooks/pre-applypath 152 | fi 153 | 154 | if [ -f ".git/hooks/post-applypatch" ]; then 155 | echo_f "Beware .git/hooks/post-applypatch specifies:" 156 | cat .git/hooks/post-applypatch 157 | fi 158 | 159 | # 9. Create a branch: 160 | 161 | # if NEW_BRANCH_NAME is not blank: 162 | CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" 163 | echo_f "At branch $CURRENT_BRANCH to create branch $NEW_BRANCH_NAME:" 164 | git checkout -b "$NEW_BRANCH_NAME" 165 | git branch # list branches 166 | 167 | # 10. Apply patch: 168 | 169 | # TODO: Move patch files to TO repo folder? 170 | 171 | echo_f "Using git am to apply patch file $URL_FROM/$PATCH_FILE" 172 | ls -l $URL_FROM/$PATCH_FILE # not 0*.patch 173 | 174 | # See https://git-scm.com/docs/git-am/2.0.0 for options: 175 | # git am $URL_FROM/0*.patch # doesn't read all files and issues errors. 176 | # -3 means trying the three-way merge if the patch fails to apply cleanly 177 | cat "$URL_FROM/$PATCH_FILE" | git am --ignore-space-change --ignore-whitespace 178 | if [ $? -eq 0 ]; then 179 | echo_f "No error in $? status returned." 180 | else 181 | echo_f "Error $? from statement. git am --abort --show-current-patch ..." 182 | git am --abort 183 | # git am --show-current-patch 184 | fi 185 | echo_f "Git log of new SHAs in $REPO_NAME_TO after messages applied:" 186 | git log --oneline 187 | # Note: the SHA of the patch that you merge with git am will not be the same SHA. 188 | # However, the commit message text will be intact. 189 | 190 | # 11. TODO: Create pull request in GitHub 191 | # Using hub: https://www.skcript.com/svr/cli-pr-pull-request-command-line-github/ 192 | # Using GitHub API: See https://gist.github.com/devongovett/10399980 193 | # Using GitHub API: See https://github.com/wjmelements/scripts#cpr 194 | # See https://www.skcript.com/svr/cli-pr-pull-request-command-line-github/ 195 | 196 | # Check to see if hub is installed: 197 | # https://andrewlock.net/creating-github-pull-requests-from-the-command-line-with-hub/ 198 | 199 | # 12. Remove folders 200 | 201 | if [ "$REMOVE_REPO_FROM_WHEN_DONE" -eq "1" ]; then # 0=No (default), "1"=Yes 202 | echo_f "Removing $URL_FROM/$PATCH_FILE as REMOVE_REPO_FROM_WHEN_DONE=$REMOVE_REPO_FROM_WHEN_DONE" 203 | rm -rf "$REPO_TO_CONTAINER/$REPO_NAME_FROM" 204 | if [ -d "$REPO_FROM_CONTAINER/$REPO_NAME_FROM" ]; then 205 | FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')" 206 | echo_f "WARNING: $FOLDER_DISK_SPACE folder still at $REPO_FROM_CONTAINER/$REPO_NAME_FROM." 207 | ls -al 208 | fi 209 | else 210 | if [ -d "$REPO_FROM_CONTAINER/$REPO_NAME_FROM" ]; then 211 | FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')" 212 | echo_f "WARNING: $FOLDER_DISK_SPACE folder remains at $REPO_FROM_CONTAINER/$REPO_NAME_FROM." 213 | else 214 | echo_f "Folder no longer at $REPO_FROM_CONTAINER/$REPO_NAME_FROM." 215 | fi 216 | fi 217 | 218 | if [ "$REMOVE_REPO_TO_WHEN_DONE" -eq "1" ]; then # 0=No (default), "1"=Yes 219 | echo_f "Removing $REPO_TO_CONTAINER/$REPO_NAME_TO as REMOVE_REPO_TO_WHEN_DONE=$REMOVE_REPO_TO_WHEN_DONE" 220 | rm -rf "$REPO_TO_CONTAINER/$REPO_NAME_TO" 221 | if [ -d "$REPO_TO_CONTAINER/$REPO_NAME_TO" ]; then 222 | FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')" 223 | echo_f "WARNING: $FOLDER_DISK_SPACE folder still at $REPO_TO_CONTAINER/$REPO_NAME_TO." 224 | ls -al 225 | fi 226 | else 227 | if [ -d "$REPO_TO_CONTAINER/$REPO_NAME_TO" ]; then 228 | FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')" 229 | echo_f "WARNING: $FOLDER_DISK_SPACE folder remains at $REPO_TO_CONTAINER/$REPO_NAME_TO." 230 | else 231 | echo_f "Folder no longer at $REPO_TO_CONTAINER/$REPO_NAME_TO." 232 | fi 233 | fi 234 | 235 | 236 | ### References 237 | 238 | # https://stackoverflow.com/questions/3816040/git-apply-changes-introduced-by-commit-in-one-repo-to-another-repo/3816292#3816292 239 | # https://stackoverflow.com/questions/5120038/is-it-possible-to-cherry-pick-a-commit-from-another-git-repository/9507417#9507417 240 | 241 | 242 | ######### 243 | 244 | #18 Calculate and display end of run statistics: 245 | FREE_DISKBLOCKS_END="$(df -P | awk '{print $4}' | sed -n 2p)" 246 | DIFF=$(((FREE_DISKBLOCKS_START-FREE_DISKBLOCKS_END)/2048)) 247 | # 380691344 / 182G = 2091710.681318681318681 blocks per GB 248 | # 182*1024=186368 MB 249 | # 380691344 / 186368 G = 2042 blocks per MB 250 | TIME_END=$(date -u +%s); 251 | DIFF=$((TIME_END-TIME_START)) 252 | MSG="End of script after $((DIFF/60))m $((DIFF%60))s elapsed" 253 | echo_f "$MSG and $DIFF MB disk space consumed." 254 | #say "script ended." # through speaker 255 | -------------------------------------------------------------------------------- /git-sample-repo-create.ps1: -------------------------------------------------------------------------------- 1 | 2 | # git-sample-repo-create.ps1 from within http://github.com/wilsonmar/git-utilities. 3 | # by Wilson Mar (wilsonmar@gmail.com, @wilsonmar) 4 | 5 | # This script was created for experiementing and learning Git. 6 | # Git commands in this script are meant as examples for manual entry 7 | # explained during my live "Git and GitHub" tutorials and 8 | # explained at https://wilsonmar.github.io/git-commands-and-statuses/). 9 | # Most of the regularly used Git commands are covered here. 10 | 11 | # This script creates and populates a sample repo which is then 12 | # uploaded to a new repo created using GitHub API calls 13 | 14 | # This script is designed to be "idempotent" in that repeat runs 15 | # begin by deleting what was created: the local repo and repo in GitHub. 16 | 17 | # Sample call in Win10 running within MacOS: 18 | # Set-ExecutionPolicy Unrestricted 19 | # ./git-sample-repo-create.ps1 20 | 21 | # Last tested on MacOS 10.12 (Sierra) 2017-01-12 22 | # http://skimfeed.com/blog/windows-command-prompt-ls-equivalent-dir/ 23 | 24 | ################################# 25 | 26 | # Create blank lines in the log to differentiate different runs: 27 | echo "" 28 | echo "" 29 | echo "" 30 | echo "" 31 | echo "" 32 | # Make the beginning of run easy to find: 33 | echo "**********************************************************" 34 | $NOW = Get-Date -Format "yyyy-MM-ddTHH:mmzzz" 35 | echo "******** NOW=$NOW $PSUICULTURE PID=$PID :" 36 | # $PSUICULTURE & $PID are built-in variables. 37 | $PSHOME # built-in varialbe # $psversiontable 38 | echo "******** IsWindows=$IsWindows IsOSX=$IsOSX IsLinux=$IsLinux" 39 | #[System.Environment]::OSVersion.Version 40 | echo "******** PSSCRIPTROOT= $PSSCRIPTROOT" 41 | git --version 42 | 43 | # exit #1 44 | 45 | # Make the beginning of run easy to find: TODO: Parameterize: 46 | $REPONAME='git-sample-repo' 47 | 48 | 49 | echo "******** STEP Delete $REPONAME remnant from previous run:" 50 | $FileExists = Test-Path $REPONAME 51 | if ($FileExists -eq $True ){ 52 | # See https://technet.microsoft.com/en-ca/library/hh849765.aspx?f=255&MSPPError=-2147217396 53 | Remove-Item -path ${REPONAME} -Recurse -Force # instead of rm -rf ${REPONAME} 54 | } 55 | # exit #2 56 | 57 | New-item ${REPONAME} -ItemType "directory" >$null # instead of mkdir ${REPONAME} 58 | # >$null suporesses several lines being printing out by PS to confirm. 59 | cd ${REPONAME} 60 | echo "******** $CURRENTDIR pwd " 61 | pwd | foreach { $_.Name } 62 | 63 | # exit #3 64 | 65 | #$CURRENTDIR = (Get-Item -Path ".\" -Verbose).FullName # Get-Location cmdlet 66 | $CURRENTDIR = $PSScriptRoot # PowerShell specific 67 | echo "CURRENTDIR=$CURRENTDIR" 68 | 69 | echo "******** STEP Init repo :" 70 | git init # init without --bare so we get a working directory: 71 | # echo "******** git rev-parse --git-dir (return the .git path of the current project:" 72 | #git rev-parse --git-dir 73 | 74 | echo "******** remove hooks/*.sample files :" 75 | del .git/hooks/*.sample 76 | # No files yet for Get-ChildItem -Recurse | ?{ $_.PSIsContainer } 77 | echo "******** tree .git (blank repo)" 78 | tree .git 79 | 80 | # exit #4 the file structure of an empty repo. 81 | 82 | echo "******** STEP Make develop the default branch instead of master :" 83 | # The contents of HEAD is stored in this file: 84 | cat .git/HEAD 85 | # Change from default "ref: refs/heads/master" : 86 | # See http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html 87 | echo "******** git symbolic-ref HEAD ... :" 88 | git symbolic-ref HEAD refs/heads/develop 89 | echo "******** cat .git/HEAD :" 90 | cat .git/HEAD 91 | echo "******** git branch :" 92 | git branch 93 | 94 | $DEFAULT_BRANCH="develop" 95 | echo "DEFAULT_BRANCH=$DEFAULT_BRANCH" 96 | 97 | # exit #5 98 | 99 | echo "******** STEP Attribution & Config (not --global):" 100 | # See https://git-scm.com/docs/pretty-formats : 101 | git config user.email "wilsonmar@gmail.com" 102 | git config user.name "Wilson Mar" # Username (not email) in GitHub.com cloud. 103 | $GITHUB_USER="wilsonmar" 104 | echo "******** GITHUB_USER=$GITHUB_USER " 105 | 106 | 107 | echo "******** Run PowerShell file for Git configurations at the repo level:" 108 | # PS TRICK: Get parent folder path using the $MyInvocation built-in PS variable: 109 | # See http://stackoverflow.com/questions/7377981/how-do-i-call-another-powershell-script-with-a-relative-path 110 | $ScriptPath = Split-Path -Parent $MyInvocation.InvocationName 111 | $UtilPath = Join-Path -Path $ScriptPath -ChildPath ..\ 112 | #Write-Host "Path:" $UtilPath 113 | # NOTE: PowerShell accepts both forward and backward slashes: 114 | & "$UtilPath/git-client-config.ps1" 115 | # Alternately, use & to run scripts in same scope: 116 | # & "../git_client-config.ps1 global" # 117 | # Alternately, use . to run scripts in child scope that will be thrown away: 118 | # . "../git_client-config.ps1 global" # 119 | #echo "******** Present Working Directory :" 120 | #pwd 121 | # git config --list # Dump config file 122 | 123 | # exit #6 124 | 125 | # WORKFLOW: After gpg is installed, find: 126 | # gpg --gen-key 127 | git config user.signingkey 2E23C648 # not --global 128 | gpg --list-keys 129 | 130 | # exit #7 131 | 132 | 133 | echo "******** STEP commit (initial) README :" 134 | echo "hello" > README.md # no touch command on Windows. 135 | git add . -A 136 | git commit -m "README.md" 137 | # In "create mode 100644", first three is about the file type 138 | # "644" (last three numbers) is the file permissions 139 | git l -1 140 | 141 | exit #8 # after first commit. 142 | 143 | 144 | echo "******** STEP amend commit README : " 145 | # ammend last commit with all uncommitted and un-staged changes: 146 | echo "color">>README.md 147 | git ca # use this alias instead of git commit -a --amend -C HEAD 148 | git l -1 149 | 150 | # exit #9 151 | 152 | echo "******** STEP amend commit 2 : " 153 | # ammend last commit with all uncommitted and un-staged changes: 154 | echo "still more">>README.md 155 | git ca # alias for git commit -a --amend -C HEAD 156 | git l -1 157 | git diff 158 | 159 | # exit #10 160 | 161 | echo "******** STEP commit .DS_Store in .gitignore :" 162 | echo ".DS_Store">>.gitignore 163 | git add . 164 | git commit -m "Add .gitignore" 165 | git l -1 166 | 167 | # exit #11 168 | 169 | echo "******** STEP commit --amend .secrets in .gitignore :" 170 | echo "secrets/">>.gitignore 171 | echo ".secrets">>.gitignore 172 | echo "*.log">>.gitignore 173 | git add . 174 | git ca # use this alias instead of git commit -a --amend -C HEAD 175 | git l -1 176 | 177 | # exit #12 178 | 179 | git reflog 180 | dir | format-table # Get-ChildItem # ps for ls -al 181 | 182 | cat README.md 183 | 184 | echo "******** STEP lightweight tag :" 185 | git tag "v1" # lightweight tag 186 | 187 | # exit #13 188 | 189 | echo "******** STEP checkout HEAD to create feature1 branch : --------------------------" 190 | git checkout HEAD -b feature1 191 | # git branch 192 | ls .git/refs/heads/ 193 | git l -1 194 | 195 | # exit #14 196 | 197 | echo "******** STEP commit .secrets : " 198 | echo "shessh!">>.secrets 199 | git add . 200 | git commit -m "Add .secrets" 201 | git l -1 202 | dir | format-table 203 | 204 | # exit #15 205 | 206 | echo "******** STEP commit: empty-folder" 207 | mkdir empty-folder 208 | 209 | echo "******** STEP commit: d" 210 | echo "free!">>LICENSE.md 211 | echo "d">>file-d.txt 212 | git add . 213 | git commit -m "Add d in feature1" 214 | git l -1 215 | dir | format-table 216 | 217 | # exit #16 218 | 219 | 220 | echo "******** STEP Merge feature1 :" 221 | # Instead of git checkout $DEFAULT_BRANCH : 222 | # git checkout @{-1} # doesn't work in PowerShell. 223 | git checkout $DEFAULT_BRANCH 224 | # response is "Switched to branch 'develop" 225 | 226 | # Alternately, use git-m.sh to merge and delete in one step. 227 | # git merge --no-ff (no fast forward) for "true merge": 228 | #git merge feature1 --no-ff --no-commit # to see what may happen 229 | git merge feature1 -m "merge feature1" --no-ff # --verify-signatures 230 | # resolve conflicts here? 231 | git add . 232 | # git commit -m "commit merge feature1" 233 | git branch 234 | git l -1 235 | 236 | # exit #17 237 | 238 | echo "******** STEP Remove merged branch ref :" 239 | git branch -D feature1 240 | git branch 241 | git l -1 242 | 243 | # exit #18 244 | 245 | echo "******** $NOW What's dangling? " 246 | git fsck --dangling --no-progress 247 | 248 | echo "******** STEP commit: e" 249 | echo "e money">>file-e.txt 250 | git add . 251 | git commit -m "Add e" 252 | git l -1 253 | 254 | # exit #19 255 | 256 | echo "******** STEP commit f : " 257 | echo "f money">>file-f.txt 258 | dir | format-table 259 | git add . 260 | git commit -m "Add f" 261 | git l -1 262 | 263 | # exit #20 264 | 265 | echo "******** STEP heavyeight tag (a commit) :" 266 | # git tag -a v0.0.1 -m"v1 unsigned" 267 | git tag -a v0.0.1 -m"v1 signed" -s # signed "heavyweight" tag 268 | # For numbering, see http://semver.org/ 269 | # echo "******** STEP tag verify :" 270 | # git tag -v v1 # calls verify-tag. 271 | git verify-tag v0.0.1 272 | 273 | exit #21 274 | 275 | # echo "******** STEP tag show :" 276 | # git show v1 # Press q to exit scroll. 277 | 278 | 279 | echo "Copy this and paste to a text edit for reference: --------------" 280 | git l 281 | echo "******** show HEAD : ---------------------------------------" 282 | git w HEAD 283 | echo "******** show HEAD~1 :" 284 | git w HEAD~1 285 | echo "******** show HEAD~2 :" 286 | git w HEAD~2 287 | echo "******** show HEAD~3 :" 288 | git w HEAD~3 289 | echo "******** show HEAD~4 :" 290 | git w HEAD~4 291 | 292 | echo "******** show HEAD^ :" 293 | git w HEAD^ 294 | echo "******** show HEAD^^ :" 295 | git w HEAD^^ 296 | echo "******** show HEAD^^^ :" 297 | git w HEAD^^^ 298 | echo "******** show HEAD^^^^ :" 299 | git w HEAD^^^^ 300 | 301 | echo "******** show HEAD^1 :" 302 | git w HEAD^1 303 | echo "******** show HEAD^2 :" 304 | git w HEAD^2 305 | 306 | echo "******** show HEAD~1^1 :" 307 | git w HEAD~1^1 308 | echo "******** show HEAD~2^1 :" 309 | git w HEAD~2^1 310 | echo "******** show HEAD~3^1 :" 311 | git w HEAD~3^1 312 | 313 | echo "******** show HEAD~1^2 :" 314 | git w HEAD~1^2 315 | 316 | echo "******** show HEAD~2^2 :" 317 | git w HEAD~2^2 318 | echo "******** show HEAD~2^3 :" 319 | git w HEAD~2^3 320 | dir | format-table 321 | 322 | echo "******** Reflog: ---------------------------------------" 323 | git reflog 324 | 325 | exit #22 326 | 327 | 328 | echo "******** show HEAD@{5} :" 329 | # FIX: git w HEAD@{5} 330 | 331 | echo "******** Create archive file, excluding .git directory :" 332 | $NOW = Get-Date -Format "yyyy-MM-ddTHH:mmzzz" 333 | # WARNING: The DateTime string format returned by Get-Date contains characters that can't be used for file names. Try something like this: 334 | # new-item -path .\desktop\testfolder -name "$NOW.txt" ` 335 | # -value (get-date).toString() -itemtype file 336 | $FILENAME="$REPONAME_$NOW.zip" 337 | #NOW=$(date +%Y-%m-%d:%H:%M:%S) 338 | #FILENAME=$( echo ${REPONAME}_${NOW}.zip) 339 | # See https://gallery.technet.microsoft.com/scriptcenter/Get-TimeZone-PowerShell-4f1a34e6 340 | 341 | echo "FILENAME=$FILENAME" 342 | 343 | # Commented out to avoid creating a file from each run: 344 | # git archive --format zip --output ../$FILENAME feature1 345 | # ls -l ../$FILENAME 346 | 347 | 348 | echo "******** STEP checkout c :" 349 | Get-ChildItem # ls -al 350 | git show HEAD@{5} 351 | git checkout HEAD@{5} 352 | Get-ChildItem 353 | 354 | echo "******** Go back to HEAD --hard :" 355 | git reset --hard HEAD 356 | # git checkout HEAD 357 | Get-ChildItem 358 | 359 | echo "******** Garbage Collect (gc) what Git can't reach :" 360 | git gc 361 | git reflog 362 | Get-ChildItem 363 | echo "******** Compare against previous reflog." 364 | 365 | # exit #11 366 | 367 | 368 | # See https://gist.github.com/caspyin/2288960 about GitHub API 369 | # From https://gist.github.com/robwierzbowski/5430952 on Windows 370 | # From https://gist.github.com/jerrykrinock/6618003 on Mac 371 | 372 | echo "****** GITHUB_USER=$GITHUB_USER, CURRENTDIR=$CURRENTDIR, REPONAME=$REPONAME" 373 | echo "****** DESCRIPTION=$DESCRIPTION" 374 | 375 | # Invoke file defined manually containing definition of GITHUB_PASSWORD: 376 | # Dot is cross-platform whereas source command is only for Bash: 377 | $RSA_PUBLIC_KEY = Get-Content "$home/.ssh/id_rsa.pub" 378 | # echo "RSA_PUBLIC_KEY=$RSA_PUBLIC_KEY" 379 | # Bash command to load contents of file into env. variable: 380 | # export RSA_PUBLIC_KEY=$(cat ~/.ssh/id_rsa.pub) 381 | # echo "RSA_PUBLIC_KEY=$RSA_PUBLIC_KEY" 382 | 383 | # Ignore SSL errors: 384 | # http://connect.microsoft.com/PowerShell/feedback/details/419466/new-webserviceproxy-needs-force-parameter-to-ignore-ssl-errors 385 | $SECRETS = Get-Content "$home/.secrets" | ConvertFrom-StringData 386 | # Please don't echo $SECRETS.GITHUB_TOKEN.Substring(0,8) 387 | # err: echo "SECRETS.TWITTER_TOKEN=${SECRETS.TWITTER_TOKEN}" 388 | 389 | 390 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 391 | 392 | #Install from the PowerShell Gallery (requires PowerShell 5.0+) 393 | #Copy-install the module to your $env:PSModulePath 394 | #Extract the module anywhere on the filesystem, and import it explicitly, using Import-Module 395 | # Import-module "../MyTwitter.psm1" 396 | # Send-Tweet -Message '@adbertram Thanks for the Powershell Twitter module' 397 | # $body = @{ 398 | # Name = "So long and thanks for all the fish" 399 | # } 400 | 401 | # exit #31 402 | 403 | # $GITHUB_TOKEN is not defined before this point so code can test if 404 | # one needs to be created: 405 | If ("$GITHUB_TOKEN" -eq "") { 406 | echo "******** Creating Auth GITHUB_TOKEN to delete repo later : " 407 | # Based on http://douglastarr.com/using-powershell-3-invoke-restmethod-with-basic-authentication-and-json 408 | 409 | $secpasswd = ConvertTo-SecureString $GITHUB_USER -AsPlainText -Force 410 | $cred = New-Object System.Management.Automation.PSCredential ($SECRETS.GITHUB_PASSWORD, $secpasswd) 411 | # CAUTION: which sends passwords through the internet here. 412 | # You may instead manually obtain a token on GitHub.com. 413 | 414 | #$Body_JSON = '{"scopes":["delete_repo"],"note":"token with delete repo scope"}' 415 | $BODY_JSON = "{""scopes"":[""delete_repo""], ""note"":""token with delete repo scope""}" 416 | echo "Body_JSON=$Body_JSON" # DEBUGGING 417 | 418 | $response = Invoke-RestMethod -Method Post ` 419 | -Credential $cred ` 420 | -Body $Body_JSON ` 421 | -Uri "https://api.github.com/authorizations" 422 | $GITHUB_TOKEN = $response.Stuffs | where { $_.Name -eq "token" } 423 | # Do not display token secret! 424 | # API Token (32 character long string) is unique among all GitHub users. 425 | # Response: X-OAuth-Scopes: user, public_repo, repo, gist, delete_repo scope. 426 | # See https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization 427 | 428 | # WORKFLOW: Manually see API Tokens on GitHub | Account Settings | Administrative Information 429 | } Else { 430 | echo "******** Verifying Auth GITHUB_TOKEN to delete repo later : " 431 | 432 | $Headers = @{ 433 | Authorization = 'Basic ' + ${GITHUB_TOKEN} 434 | }; 435 | # -f is for substitution of (0). 436 | # See https://technet.microsoft.com/en-us/library/ee692795.aspx 437 | # Write-Host ("Headers="+$Headers.Authorization) 438 | 439 | $response = Invoke-RestMethod -Method Get ` 440 | -Headers $Headers ` 441 | -ContentType 'application/json' ` 442 | -Uri https://api.github.com 443 | 444 | # Expect HTTP 404 Not Found if valid to avoid disclosing valid data with 401 response as RFC 2617 defines. 445 | $GITHUB_AVAIL = $response.Stuffs | where { $_.Name -eq "authorizations_url" } 446 | echo "******** authorizations_url=$GITHUB_AVAIL.Substring(0,8)" # DEBUGGING 447 | } 448 | 449 | echo "******** Checking GITHUB repo exists (_AVAIL) from prior run: " 450 | $response = Invoke-WebMethod -Method Put ` 451 | -Headers $Headers ` 452 | -ContentType 'application/json' ` 453 | -Uri https://api.github.com/repos/${GITHUB_USER}/${REPONAME} 454 | $GITHUB_AVAIL = $response.Stuffs | where { $_.Name -eq "full_name" } 455 | echo "******** authorizations_url=$GITHUB_AVAIL" # DEBUGGING 456 | 457 | # exit #41 458 | 459 | # 15:49 into https://channel9.msdn.com/Blogs/trevor-powershell/Automating-the-GitHub-REST-API-Using-PowerShell 460 | # https://developer.github.com/v3/users/ 461 | # https://github.com/pcgeek86/PSGitHub 462 | -------------------------------------------------------------------------------- /git-sample-repo-create.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # git-sample-repo-create.sh from within http://github.com/wilsonmar/git-utilities. 4 | # by Wilson Mar (wilsonmar@gmail.com, @wilsonmar) 5 | 6 | # This script was created for experiementing and learning Git. 7 | # Git commands in this script are meant as examples for manual entry 8 | # explained during my live "Git and GitHub" tutorials and 9 | # explained at https://wilsonmar.github.io/git-commands-and-statuses/). 10 | # Most of the regularly used Git commands are covered here. 11 | 12 | # This script creates and populates a sample repo which is then 13 | # uploaded to a new repo created using GitHub API calls 14 | 15 | # This script is designed to be "idempotent" in that repeat runs 16 | # begin by deleting what was created: the local repo and repo in GitHub. 17 | 18 | # Sample call in MacOS Terminal shell window: 19 | # chmod +x git-sample-repo-create.sh 20 | # ./git-sample-repo-create.sh 21 | 22 | # Last tested on MacOS 10.11 (El Capitan) 2015-09-15 23 | # TODO: Create a PowerShell script that works on Windows: 24 | # git-sample-repo-create.ps1 25 | 26 | # Create blank lines in the log to differentiate different runs: 27 | echo "" 28 | echo "" 29 | echo "" 30 | echo "" 31 | echo "" 32 | TZ=":UTC" date +%z 33 | NOW=$(date +%Y-%m-%d:%H:%M:%S%z) 34 | # 2016-09-16T05:26-06:00 vs UTC 35 | 36 | # Make the beginning of run easy to find: 37 | echo "**********************************************************" 38 | echo "******** $NOW Versions :" 39 | # After "brew install git" on Mac: 40 | git --version 41 | 42 | # exit #1 43 | 44 | echo "******** STEP .secret Attribution & Config (not --global):" 45 | # Invoke file defined manually containing definition of GITHUB_PASSWORD: 46 | source ~/.secrets # but don't echo "GITHUB_PASSWORD=$GITHUB_PASSWORD" 47 | 48 | # See https://git-scm.com/docs/pretty-formats : 49 | git config user.email $GITHUB_USER_EMAIL # "wilsonmar@gmail.com" 50 | git config user.name $GITHUB_USER_NAME # "Wilson Mar" # Username (not email) in GitHub.com cloud. 51 | git config user.user $GITHUB_USER # "wilsonmar" # Username (not email) in GitHub.com cloud. 52 | #GITHUB_USER=$(git config github.email) # Username (not email) in GitHub.com cloud. 53 | echo "GITHUB_USER_EMAIL= $GITHUB_USER_EMAIL" 54 | # echo $GIT_AUTHOR_EMAIL 55 | # echo $GIT_COMMITTER_EMAIL 56 | 57 | # After gpg is installed and # gpg --gen-key: 58 | git config --global user.signingkey $GITHUB_SIGNING_KEY 59 | # gpg --list-keys 60 | 61 | 62 | 63 | REPONAME='git-sample-repo' 64 | GITHUB_USER="wilsonmar" 65 | DESCRIPTION="Automated Git repo from run using $REPONAME in https://github.com/wilsonmar/git-utilities." 66 | 67 | echo "******** GITHUB_USER=$GITHUB_USER " 68 | 69 | # exit #2 70 | 71 | echo "******** STEP Delete \"$REPONAME\" remnant from previous run:" 72 | # set -x # xtrace command echo on (with ++ prefix). http://www.faqs.org/docs/abs/HTML/options.html 73 | # Remove folder if exists (no symbolic links are used here): 74 | if [ -d ${REPONAME} ]; then 75 | rm -rf ${REPONAME} 76 | fi 77 | 78 | # Remove folder because files are built (not cloned in): 79 | mkdir ${REPONAME} 80 | cd ${REPONAME} 81 | 82 | CURRENTDIR=${PWD##*/} 83 | 84 | echo "CURRENTDIR=$CURRENTDIR" 85 | 86 | # exit #3 87 | 88 | 89 | echo "******** Ensure \"$REPONAME\" folder is in .gitignore file:" 90 | # -F for fixed-strings, -x to match whole line, -q for quiet (not show text sought) 91 | if grep -Fxq "${REPONAME}" .gitignore ; then 92 | echo "FOUND within .gitignore file." 93 | else 94 | echo ${REPONAME}>>.gitignore 95 | # sed 's/fields/fields\nNew Inserted Line/' .gitignore 96 | echo "Added to bottom of .gitignore file." 97 | fi 98 | 99 | # exit #4 100 | 101 | 102 | echo "******** STEP Init repo :" 103 | # init without --bare so we get a working directory: 104 | git init 105 | # return the .git path of the current project:: 106 | git rev-parse --git-dir 107 | ls .git/ 108 | 109 | echo "******** STEP Make develop the default branch instead of master :" 110 | # The contents of HEAD is stored in this file: 111 | cat .git/HEAD 112 | 113 | # Change from default "ref: refs/heads/master" : 114 | # See http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html 115 | DEFAULT_BRANCH="develop" 116 | git symbolic-ref HEAD refs/heads/$DEFAULT_BRANCH 117 | cat .git/HEAD 118 | git branch -avv 119 | # echo $DEFAULT_BRANCH 120 | 121 | # exit #5 122 | 123 | echo "******** Configure git aliases : " 124 | 125 | # Verify settings: 126 | git config core.filemode false 127 | git config core.autocrlf input 128 | git config core.safecrlf true 129 | 130 | # On Unix systems, ignore ^M symbols created by Windows: 131 | # git config core.whitespace cr-at-eol 132 | 133 | # Change default commit message editor program to Sublime Text (instead of vi): 134 | git config core.editor "~/Sublime\ Text\ 3/sublime_text -w" 135 | 136 | # Allow all Git commands to use colored output, if possible: 137 | git config color.ui auto 138 | 139 | # See https://git-scm.com/docs/pretty-formats : Add "| %G?" for signing 140 | # In Windows, double quotes are needed: 141 | git config alias.l "log --pretty='%Cred%h%Creset %C(yellow)%d%Creset | %Cblue%s%Creset' --graph" 142 | 143 | git config alias.s "status -s" 144 | #it config alias.w "show -s --quiet --pretty=format:'%Cred%h%Creset | %Cblue%s%Creset | (%cr) %Cgreen<%ae>%Creset'" 145 | git config alias.w "show -s --quiet --pretty=format:'%Cred%h%Creset | %Cblue%s%Creset'" 146 | git config alias.ca "commit -a --amend -C HEAD" # (with no message) 147 | 148 | # Have git diff use mnemonic prefixes (index, work tree, commit, object) instead of standard a and b notation: 149 | git config diff.mnemonicprefix true 150 | 151 | # Reuse recorded resolution of conflicted merges - https://git-scm.com/docs/git-rerere 152 | git config rerere.enabled false 153 | 154 | # git config --list # Dump config file 155 | 156 | echo "******** git count-objects -v : baseline " 157 | # Get the size of what was transmitted on the current repo folder: 158 | git count-objects -v 159 | 160 | echo "******** git remote show origin : " 161 | git remote show origin 162 | 163 | # exit #6 164 | 165 | 166 | echo "******** STEP commit (initial) README :" 167 | echo -e "Hello" >>README.md 168 | git add . 169 | git commit -m "README.md" 170 | git l -1 171 | 172 | exit #11 173 | 174 | echo "******** STEP amend commit README : " 175 | # ammend last commit with all uncommitted and un-staged changes: 176 | # See http://unix.stackexchange.com/questions/219268/how-to-add-new-lines-when-using- echo 177 | echo -e "color">>README.md 178 | git ca # use this alias instead of git commit -a --amend -C HEAD 179 | git l -1 180 | 181 | echo "******** STEP amend commit 2 : " 182 | # ammend last commit with all uncommitted and un-staged changes: 183 | echo -e "still more\r\n">>README.md 184 | git ca # alias for git commit -a --amend -C HEAD 185 | git l -1 186 | 187 | echo "******** STEP commit .DS_Store in .gitignore :" 188 | echo ".DS_Store">>.gitignore 189 | git add . 190 | git commit -m "Add .gitignore" 191 | git l -1 192 | 193 | echo "******** STEP commit --amend .secrets in .gitignore :" 194 | echo "secrets">>.gitignore 195 | echo ".secrets">>.gitignore 196 | git add . 197 | git ca # use this alias instead of git commit -a --amend -C HEAD 198 | git l -1 199 | 200 | git reflog 201 | ls -al 202 | 203 | # cat README.md 204 | 205 | # echo "******** rebase squash : " 206 | 207 | echo "******** STEP lightweight tag :" 208 | git tag "v1" # lightweight tag 209 | git l 210 | 211 | exit #15 212 | 213 | 214 | echo "******** STEP checkout HEAD to create feature1 branch : --------------------------" 215 | git checkout HEAD -b feature1 216 | # git branch 217 | ls .git/refs/heads/ 218 | git l -1 219 | 220 | echo "******** STEP commit c - LICENSE.md : " 221 | echo -e "MIT\r\n">>LICENSE.md 222 | git add . 223 | git commit -m "Add c" 224 | git l -1 225 | ls -al 226 | 227 | echo "******** STEP commit: d" 228 | echo -e "free!">>LICENSE.md 229 | echo "d">>file-d.txt 230 | git add . 231 | git commit -m "Add d in feature1" 232 | git l -1 233 | ls -al 234 | 235 | # echo "******** STEP Merge feature1 :" 236 | # Instead of git checkout $DEFAULT_BRANCH : 237 | # git checkout @{-1} # checkout previous branch (develop, master) 238 | 239 | echo "******** STEP Merge feature1 :" 240 | # Alternately, use git-m.sh to merge and delete in one step. 241 | # git merge --no-ff (no fast forward) for "true merge": 242 | #git merge feature1 --no-ff --no-commit # to see what may happen 243 | git merge feature1 -m "merge feature1" --no-ff # --verify-signatures 244 | # resolve conflicts here? 245 | git add . 246 | # git commit -m "commit merge feature1" 247 | git branch 248 | git l -1 249 | 250 | echo "******** $NOW Remove merged branch ref :" 251 | git branch -D feature1 252 | git branch 253 | 254 | echo "******** $NOW What's dangling? " 255 | git fsck --dangling --no-progress 256 | git l -1 257 | 258 | echo "******** STEP commit: e" 259 | echo "e money">>file-e.txt 260 | git add . 261 | git commit -m "Add e" 262 | git l -1 263 | 264 | echo "******** STEP commit: f" 265 | echo "f money">>file-f.txt 266 | ls -al 267 | git add . 268 | git commit -m "Add f" 269 | git l -1 270 | 271 | echo "******** STEP heavyeight tag (a commit) :" 272 | # git tag -a v0.0.1 -m"v1 unsigned" 273 | git tag -a v0.0.1 -m"v1 signed" -s # signed "heavyweight" tag 274 | # For numbering, see http://semver.org/ 275 | # echo "******** STEP tag verify :" 276 | # git tag -v v1 # calls verify-tag. 277 | git verify-tag v0.0.1 278 | 279 | # echo "******** STEP tag show :" 280 | # git show v1 # Press q to exit scroll. 281 | 282 | exit #21 283 | 284 | 285 | echo "Copy this and paste to a text edit for reference: --------------" 286 | git l 287 | echo "******** show HEAD : ---------------------------------------" 288 | git w HEAD 289 | echo "******** show HEAD~1 :" 290 | git w HEAD~1 291 | echo "******** show HEAD~2 :" 292 | git w HEAD~2 293 | echo "******** show HEAD~3 :" 294 | git w HEAD~3 295 | echo "******** show HEAD~4 :" 296 | git w HEAD~4 297 | 298 | echo "******** show HEAD^ :" 299 | git w HEAD^ 300 | echo "******** show HEAD^^ :" 301 | git w HEAD^^ 302 | echo "******** show HEAD^^^ :" 303 | git w HEAD^^^ 304 | echo "******** show HEAD^^^^ :" 305 | git w HEAD^^^^ 306 | 307 | echo "******** show HEAD^1 :" 308 | git w HEAD^1 309 | echo "******** show HEAD^2 :" 310 | git w HEAD^2 311 | 312 | echo "******** show HEAD~1^1 :" 313 | git w HEAD~1^1 314 | echo "******** show HEAD~2^1 :" 315 | git w HEAD~2^1 316 | echo "******** show HEAD~3^1 :" 317 | git w HEAD~3^1 318 | 319 | echo "******** show HEAD~1^2 :" 320 | git w HEAD~1^2 321 | 322 | echo "******** show HEAD~2^2 :" 323 | git w HEAD~2^2 324 | echo "******** show HEAD~2^3 :" 325 | git w HEAD~2^3 326 | ls -al 327 | 328 | exit #31 329 | 330 | echo "******** Reflog: ---------------------------------------" 331 | git reflog 332 | echo "******** show HEAD@{5} :" 333 | git w HEAD@{5} 334 | 335 | 336 | echo "******** STEP Create archive file, excluding .git directory :" 337 | TZ=":UTC" date +%z 338 | NOW=$(date +%Y-%m-%d:%H:%M:%S%z) 339 | # 2016-09-16T05:26-06:00 vs UTC 340 | FILENAME=$( echo ${REPONAME}_${NOW}.zip) 341 | 342 | echo "FILENAME=$FILENAME" 343 | 344 | # echo "******** STEP Creating a zip file :" 345 | # Commented out to avoid creating a file from each run: 346 | # git archive --format zip --output ../$FILENAME feature1 347 | # ls -l ../$FILENAME 348 | 349 | 350 | echo "******** STEP checkout c :" 351 | ls -al 352 | git show HEAD@{5} 353 | git checkout HEAD@{5} 354 | ls -al 355 | 356 | echo "******** Go back to HEAD --hard :" 357 | git reset --hard HEAD 358 | # git checkout HEAD 359 | ls -al 360 | 361 | 362 | echo "******** Garbage Collect (gc) what Git can't reach :" 363 | git gc 364 | git reflog 365 | ls -al 366 | echo "******** Compare against previous reflog." 367 | 368 | 369 | # See https://gist.github.com/caspyin/2288960 about GitHub API 370 | # From https://gist.github.com/robwierzbowski/5430952 on Windows 371 | # From https://gist.github.com/jerrykrinock/6618003 on Mac 372 | 373 | echo "****** GITHUB_USER=$GITHUB_USER, CURRENTDIR=$CURRENTDIR, REPONAME=$REPONAME" 374 | echo "****** DESCRIPTION=$DESCRIPTION" 375 | # Bash command to load contents of file into env. variable: 376 | export RSA_PUBLIC_KEY=$(cat ~/.ssh/id_rsa.pub) 377 | # TODO: Windows version. 378 | # echo "RSA_PUBLIC_KEY=$RSA_PUBLIC_KEY" 379 | 380 | exit #41 381 | 382 | # The following use jq installed locally. 383 | 384 | # Since no need to create another token if one already exists: 385 | if [ "$GITHUB_TOKEN" = "" ]; then # Not run before 386 | echo "******** Creating Auth GITHUB_TOKEN to delete repo later : " 387 | GITHUB_TOKEN=$(curl -v -u "$GITHUB_USER:$GITHUB_PASSWORD" -X POST https://api.github.com/authorizations -d "{\"scopes\":[\"delete_repo\"], \"note\":\"token with delete repo scope\"}" | jq ".token") 388 | # Do not echo GITHUB_TOKEN=$GITHUB_TOKEN # secret 389 | # API Token (32 character long string) is unique among all GitHub users. 390 | # Response: X-OAuth-Scopes: user, public_repo, repo, gist, delete_repo scope. 391 | # See https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization 392 | 393 | # WORKFLOW: Manually see API Tokens on GitHub | Account Settings | Administrative Information 394 | else 395 | echo "******** Verifying Auth GITHUB_TOKEN to delete repo later : " 396 | # FIX: Commented out due to syntax error near unexpected token `|' 397 | GITHUB_AVAIL=$(curl -v -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com | jq ".authorizations_url") 398 | echo "******** authorizations_url=$GITHUB_AVAIL" 399 | # https://api.github.com/authorizations" 400 | fi 401 | 402 | #### 403 | echo "******** Checking GITHUB repo exists (_AVAIL) from prior run: " 404 | GITHUB_AVAIL=$(curl -X GET https://api.github.com/repos/${GITHUB_USER}/${REPONAME} | jq ".full_name") 405 | echo "GITHUB_AVAIL=$GITHUB_AVAIL (null if not exist)" 406 | # Expecting "full_name": "wilsonmar/git-sample-repo", 407 | # TODO: Fix return of null. 408 | 409 | if [ "$GITHUB_AVAIL" = "${GITHUB_USER}/${REPONAME}" ]; then # Not run before 410 | echo "******** Deleting GITHUB_REPO created earlier : " 411 | # TODO: Delete repo in GitHub.com Settings if it already exists: 412 | # Based on https://gist.github.com/JadedEvan/5639254 413 | # See http://stackoverflow.com/questions/19319516/how-to-delete-a-github-repo-using-the-api 414 | GITHUB_AVAIL=$(curl -X DELETE -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/${GITHUB_USER}/${REPONAME} | jq ".full_name") 415 | # Response is 204 No Content per https://developer.github.com/v3/repos/#delete-a-repository 416 | echo "GITHUB_AVAIL=$GITHUB_AVAIL deleted." 417 | else 418 | echo "******** No GITHUB repo known to delete. " 419 | fi 420 | 421 | #### Create repo in GitHub: 422 | echo "******** Creating GITHUB repo. " 423 | GITHUB_AVAIL=$(curl -u $GITHUB_USER:$GITHUB_PASSWORD https://api.github.com/user/repos -d "{\"name\": \"${REPONAME:-${CURRENTDIR}}\", \"description\": \"${DESCRIPTION}\", \"private\": false, \"has_issues\": false, \"has_downloads\": true, \"has_wiki\": false}" | jq ".full_name") 424 | echo "GITHUB_AVAIL=$GITHUB_AVAIL created." 425 | GITHUB_PASSWORD="" # No longer needed. 426 | 427 | # Set the freshly created repo to the origin and push 428 | git remote add origin "https://github.com/$GITHUB_USER/$REPONAME.git" 429 | git remote -v 430 | git push --set-upstream origin develop 431 | git remote show origin 432 | # git remote set-url origin git@github.com:${GITHUB_USER}/${REPONAME}.git 433 | # git remote set-head origin develop 434 | # git config branch.develop.remote origin 435 | # fi 436 | 437 | echo "********** DOTHIS: Manually make a change online GitHub file : " 438 | echo "Add to bottom of README.md \"Changed online\" and Save." 439 | read "WAITING FOR RESPONSE: Press Enter/Return to continue:" 440 | 441 | echo "********** Making change that will be duplicated online : " 442 | echo -e "Change locally\r\n">>README.md 443 | 444 | # echo "********** Doing git pull to create conflict : " 445 | # git pull 446 | echo "********** Doing git fetch a conflict : " 447 | git fetch 448 | git merge origin/develop 449 | 450 | exit #51 451 | 452 | # git stash save "text message here" 453 | 454 | # git stash list /* shows whats in stash */ 455 | # git stash show -p stash@{0} /* Show the diff in the stash */ 456 | 457 | # git stash pop stash@{0} /* restores the stash deletes the tash */ 458 | # git stash apply stash@{0} /* restores the stash and keeps the stash */ 459 | # git stash drop stash@{0} 460 | # git stash clear /* removes all stash */ 461 | 462 | 463 | # Undo last commit, preserving local changes: 464 | # git reset --soft HEAD~1 465 | 466 | # Undo last commit, without preserving local changes: 467 | # git reset --hard HEAD~1 468 | 469 | # Undo last commit, preserving local changes in index: 470 | # git reset --mixed HEAD~1 471 | 472 | # Undo non-pushed commits: 473 | # git reset origin/$DEFAULT_BRANCH 474 | 475 | 476 | # Revert a range of the last two commits: 477 | # git revert HEAD~2..HEAD 478 | # Create several revert commits: 479 | # git revert a867b4af 25eee4ca 0766c053 480 | 481 | # Reverting a merge commit 482 | # git revert -m 1 483 | # See http://git-scm.com/blog/2010/03/02/undoing-merges.html 484 | 485 | 486 | # From https://www.youtube.com/watch?v=sevc6668cQ0&t=41m40s 487 | # git rebase master --exec "make test" 488 | 489 | # echo "******** Bisect loop : " 490 | # for loop: 491 | # git bisect start 492 | # git bisect good master 493 | # git bisect run make test 494 | # end loop 495 | 496 | # echo "******** Remote commands : " 497 | # git fetch origin 498 | # git reset --hard origin/$DEFAULT_BRANCH 499 | 500 | # echo "******** Cover your tracks:" 501 | # Remove from repository all locally deleted files: 502 | # git rm $(git ls-files --deleted) 503 | 504 | # Move the branch pointer back to the previous HEAD: 505 | # git reset --soft HEAD@{1} 506 | 507 | 508 | # Commented out for cleanup at start of next run: 509 | # cd .. 510 | # rm -rf ${REPONAME} 511 | 512 | echo "******** $NOW end." 513 | -------------------------------------------------------------------------------- /git-sisters-update.ps1: -------------------------------------------------------------------------------- 1 | # git-sisters-update.ps1 from within http://github.com/wilsonmar/git-utilities. 2 | # by Wilson Mar (wilsonmar@gmail.com, @wilsonmar) 3 | 4 | # This script was created for experiementing and learning Git with GitHub. 5 | # Git commands in this script are meant as examples for manual entry 6 | # explained during my live "Git and GitHub" tutorials and 7 | # explained at https://wilsonmar.github.io/git-commands-and-statuses/). 8 | # Most of the regularly used Git commands are covered here. 9 | 10 | # This script clones and edits a sample repo with known history. 11 | 12 | # This script is designed to be "idempotent" in that repeat runs 13 | # result in the same condition whether it's run the first or subsequent times. 14 | # This is achieved by beginning the run by deleting what was created 15 | # by the previous run. 16 | 17 | # PRE-REQUSITES: Before running this on a Mac, install PowerShell for Mac. 18 | # TODO: Add handling of script call attribute containing REPONAME and GITHUB_USER: 19 | $GITHUB_USERID="wilson-jetbloom" # <-- replace with your own 20 | 21 | # Sample call in MacOS running PowerShell for Mac: 22 | # chmod +x git-sisters-update.ps1 23 | # ./git-sisters-update.ps1 24 | # results in "Add " as branch name. Alternately, run script with your own branch: 25 | # ./git-sisters-update.ps1 "Add year 1979" 26 | 27 | # Last tested on MacOS 10.12 (Sierra) 2015-11-29 28 | # http://skimfeed.com/blog/windows-command-prompt-ls-equivalent-dir/ 29 | 30 | 31 | # PS TRICK: Functions must be defined at the top of the script. 32 | function sisters_new_photo-info 33 | { 34 | # sisters_new_photo-info 1979 "Bloomfield, Connecticut" 35 | $PIC_YEAR = $args[0] # 1979 or other year. 36 | $FILE_CONTEXT = "photo-info.md" # file name 37 | $PIC_CITY = $args[1] # City 38 | 39 | Remove-Item $FILE_CONTEXT -recurse -force # CAUTION: deleting file! 40 | # -force deletion of hidden and read only items. 41 | New-Item $FILE_CONTEXT >$null 42 | $NL = "`n" # New Line $s, $t -join ", " 43 | $OUT_STRING = "# Photo Information" +$NL 44 | $OUT_STRING += $NL 45 | $OUT_STRING += "**Year:** " +$PIC_YEAR +$NL # **Year:** 1978 46 | $OUT_STRING += $NL 47 | $OUT_STRING += "**City: ** " +$PIC_CITY +$NL # **City: ** Harwich Port, Massachusetts 48 | $OUT_STRING | Set-Content $FILE_CONTEXT 49 | 50 | echo "******** cat $FILE_CONTEXT for $PIC_YEAR : AFTER changes :" 51 | cat $FILE_CONTEXT 52 | } 53 | 54 | function sisters_new_meta_file 55 | { 56 | # TODO: 57 | $PERSON_NAME = $args[0] 58 | $FILE_CONTEXT = $args[0].ToLower() + ".md" # file name 59 | 60 | $SMILING = $args[1] # smiling true or false 61 | $CLOTHING = $args[2] 62 | 63 | Remove-Item $FILE_CONTEXT -recurse -force # CAUTION: deleting file! 64 | # -force deletion of hidden and read only items. 65 | New-Item $FILE_CONTEXT >$null 66 | 67 | $NL = "`n" # New Line $s, $t -join ", " 68 | $OUT_STRING = "# $PERSON_NAME" +$NL 69 | $OUT_STRING += $NL 70 | # PROTIP: Double grave-accent(`) to use back-tick as regular text: 71 | $OUT_STRING += "**Smiling:** ``$SMILING``" +$NL 72 | $OUT_STRING += $NL 73 | $OUT_STRING += "**Outfit:** $CLOTHING" 74 | $OUT_STRING | Set-Content $FILE_CONTEXT 75 | 76 | echo "******** cat $FILE_CONTEXT : AFTER changes :" 77 | cat $FILE_CONTEXT 78 | } 79 | 80 | function sisters_replace_meta_file 81 | { 82 | $PERSON_NAME = $args[0] 83 | $FILE_CONTEXT = $args[0].ToLower() + ".md" # file name 84 | echo "******** cat $FILE_CONTEXT : BEFORE change :" 85 | cat $FILE_CONTEXT 86 | 87 | echo "******** processing $FILE_CONTEXT :" 88 | #$SMILING = $args[1] # smiling true or false 89 | #$CLOTHING = $args[2] 90 | 91 | # Get-Content info: https://technet.microsoft.com/en-us/library/ee176843.aspx 92 | $WORK_TEXT = Get-Content $FILE_CONTEXT 93 | #cat $WORK_TEXT 94 | 95 | # About regex in PowerShell: https://www.youtube.com/watch?v=K3JKmWmbbGM 96 | if ($args[1] -eq "true"){ 97 | $WORK_TEXT -replace '(\*\*Smiling:\*\* `true`)' ,'\*\*Smiling:\*\* `false`' 98 | }else{ # -eq "false" 99 | $WORK_TEXT -replace '(\*\*Smiling:\*\* `false`)','\*\*Smiling:\*\* `true`' 100 | } 101 | 102 | $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False) 103 | [System.IO.File]::WriteAllLines($MyPath, $WORK_TEXT, $Utf8NoBomEncoding) 104 | # $WORK_TEXT | Set-Content $FILE_CONTEXT 105 | # Set-Content info: https://msdn.microsoft.com/powershell/reference/5.1/microsoft.powershell.management/Set-Content?f=255&MSPPError=-2147217396 106 | 107 | # PROTIP: Use https://regex101.com/ using Flavor: PY (python) to verify: 108 | # Put slashes in front of special characters used as regular text: 109 | 110 | echo "******** cat $FILE_CONTEXT : AFTER changes :" 111 | cat $FILE_CONTEXT 112 | } 113 | 114 | function du-hs { 115 | # Size of bytes in folder: instead of Linux command): du -hs ${REPONAME} 116 | # (7 files in 1475 bytes) https://blogs.technet.microsoft.com/heyscriptingguy/2012/05/25/getting-directory-sizes-in-powershell/ 117 | Get-ChildItem $REPONAME | Measure-Object -Sum Length | Select-Object Count, Sum 118 | } 119 | 120 | ################################# 121 | 122 | # Create blank lines in the log to differentiate different runs: 123 | # Clear-Host # clear in PowerShell see https://kgk.gr/2011/10/16/powershell-clrscr/ 124 | echo "" 125 | echo "" 126 | echo "" 127 | echo "" 128 | echo "" 129 | # Make the beginning of run easy to find: 130 | echo "**********************************************************" 131 | $NOW = Get-Date -Format "yyyy-MM-ddTHH:mmzzz" 132 | echo "******** NOW=$NOW $PSUICULTURE PID=$PID :" 133 | # $PSUICULTURE & $PID are built-in variables. 134 | $PSHOME #$psversiontable 135 | echo "******** IsWindows=$IsWindows IsOSX=$IsOSX IsLinux=$IsLinux" 136 | #[System.Environment]::OSVersion.Version 137 | echo "******** PSSCRIPTROOT= $PSSCRIPTROOT" 138 | git --version 139 | 140 | # exit #1 141 | 142 | $REPONAME='sisters' 143 | $UPSTREAM="https://github.com/hotwilson/sisters" # a repo prepared for the class. 144 | $CURRENT_COMMIT="" 145 | 146 | echo "******** Delete $REPONAME remaining from previous run (for idempotent script):" 147 | $FileExists = Test-Path $REPONAME 148 | if ($FileExists -eq $True ){ 149 | # See https://technet.microsoft.com/en-ca/library/hh849765.aspx?f=255&MSPPError=-2147217396 150 | Remove-Item -path ${REPONAME} -Recurse -Force # instead of rm -rf ${REPONAME} 151 | } 152 | echo "******** Exit #2." 153 | # exit #2 154 | 155 | # New-item ${REPONAME} -ItemType "directory" >$null # instead of mkdir ${REPONAME} 156 | # >$null suporesses several lines being printing out by PS to confirm. 157 | 158 | $GITHUB_REPO="https://github.com/"+ $GITHUB_USERID +"/"+ $REPONAME 159 | echo "******** Before running this, fork from $UPSTREAM " 160 | echo "******** git clone $GITHUB_REPO " 161 | # Notice the string concatenation format: 162 | git clone "$($GITHUB_REPO).git" # $REPONAME # --depth=1 163 | 164 | echo "******** git tag -l cloned # lightweight tag for private temp use :" 165 | git tag -l cloned 166 | # Note no spaces and thus no quotes. 167 | echo "******** git tag (list) :" 168 | git tag 169 | echo "******** git log :" 170 | git l -3 171 | 172 | echo "******** Exit #3." 173 | # exit #3 174 | 175 | echo "******** Ensure $REPONAME folder is specified in .gitignore file:" 176 | # & ((Split-Path $MyInvocation.InvocationName) + "\my_ps_functions.ps1") 177 | if (Test-Path ".gitignore"){ 178 | echo "******** .gitignore file found within ${REPONAME} folder :" 179 | Select-String -Pattern "$REPONAME" -Path ".gitignore" > $null # -CaseSensitive 180 | #get-content myfile.txt -ReadCount 1000 | foreach { $_ -match "my_string" } 181 | echo "******** ${REPONAME} FOUND within .gitignore file." 182 | } Else { 183 | echo "${REPONAME}">>.gitignore # save text at bottom of file. 184 | # sed 's/fields/fields\nNew Inserted Line/' .gitignore 185 | echo "******** ${REPONAME} added to bottom of .gitignore file." 186 | } 187 | 188 | echo "******** Exit #4." 189 | # exit #4 190 | 191 | 192 | cd ${REPONAME} 193 | $CurrentDir = $(get-location).Path; 194 | # This outputs the parent folder, not the current folder: 195 | #$CURRENTDIR = (Get-Item -Path ".\" -Verbose).FullName # Get-Location cmdlet 196 | #$CURRENTDIR = $PSScriptRoot # PowerShell specific 197 | # echo "CURRENTDIR=$CURRENTDIR" 198 | echo "******** Now in $REPONAME folder! - cd .. before re-run!" 199 | echo $CURRENTDIR 200 | 201 | # exit #5 202 | 203 | 204 | echo "******** Run PowerShell file for Git configurations at the repo level:" 205 | # PS TRICK: Get parent folder path using the $MyInvocation built-in PS variable: 206 | # See http://stackoverflow.com/questions/7377981/how-do-i-call-another-powershell-script-with-a-relative-path 207 | $ScriptPath = Split-Path -Parent $MyInvocation.InvocationName 208 | $UtilPath = Join-Path -Path $ScriptPath -ChildPath ..\ 209 | #Write-Host "Path:" $UtilPath 210 | # NOTE: PowerShell accepts both forward and backward slashes: 211 | & "$UtilPath/git-client-config.ps1" 212 | # Alternately, use & to run scripts in same scope: 213 | # & "../git_client-config.ps1 global" # 214 | # Alternately, use . to run scripts in child scope that will be thrown away: 215 | # . "../git_client-config.ps1 global" # 216 | #echo "******** Present Working Directory :" 217 | #pwd 218 | 219 | echo "******** Exit #6." 220 | # exit #6 221 | 222 | Write-Host "******** git remote add upstream $UPSTREAM :" 223 | git remote add upstream ${UPSTREAM} 224 | Write-Host "******** git remote -v :" 225 | git remote -v 226 | Write-Host "******** git remote show origin :" 227 | git remote show origin 228 | 229 | echo "******** cat .git/HEAD to show internal current branch HEAD :" 230 | # The contents of HEAD is stored in this file: 231 | cat .git/HEAD 232 | 233 | echo "******** git branch -avv at master:" 234 | git branch -avv # shows tracking branches 235 | # In Merge lesson, change hotwilson GitHub at this point and git merge 236 | 237 | echo "******** Exit #7." 238 | # exit #7 239 | 240 | echo "******** git l = git log of commits in repo:" 241 | # add -10 to list 10 lines using l for log alias: 242 | git l 243 | echo "******** tree of folders in working area:" 244 | # PS TRICK: Different commands to list folders with properties: 245 | if( "$IsWindows" -eq $True ) { 246 | dir 247 | }else{ # Mac / Linux: 248 | ls # -al 249 | } 250 | #tree 251 | echo "******** git reflog (showing only what occurred locally):" 252 | git reflog 253 | 254 | # These above commands cover the dimensions: branch, commits, working directory, staging, lines, hunks. 255 | 256 | echo "******** git status at initial clone:" 257 | git status 258 | 259 | echo "******** Exit #8." 260 | # exit #8 261 | 262 | echo "******** cat ${REPONAME}/bebe.md at HEAD:" 263 | cat bebe.md 264 | 265 | echo "******** git blame bebe.md : " 266 | git blame bebe.md 267 | # NOTE: 268 | echo "******** git l = git log of commits in repo:" 269 | # add -10 to list 10 lines using l for log alias: 270 | git l -10 271 | # Notice the title "BeBe" and blank lines in the file are from the initial commit. 272 | # Two lines were changed in the latest commit. 273 | 274 | echo "******** Exit #9." 275 | # exit #9 276 | 277 | # echo "******** git show --oneline --abbrev-commit - press q to quit:" 278 | # git show --oneline --abbrev-commit 279 | 280 | git diff HEAD..HEAD^ 281 | 282 | echo "******** Exit #10." 283 | # exit #10 284 | 285 | # echo "******** Begin trace :" 286 | # # Do not set trace on: 287 | # set -x # xtrace command echo on (with ++ prefix). http://www.faqs.org/docs/abs/HTML/options.html 288 | 289 | echo "******** git checkout master branch:" 290 | git checkout master 291 | 292 | # PS TRICK: Check for no arguments specified with invocation command: 293 | if( $($args.Count) -eq 0 ) { 294 | $CURRENT_BRANCH="feature1" 295 | }else{ 296 | $CURRENT_BRANCH=$args[0] 297 | } 298 | echo "******** git checkout new branch ""$CURRENT_BRANCH"" from master branch :" 299 | git checkout -b $CURRENT_BRANCH 300 | git branch -avv 301 | # PS TRICK: Double-quotes to display words in quotes: 302 | echo "******** git reflog at ""$CURRENT_BRANCH"" :" 303 | git reflog 304 | 305 | echo "******** Exit #11." 306 | # exit #11 307 | 308 | $CURRENT_YEAR = "1979" 309 | echo "******** Make changes to $CURRENT_YEAR files and stage it at $CURRENT_COMMIT :" 310 | sisters_new_photo-info $CURRENT_YEAR "Hartford, Connecticut" 311 | 312 | #sisters_new_meta_file BeBe false "White buttoned shirt" 313 | # Notice the person name is upper/lower case: 314 | 315 | echo "******** Exit #12." 316 | # exit #12 317 | 318 | echo "******** git checkout ""@{10 minutes ago}"" :" 319 | git checkout "@{10 minutes ago}" 320 | 321 | sisters_new_meta_file Bebe false "White buttoned shirt" 322 | # Notice the person name is unchanged from previous commits: 323 | 324 | # echo "******** git add -p (hunks interactive) :" 325 | #git add -p # GUI (requires manual response) 326 | 327 | echo "******** Exit #13." 328 | exit #13 329 | 330 | sisters_new_meta_file Heather true "Plaid shirt" 331 | sisters_new_meta_file Laurie false "Cable-knit sweater" 332 | sisters_new_meta_file Mimi false "French sailor shirt" 333 | 334 | echo "******** Exit #14." 335 | # exit #14 336 | 337 | echo "******** git stash :" 338 | git stash 339 | # Response: 340 | # Saved working directory and index state WIP on feature1: ea2db2c Snapshot for 1978 341 | # HEAD is now at ea2db2c Snapshot for 1978 342 | echo "******** git stash list :" 343 | git stash list 344 | # Response: stash@{0}: WIP on feature1: ea2db2c Snapshot for 1978 345 | 346 | echo "******** git status (after git stash) :" 347 | git status 348 | 349 | echo "******** Exit #15." 350 | # exit #15 351 | 352 | # Do something else 353 | 354 | echo "******** git stash pop :" 355 | git stash pop 356 | echo "******** git status : before git add :" 357 | git status 358 | 359 | echo "******** Exit #16." 360 | # exit #16 361 | 362 | echo "******** git add . :" 363 | git add . # photo-info.md bebe.md heather.md laurie.md mimi.md 364 | echo "******** git status : after git add " 365 | git status 366 | echo "******** git commit of $CURRENT_YEAR (new commit SHA) :" 367 | git commit -m"Snapshot for $CURRENT_YEAR" 368 | echo "******** git status : after git add " 369 | git status 370 | echo "******** git diff (files committed and will be pushed) :" 371 | git diff --stat HEAD origin/$CURRENT_BRANCH 372 | #git cherry -v 373 | #git diff origin/master..master 374 | #git diff --stat HEAD --cached origin/$CURRENT_BRANCH 375 | # echo "******** git diff (contents of what has been committed and will be pushed) :" 376 | #git diff --stat --patch origin master 377 | #git diff origin/master HEAD 378 | echo "******** git reflog at ""$CURRENT_BRANCH"" :" 379 | git reflog 380 | echo "******** git git diff HEAD^ :" 381 | git diff HEAD^ 382 | echo "******** git l = git log of commits in repo:" 383 | git l 384 | 385 | echo "******** Exit #17." 386 | exit #17 --- major checkpoint here. 387 | 388 | # Export an entire branch, complete with history, to the specified file: 389 | # git bundle create 390 | 391 | # Re-create a project from a bundled repository and checkout : 392 | # git clone repo.bundle -b 393 | 394 | # echo "******** git archive master :" 395 | if( "$make_archive" -eq $True ) { 396 | if( "$IsWindows" -eq $True ) { 397 | git archive $CURRENT_BRANCH --format=zip --output=$REPONAME_$CURRENT_BRANCH_$REPONAME.zip 398 | }else{ # Mac / Linux: 399 | git archive $CURRENT_BRANCH --format=tar --output=$REPONAME_$CURRENT_BRANCH_$REPONAME.tar 400 | } 401 | } 402 | # list files archived. 403 | 404 | echo "******** Exit #18." 405 | exit #18 406 | 407 | 408 | #git push --dry-run 409 | 410 | 411 | echo "******** Exit #20." 412 | exit #19 413 | #exit #20 reserved 414 | 415 | 416 | # TODO: Extract $CURRENT_COMMIT from capturing git command. 417 | 418 | $CURRENT_COMMIT="c4b84db" 419 | echo "******** git checkout $CURRENT_COMMIT : (parent branch) :" 420 | git checkout $CURRENT_COMMIT 421 | echo "******** cat .git/HEAD :" 422 | cat .git/HEAD # contains a commit SHA rather than HEAD 423 | echo "******** git checkout -b branch1 :" 424 | git checkout -b branch1 # Switched to a new branch 'branch1' 425 | 426 | echo "******** cat bebe.md at $CURRENT_COMMIT :" 427 | cat bebe.md 428 | echo "******** git log at $CURRENT_BRANCH :" 429 | git commit 430 | 431 | echo "******** Exit #21." 432 | exit #21 433 | 434 | $CURRENT_COMMIT="a874ef4" 435 | echo "******** git reset --soft $CURRENT_COMMIT (to remove it):" 436 | git reset --soft $CURRENT_COMMIT 437 | echo "******** git fsck after $CURRENT_COMMIT :" 438 | git fsck 439 | echo "******** git reflog at $CURRENT_BRANCH :" 440 | git reflog 441 | 442 | echo "******** Exit #22." 443 | exit #22 444 | 445 | echo "******** Make changes to files and stage it at $CURRENT_COMMIT :" 446 | echo "change 1">>bebe.md 447 | git add bebe.md 448 | echo "******** git reset HEAD at $CURRENT_COMMIT :" 449 | git reset HEAD 450 | echo "******** git fsck after $CURRENT_COMMIT :" 451 | git fsck 452 | 453 | echo "******** Exit #23." 454 | exit #23 455 | 456 | $CURRENT_COMMIT="82e957c" 457 | echo "******** git reset --hard a874ef2 :" 458 | git reset --hard $CURRENT_COMMIT 459 | echo "******** git fsck after $CURRENT_COMMIT :" 460 | git fsck 461 | 462 | 463 | echo "******** Exit #24. $NOW ends." 464 | exit #24 465 | 466 | ############################## 467 | 468 | # END OF FILE 469 | -------------------------------------------------------------------------------- /git-sisters-update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # git-sisters-update.sh from within http://github.com/wilsonmar/git-utilities. 4 | # by Wilson Mar (wilsonmar@gmail.com, @wilsonmar) 5 | 6 | # This script was created for experiementing and learning Git. 7 | # Git commands in this script are meant as examples for manual entry 8 | # explained during my live "Git and GitHub" tutorials and 9 | # explained at https://wilsonmar.github.io/git-commands-and-statuses/). 10 | # Most of the regularly used Git commands are covered here. 11 | 12 | # This script clones and edits a sample repo with known history. 13 | 14 | # This script is designed to be "idempotent" in that repeat runs 15 | # begin by deleting what was created: the local repo and repo in GitHub. 16 | 17 | # Sample call in MacOS Terminal shell window: 18 | # chmod +x git-sisters-update.sh 19 | # ./git-sisters-update.sh 20 | 21 | # Last tested on MacOS 10.11 (El Capitan) 2015-09-15 22 | # TODO: Create a PowerShell script that works on Windows: 23 | # git-sisters-update.ps1 24 | 25 | fancy_echo() { 26 | local fmt="$1"; shift 27 | 28 | # shellcheck disable=SC2059 29 | printf "\n$fmt\n" "$@" 30 | } 31 | 32 | # Create blank lines in the log to differentiate different runs: 33 | echo "" 34 | echo "" 35 | echo "" 36 | echo "" 37 | echo "" 38 | # Make the beginning of run easy to find: 39 | echo "**********************************************************" 40 | TZ=":UTC" date +%z 41 | NOW=$(date +%Y-%m-%d:%H:%M:%S%z) 42 | # 2016-09-16T05:26-06:00 vs UTC 43 | 44 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 45 | echo "******** Script from $DIR" 46 | 47 | echo "******** $NOW " 48 | # After "brew install git" on Mac: 49 | git --version 50 | 51 | 52 | # exit #1 53 | 54 | echo "******** Load secrets file :" 55 | # Change the name of your secrets file and edit the file: 56 | SECRETS_FILEPATH="~/.secrets" 57 | if [ -f ${SECRETS_FILEPATH} ]; then 58 | source ${SECRETS_FILEPATH} # load into env vars 59 | echo "******** GITHUB_USER=$GITHUB_USER - $USER"; 60 | else 61 | echo "File at ${SECRETS_FILEPATH} not found." 62 | GITHUB_USER="wilson-jetbloom" 63 | GITHUB_USER_EMAIL="wilsonmar@jetbloom.com" 64 | GITHUB_USER_NAME="Wilson Mar" 65 | fi 66 | 67 | # Check if variable is available: 68 | if [ -z ${GITHUB_USER+x} ]; then 69 | echo "******** GITHUB_USER=$GITHUB_USER : success."; 70 | else 71 | GITHUB_USER="wilson-jetbloom" 72 | echo "******** GITHUB_USER=$GITHUB_USER : default." 73 | fi 74 | 75 | # TODO: Check for existance of environment variable: 76 | 77 | # See https://git-scm.com/docs/pretty-formats : 78 | #git config user.email $GITHUB_USER_EMAIL # "hotmar@gmail.com" 79 | #git config user.name $GITHUB_USER_NAME # "Wilson Mar" # Username (not email) in GitHub.com cloud. 80 | #git config user.user $GITHUB_USER # Username (not email) in GitHub.com cloud. 81 | #GITHUB_USER=$(git config github.email) # Username (not email) in GitHub.com cloud. 82 | # echo "GITHUB_USER_EMAIL= $GITHUB_USER_EMAIL" # FIXME: Returns blank. 83 | # echo $GIT_AUTHOR_EMAIL 84 | # echo $GIT_COMMITTER_EMAIL 85 | 86 | # After gpg is installed and # gpg --gen-key: 87 | #git config --global user.signingkey $GITHUB_SIGNING_KEY 88 | # gpg --list-keys 89 | 90 | 91 | # TODO: Add handling of script call attribute containing REPONAME and GITHUB_USER: 92 | REPONAME='sisters' 93 | DESCRIPTION="Automated Git repo from run using $REPONAME." 94 | UPSTREAM="https://github.com/hotwilson/sisters" 95 | 96 | # exit #2 97 | 98 | echo "******** Delete \"$REPONAME\" remaining from previous run (for idempotent script):" 99 | # Remove folder if exists (no symbolic links are used here): 100 | if [[ -d ${REPONAME} ]]; then 101 | rm -rf ${REPONAME} 102 | fi 103 | 104 | # (No need to create a folder as that's what git clone does:) 105 | # mkdir ${REPONAME} 106 | # cd ${REPONAME} happens later on. 107 | 108 | 109 | echo "******** git clone sisters from GitHub over the internet: " 110 | # Hard-coded to use a repo prepared for the class: 111 | git clone ${UPSTREAM}.git ${REPONAME} # --depth=1 112 | # size of folder in KiloBytes (Linux command): 113 | du -hs ${REPONAME} 114 | 115 | # exit #3 116 | 117 | echo "******** Ensure \"$REPONAME\" folder is in .gitignore file:" 118 | # -F for fixed-strings, -x to match whole line, -q for quiet (not show text sought) 119 | if grep -Fxq "${REPONAME}" .gitignore ; then 120 | echo "\"${REPONAME}\" FOUND within .gitignore file." 121 | else 122 | echo "${REPONAME}">>.gitignore 123 | # sed 's/fields/fields\nNew Inserted Line/' .gitignore 124 | echo "${REPONAME} added to bottom of .gitignore file." 125 | fi 126 | # exit #4 127 | 128 | 129 | 130 | echo "******** Configure Git repo :" 131 | # TODO: Create separate shell file to define git aliases for repo. 132 | # Verify settings: 133 | git config core.filemode false 134 | git config core.autocrlf input 135 | git config core.safecrlf true 136 | 137 | # On Unix systems, ignore ^M symbols created by Windows: 138 | # git config core.whitespace cr-at-eol 139 | 140 | # Change default commit message editor program to Sublime Text (instead of vi): 141 | git config core.editor "~/Sublime\ Text\ 3/sublime_text -w" 142 | 143 | # Allow all Git commands to use colored output, if possible: 144 | git config color.ui auto 145 | 146 | # See https://git-scm.com/docs/pretty-formats : Add "| %G?" for signing 147 | # In Windows, double quotes are needed: 148 | git config alias.l "log --pretty='%Cred%h%Creset %C(yellow)%d%Creset | %Cblue%s%Creset' --graph" 149 | 150 | git config alias.s "status -s" 151 | #it config alias.w "show -s --quiet --pretty=format:'%Cred%h%Creset | %Cblue%s%Creset | (%cr) %Cgreen<%ae>%Creset'" 152 | git config alias.w "show -s --quiet --pretty=format:'%Cred%h%Creset | %Cblue%s%Creset'" 153 | git config alias.ca "commit -a --amend -C HEAD" # (with no message) 154 | 155 | # Have git diff use mnemonic prefixes (index, work tree, commit, object) instead of standard a and b notation: 156 | git config diff.mnemonicprefix true 157 | 158 | # Save & Reuse Recorded Resolution of conflicted merges - https://git-scm.com/docs/git-rerere 159 | git config rerere.enabled false 160 | 161 | # git config --list # Dump config file 162 | 163 | # exit #5 164 | 165 | echo "******** git remote add upstream :" 166 | git remote add upstream ${UPSTREAM} 167 | echo "******** git remote -v : locations :" 168 | git remote -v 169 | echo "******** git remote show origin :" 170 | git remote show origin 171 | 172 | # exit #6 173 | 174 | 175 | echo "******** git branch -avv :" 176 | git branch -avv 177 | 178 | # echo "******** cat .git/HEAD to show internal branch:" 179 | # The contents of HEAD is stored in this file: 180 | #cat .git/HEAD 181 | 182 | # exit #7 183 | 184 | echo "******** git show --oneline --abbrev-commit" 185 | # git show --oneline --abbrev-commit -l 1 186 | echo "******** cd into ${REPONAME} " 187 | cd ${REPONAME} 188 | pwd 189 | 190 | cat ${REPONAME}/bebe.md 191 | 192 | exit #8 193 | 194 | echo "******** tree of folders:" 195 | tree 196 | echo "******** git log --oneline:" 197 | git log --oneline 198 | echo "******** git reflog : baseline of git actions" 199 | git reflog 200 | 201 | # exit #9 202 | 203 | echo "******** git blame ${REPONAME}/bebe.md" 204 | git blame ${REPONAME}/bebe.md 205 | 206 | exit #10 207 | 208 | # echo "******** Begin trace :" 209 | # # Do not set trace on: 210 | # set -x # xtrace command echo on (with ++ prefix). http://www.faqs.org/docs/abs/HTML/options.html 211 | 212 | # echo "******** Define default branch :" 213 | # Change from default "ref: refs/heads/master" : 214 | # See http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html 215 | # DEFAULT_BRANCH="master" 216 | # git symbolic-ref HEAD refs/heads/$DEFAULT_BRANCH 217 | #cat .git/HEAD 218 | #git branch -avv 219 | 220 | echo "******** checkout new branch feature1 from master branch :" 221 | git checkout master 222 | git checkout -b feature1 223 | git branch -avv 224 | 225 | # exit #11 226 | 227 | 228 | echo "******** git checkout ea2db2c :" 229 | git checkout ea2db2c 230 | 231 | exit #5 232 | echo "******** git reset --soft ea2db2c (to remove it):" 233 | git reset --soft ea2db2c 234 | echo "******** git fsck:" 235 | git fsck 236 | echo "******** Make changes to files and stage it :" 237 | 238 | exit #5 239 | 240 | echo "change 1">>bebe.md 241 | git add bebe.md 242 | echo "******** git reset --mixed HEAD :" 243 | git reset HEAD 244 | echo "******** git reset --mixed HEAD :" 245 | git reset HEAD 246 | echo "******** git reset --hard a874ef2 :" 247 | git reset --hard a874ef2 248 | 249 | exit #6 250 | echo "******** $NOW end." 251 | -------------------------------------------------------------------------------- /git-stash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This is git-basics.sh from https://github.com/wilsonmar/git-utilities 3 | # Described in https://wilsonmar.github.io/git-basics 4 | # This script performs the most common actions resulting in the various statuses, 5 | # so you can make changes and see the effect. 6 | # Remember to chmod +x git-basics.sh first, then paste this command in your terminal 7 | # sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/git-utilities/master/git-basics.sh)" 8 | 9 | function fancy_echo() { 10 | local fmt="$1"; shift 11 | printf "\\n>>> $fmt\\n" "$@" 12 | } 13 | 14 | clear 15 | 16 | WORKING_FOLDER="$1" # from 1st argument 17 | if [[ -z "${WORKING_FOLDER// }" ]]; then #it's blank so assign default: 18 | WORKING_FOLDER="git-basics-working" 19 | fi 20 | cd ~/ 21 | rm -rf $WORKING_FOLDER 22 | mkdir $WORKING_FOLDER 23 | cd $WORKING_FOLDER 24 | fancy_echo "1. WORKING_FOLDER is $PWD:" 25 | 26 | fancy_echo "0. git init within $PWD:" 27 | git init # to initialized empty repository 28 | # Initialized empty Git repository in /Users/wilsonmar/git_repo/.git/ 29 | 30 | # Mute warnings on Windows machines: 31 | git config --global core.safecrlf false 32 | # No response is expected. 33 | 34 | fancy_echo "2. Add README.md and .gitignore to staging" 35 | echo "$ echo \"#git-basics.sh\" > README.md" 36 | echo "#git-basics.sh">README.md 37 | 38 | echo "$ echo \"amy\">.gitignore" 39 | echo "amy">.gitignore 40 | 41 | echo "$ git add ." 42 | git add . 43 | 44 | echo "$ git commit -m\"1st commit - $MSG\"" 45 | git commit -m"1st commit - $MSG" 46 | # [master (root-commit) 4ca8a19] 1st commit - 2. Add README.md and .gitignore to staging 47 | # 2 files changed, 2 insertions(+) 48 | # create mode 100644 .gitignore 49 | # create mode 100644 README.md 50 | echo ">>> NOTE: hash code 4ca8a19 and others are new with every run." 51 | 52 | MSG="3. I'm Amy. I get ignored." 53 | echo "$ echo \"$MSG\">amy" 54 | echo "$MSG">amy 55 | 56 | MSG="4. I'm Bob. I never go anywhere and stay untracked." 57 | echo "$ echo \"$MSG\">bob" 58 | echo "$MSG">bob 59 | 60 | MSG="5. I'm Chris. I visit the Index." 61 | echo "$ echo \"$MSG\">chris" 62 | echo "$MSG">chris 63 | 64 | echo "$ git add chris" 65 | git add chris 66 | echo ">>> git add does not issue a response message unless there is an error." 67 | 68 | MSG="6. I'm Don. I got committed once." 69 | echo "$ echo \"$MSG\">don" 70 | echo "$MSG">don 71 | 72 | echo "$ git add don" 73 | git add don 74 | 75 | echo "$ git commit -m\"2nd commit - $MSG\"" 76 | git commit -m"2nd commit - $MSG" 77 | # [master f6e6fb3] 2nd commit - 6. I'm Don. I got committed once. 78 | # 2 files changed, 2 insertions(+) 79 | # create mode 100644 chris 80 | # create mode 100644 don 81 | echo ">>> NOTE: chris and don got committed together." 82 | 83 | MSG="7. I'm Ed. But I'll soon be modified." 84 | echo "$ echo \"$MSG\">ed" 85 | echo "$MSG" >ed 86 | 87 | echo "$ git add ed" 88 | git add ed 89 | 90 | echo "$ git commit -m\"3rd commit - $MSG\"" 91 | git commit -m "3rd commit - $MSG" 92 | # [master 4e4bada] 3rd commit with 7. I'm Ed. But I'll soon escape by being edited. 93 | # 1 file changed, 1 insertion(+) 94 | # create mode 100644 ed 95 | echo "$ echo \"Now I'm outside.\" >>ed # concatenated." 96 | echo "Now I'm outside." >>ed # concatenated. 97 | 98 | fancy_echo "Add 2nd line to file ed. cat ed shows two lines:" 99 | echo "$ cat ed" 100 | cat ed 101 | echo ">>> End of file we're actively working on." 102 | 103 | MSG="8. I'm Finn. I got edited and added back, but not committed." 104 | echo -e "\n$ echo \"$MSG\" >finn" 105 | echo $MSG>finn 106 | 107 | echo "$ git add finn" 108 | git add finn 109 | 110 | echo "$ git commit -m\"4th commit - $MSG\"" 111 | git commit -m"4th commit - $MSG" 112 | # [master c21af48] 4th commit - 8. I'm Finn. I got edited and added back, but not committed. 113 | # 1 file changed, 1 insertion(+) 114 | # create mode 100644 finn 115 | 116 | echo "$ echo \"Now I'm outside.\" >>finn" 117 | echo ">>> git add finn" 118 | 119 | echo "$ git add finn" 120 | git add finn 121 | 122 | fancy_echo "cat finn shows two lines:" 123 | echo "$ cat finn" 124 | cat finn 125 | 126 | echo ">>> 9. finn and george are committed together as 2 files:" 127 | MSG="9a. I'm George. I'm a frequent traveler." 128 | echo "$ echo \"$MSG\">george" 129 | echo "$MSG">george 130 | echo "$ git add george" 131 | git add george 132 | 133 | echo "$ git commit -m\"5th commit - $MSG\"" 134 | git commit -m"5th commit - $MSG" 135 | 136 | echo "$ echo \"Now I'm outside.\" >>george\" # concatenate" 137 | echo "Now I'm outside." >>george 138 | 139 | echo "$ git add george" 140 | git add george 141 | 142 | MSG="9b. George is committed again." 143 | echo "$ git commit -m\"6th commit - $MSG\" " 144 | git commit -m"6th commit - $MSG" 145 | 146 | MSG="10. I'm Harry." 147 | echo "$ \"$MSG\">harry" 148 | echo "$MSG">harry 149 | echo ">>> (Harry will later be stashed and removed without entering commit.)" 150 | 151 | fancy_echo "11. ls -a # Listing files (using ls -a) in folder $WORKING_FOLDER :" 152 | ls -a 153 | # . .. .git .gitignore README.md amy bob chris don ed finn george harry 154 | fancy_echo "12. git status -s -b" 155 | git status -s -b 156 | # ## master 157 | # M ed 158 | # ?? bob 159 | # ?? harry 160 | echo ">>> NOTE: Ignored (amy) and Committed files (chris, don, ed, finn, george) don't appear on git status." 161 | echo ">>> PROTIP: The "M" nex to file ed means Modified and thus being tracked by Git." 162 | 163 | fancy_echo "13. git log --pretty=format:"%h %s %ad" --graph --since=10.days --date=relative " 164 | git log --pretty=format:"%h %s %ad" --graph --since=10.days --date=relative 165 | # * 9af0a6d 6th commit - 9b. George rises again. 0 seconds ago 166 | # * 473b096 5th commit - 9a. I'm George. My first commit. 0 seconds ago 167 | # * c21af48 4th commit - 8. I'm Finn. I got edited and added back, but not committed. 0 seconds ago 168 | # * 4e4bada 3rd commit - 7. I'm Ed. But I'll soon escape by being edited. 0 seconds ago 169 | # * f6e6fb3 2nd commit - 6. I'm Don. I got committed once. 0 seconds ago 170 | # * 4ca8a19 1st commit - 2. Add README.md and .gitignore to staging 0 seconds ago 171 | 172 | fancy_echo "14. git reflog # (of git actions) after initial commits:" 173 | git reflog 174 | # 9af0a6d (HEAD -> master) HEAD@{0}: commit: 6th commit - 9b. George rises again. 175 | # 473b096 HEAD@{1}: commit: 5th commit - 9a. I'm George. My first commit. 176 | # c21af48 HEAD@{2}: commit: 4th commit - 8. I'm Finn. I got edited and added back, but not committed. 177 | # 4e4bada HEAD@{3}: commit: 3rd commit - 7. I'm Ed. But I'll soon escape by being edited. 178 | # f6e6fb3 HEAD@{4}: commit: 2nd commit - 6. I'm Don. I got committed once. 179 | # 4ca8a19 HEAD@{5}: commit (initial): 1st commit - 2. Add README.md and .gitignore to staging 180 | 181 | fancy_echo "15. git checkout HEAD@{4} # attempt (at TIME TRAVEL):" 182 | git checkout HEAD@{4} 183 | # error: Your local changes to the following files would be overwritten by checkout: 184 | # ed 185 | # Please commit your changes or stash them before you switch branches. 186 | # Aborting 187 | 188 | fancy_echo "16. git stash save \"working on ed outside after adding Harry.\"" 189 | git stash save "working on ed outside after adding Harry." 190 | echo ">>> NOTE: Untracked files do not get stashed by default." 191 | 192 | fancy_echo "17. git stash list" 193 | git stash list 194 | 195 | fancy_echo "18. git stash show" 196 | git stash show 197 | 198 | fancy_echo "19. git status -s -b # after git stash and before going back in time:" 199 | git status -s -b 200 | echo ">>> NOTE: Untracked files still there on the sidelines." 201 | 202 | fancy_echo "20. git checkout HEAD@{4} # when Don was committed:" 203 | git checkout HEAD@{4} 204 | # Note: checking out 'HEAD@{4}'. 205 | # You are in 'detached HEAD' state. You can look around, make experimental 206 | # changes and commit them, and you can discard any commits you make in this 207 | # state without impacting any branches by performing another checkout. 208 | # HEAD is now at 744646a 3rd commit - 7. I'm Ed. But I'll soon be modified. 209 | 210 | fancy_echo "21. cat ed # contents: It doesn't contain 2nd line:" 211 | cat ed 212 | echo ">>> end of file." 213 | 214 | fancy_echo "22. ls -a # listing files after checkout:" 215 | ls -a 216 | # . .. .git .gitignore README.md amy bob chris don ed harry 217 | echo ">>> Notice finn and george are not included because they happen after the point of checkout." 218 | 219 | fancy_echo "23. git reflog -n 6 # after checkout HEAD@{4}:" 220 | git reflog -n 6 221 | # 4e4bada (HEAD) HEAD@{0}: checkout: moving from master to HEAD@{4} 222 | # 9af0a6d (master) HEAD@{1}: reset: moving to HEAD 223 | # 9af0a6d (master) HEAD@{2}: commit: 6th commit - 9b. George rises again. 224 | # 473b096 HEAD@{3}: commit: 5th commit - 9a. I'm George. My first commit. 225 | # c21af48 HEAD@{4}: commit: 4th commit - 8. I'm Finn. I got edited and added back, but not committed. 226 | # 4e4bada (HEAD) HEAD@{5}: commit: 3rd commit with 7. I'm Ed. But I'll soon escape by being edited. 227 | echo ">>> NOTE: finn, george are included in reflog because it lists all actions." 228 | 229 | fancy_echo "24. concatenate line to file don:" 230 | echo "$ echo \"Touched while away\" >>don " 231 | echo "Touched while away" >>don 232 | 233 | fancy_echo "25. git status -s -b # shows file done was modified:" 234 | git status -s -b 235 | 236 | fancy_echo "26. git checkout master # back to master:" 237 | git checkout master 238 | # M don 239 | # Previous HEAD position was 9c31cef 3rd commit - 7. I'm Ed. But I'll soon be modified. 240 | # Switched to branch 'master' 241 | 242 | fancy_echo "27. ls -a # Listing files shows the whole gang is back together (from amy to george)." 243 | ls -a 244 | 245 | fancy_echo "28. cat don " 246 | cat don 247 | echo ">>> Modification to don is carried forward." 248 | 249 | fancy_echo "29. git stash pop" 250 | git stash pop 251 | # Dropped refs/stash@{0} (6023f95782622e62ee219fac3076827ee1463e1c) 252 | 253 | fancy_echo "30. git status -s -b # after stack pop:" 254 | git status -s -b 255 | # ## master 256 | # M ed 257 | # ?? bob 258 | # ?? harry 259 | 260 | fancy_echo "31. cat ed # (display contents of) file ed:" 261 | cat ed 262 | echo ">>> NOTE: see the second line is back." 263 | 264 | fancy_echo "32. git stash list # after pop:" 265 | git stash list 266 | echo ">>> nothing returns if the list is empty." 267 | 268 | fancy_echo "33. git reflog -n 3 # after checkout master:" 269 | git reflog -n 3 270 | # 32fa405 (HEAD -> master) HEAD@{0}: checkout: moving from 2bebeecd4ca251429b958275805675d206501353 to master 271 | # 2bebeec HEAD@{1}: checkout: moving from master to HEAD@{4} 272 | # 32fa405 (HEAD -> master) HEAD@{2}: reset: moving to HEAD 273 | 274 | fancy_echo "34a. Some prefer an alternate to stash in checking out a branch:" 275 | echo "$ git checkout -b tmpbranch:" 276 | git checkout -b tmpbranch 277 | 278 | fancy_echo "34b. cat (display contents) of harry" 279 | cat harry 280 | echo ">>> end of file" 281 | 282 | fancy_echo "34c. git add & commit -m\"saving harry\" " 283 | git add harry 284 | git commit -m "saving harry" 285 | 286 | fancy_echo "34d. git status -s -b after saving harry:" 287 | git status -s -b 288 | # ## master 289 | # M ed 290 | # ?? bob 291 | # ?? harry 292 | 293 | fancy_echo "34f. git checkout master" 294 | git checkout master 295 | 296 | fancy_echo "34g. git branch -vv" 297 | git branch -vv 298 | 299 | fancy_echo "34h. ls -a # Listing files shows the whole gang is back together (from amy to george)." 300 | ls -a 301 | 302 | exit 303 | 304 | fancy_echo "36. New branch AddIngrid:" 305 | git checkout -b Add-Ingrid 306 | fancy_echo "Git reflog:" 307 | git reflog -n 5 308 | -------------------------------------------------------------------------------- /git-upload-new.ps1: -------------------------------------------------------------------------------- 1 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 2 | 3 | $SECRETS = Get-Content "$home/.secrets" | ConvertFrom-StringData 4 | $GITHUB_USER="wilsonmar" 5 | # $GITHUB_TOKEN="wilsonmar 6 | 7 | 8 | # $GITHUB_TOKEN is not defined before this point so code can test if 9 | # one needs to be created: 10 | If ("$GITHUB_TOKEN" -eq "") { 11 | echo "******** Creating Auth GITHUB_TOKEN to delete repo later : " 12 | # Based on http://douglastarr.com/using-powershell-3-invoke-restmethod-with-basic-authentication-and-json 13 | 14 | $secpasswd = ConvertTo-SecureString $GITHUB_USER -AsPlainText -Force 15 | $cred = New-Object System.Management.Automation.PSCredential ($SECRETS.GITHUB_PASSWORD, $secpasswd) 16 | # CAUTION: which sends passwords through the internet here. 17 | # You may instead manually obtain a token on GitHub.com. 18 | 19 | #$Body_JSON = '{"scopes":["delete_repo"],"note":"token with delete repo scope"}' 20 | $BODY_JSON = "{""scopes"":[""delete_repo""], ""note"":""token with delete repo scope""}" 21 | echo "Body_JSON=$Body_JSON" # DEBUGGING 22 | 23 | $response = Invoke-RestMethod -Method Post ` 24 | -Credential $cred ` 25 | -Body $Body_JSON ` 26 | -Uri "https://api.github.com/authorizations" 27 | $GITHUB_TOKEN = $response.Stuffs | where { $_.Name -eq "token" } 28 | # Do not display token secret! 29 | # API Token (32 character long string) is unique among all GitHub users. 30 | # Response: X-OAuth-Scopes: user, public_repo, repo, gist, delete_repo scope. 31 | # See https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization 32 | 33 | # WORKFLOW: Manually see API Tokens on GitHub | Account Settings | Administrative Information 34 | } Else { 35 | echo "******** Verifying Auth GITHUB_TOKEN to delete repo later : " 36 | 37 | $Headers = @{ 38 | Authorization = 'Basic ' + ${GITHUB_TOKEN} 39 | }; 40 | # -f is for substitution of (0). 41 | # See https://technet.microsoft.com/en-us/library/ee692795.aspx 42 | # Write-Host ("Headers="+$Headers.Authorization) 43 | 44 | $response = Invoke-RestMethod -Method Get ` 45 | -Headers $Headers ` 46 | -ContentType 'application/json' ` 47 | -Uri https://api.github.com 48 | 49 | # Expect HTTP 404 Not Found if valid to avoid disclosing valid data with 401 response as RFC 2617 defines. 50 | $GITHUB_AVAIL = $response.Stuffs | where { $_.Name -eq "authorizations_url" } 51 | echo "******** authorizations_url=$GITHUB_AVAIL.Substring(0,8)" # DEBUGGING 52 | } 53 | -------------------------------------------------------------------------------- /github_img_to_cloudinary.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # github_img_to_cloudinary.py at https://github.com/wilsonmar/git-utilities/master/github_img_to_cloudinary.py 4 | # Based on migrate_to_cloudinary.py at https://gist.github.com/akshay-ranganath/b5e2d9b0c29ddfe676bdf9cd3713cf12 5 | 6 | import cloudinary 7 | import cloudinary.uploader 8 | import cloudinary.api 9 | import cloudinary.utils 10 | import argparse 11 | import sys, os, glob, re 12 | import urllib.parse 13 | 14 | cloudinary.config( 15 | cloud_name = '<>', 16 | api_key = '<>', 17 | api_secret = '<>' 18 | ) 19 | 20 | 21 | def cli(): 22 | prog = "github_migration.py" 23 | if len(sys.argv) == 1: 24 | prog += " [command]" 25 | 26 | parser = argparse.ArgumentParser( 27 | description='CLI to migration Ghithub blog images to cloudinary', 28 | add_help=True, 29 | prog=prog) 30 | 31 | parser.add_argument( 32 | '--version', 33 | action='version', 34 | version='0.1') 35 | 36 | subparsers = parser.add_subparsers( 37 | title='Commands', dest="command", metavar="") 38 | 39 | actions = {} 40 | 41 | subparsers.add_parser( 42 | name="help", 43 | help="Show available help", 44 | add_help=False).add_argument( 45 | 'args', 46 | metavar="", 47 | nargs=argparse.REMAINDER) 48 | 49 | actions["identify"] = create_sub_command( 50 | subparsers, "identify", 51 | "Identifies all the images that will be migrated to Cloudinary", 52 | required_arguments=[{"name": "directory", "help": "Base directory for the github blog project"}], 53 | optional_arguments=[{"name": "display", "help": "Display all the image names with their file name"}] 54 | ) 55 | 56 | actions["swap"] = create_sub_command( 57 | subparsers, "swap", 58 | "Identifies all the images that will be migrated to Cloudinary", 59 | required_arguments=[{"name": "directory", "help": "Base directory for the github blog project"}], 60 | optional_arguments=[{"name": "display", "help":"Display all the image names with their file name"}] 61 | ) 62 | 63 | if len(sys.argv) <= 1: 64 | parser.print_help() 65 | return 0 66 | 67 | args = parser.parse_args() 68 | 69 | if args.command == "help": 70 | if len(args.args) > 0: 71 | if actions[args.args[0]]: 72 | actions[args.args[0]].print_help() 73 | else: 74 | parser.prog = get_prog_name() + " help [command]" 75 | parser.print_help() 76 | return 0 77 | 78 | return getattr(sys.modules[__name__], args.command.replace("-", "_"))(args) 79 | 80 | 81 | def create_sub_command( 82 | subparsers, 83 | name, 84 | help, 85 | optional_arguments=None, 86 | required_arguments=None): 87 | action = subparsers.add_parser(name=name, help=help, add_help=False) 88 | 89 | if required_arguments: 90 | required = action.add_argument_group("required arguments") 91 | for arg in required_arguments: 92 | name = arg["name"] 93 | del arg["name"] 94 | required.add_argument("--" + name, 95 | required=True, 96 | **arg, 97 | ) 98 | 99 | optional = action.add_argument_group("optional arguments") 100 | if optional_arguments: 101 | for arg in optional_arguments: 102 | name = arg["name"] 103 | del arg["name"] 104 | optional.add_argument("--" + name, 105 | required=False, 106 | **arg, 107 | ) 108 | return action 109 | 110 | 111 | def identify(args): 112 | markdown_files = get_posts(args.directory) 113 | 114 | image_details = {} 115 | for each_markdown_file in markdown_files: 116 | images = find_images_in_post(each_markdown_file) 117 | 118 | #print the details 119 | image_details[each_markdown_file] = images 120 | if args.display != None: 121 | print(each_markdown_file, images) 122 | 123 | #break 124 | 125 | 126 | return image_details 127 | 128 | 129 | def swap(args): 130 | markdown_files = get_posts(args.directory) 131 | for each_markdown_file in markdown_files: 132 | find_and_swap_images_in_post(args.directory, each_markdown_file) 133 | #break 134 | 135 | 136 | def find_and_swap_images_in_post(directory, markdown_file_name): 137 | with open(markdown_file_name, "r") as blog_post: 138 | print("Migrating file " + markdown_file_name + " ...",end='') 139 | temp_file_name = os.environ['TMPDIR'] + markdown_file_name.rsplit('/',maxsplit=1)[1] 140 | 141 | 142 | with open(temp_file_name, "w") as temp_file: 143 | for line in blog_post: 144 | stripped_line = line.strip() 145 | if stripped_line.startswith("![") and stripped_line.find('](') > -1: 146 | result = run_regex(line) 147 | 148 | if result[1] != None: 149 | alt_text = result[0] 150 | image = result[1] 151 | 152 | if image.startswith("http://") or image.startswith("https://"): 153 | upload_object = image 154 | else: 155 | upload_object = directory + image 156 | 157 | if os.path.isfile(upload_object) == True and upload_object.find('cloudinary.com')==-1: 158 | cloudinary_url = upload_to_cloudinary(upload_object,alt_text) 159 | line = "![{}]({})\n".format(result[0], cloudinary_url) 160 | 161 | temp_file.write(line) 162 | 163 | #finally move the updated file to old location 164 | os.rename(temp_file_name, markdown_file_name) 165 | print(" Completed!") 166 | 167 | 168 | def upload_to_cloudinary(object,alt_text): 169 | cloudinary_url = None 170 | resp = cloudinary.uploader.upload( 171 | object, 172 | public_id=urllib.parse.quote(alt_text.strip()), 173 | invlidate=True, 174 | folder="blog" 175 | ) 176 | if resp!=None and "secure_url" in resp: 177 | cloudinary_url = cleanup_url(resp["secure_url"]) 178 | return cloudinary_url 179 | 180 | url_pattern = re.compile("(.+)\/v[0-9]+\/(.+)") 181 | def cleanup_url(url): 182 | result = url_pattern.match(url) 183 | 184 | return result.group(1)+'/f_auto,q_auto/'+result.group(2) 185 | 186 | def find_images_in_post(markdown_file_name): 187 | images = [] 188 | with open(markdown_file_name,"r") as blog_post: 189 | for line in blog_post: 190 | line = line.strip() 191 | if line.startswith("![") and line.find('](') > -1: 192 | result = run_regex(line) 193 | if result[1]!=None : 194 | images.append(result[1]) 195 | 196 | return images 197 | 198 | pattern = re.compile('\!\[(.+)\]\((.+)\)') 199 | def run_regex(line): 200 | 201 | result = pattern.match(line) 202 | matches = [] 203 | alt_text = None 204 | location = None 205 | 206 | try: 207 | if result!= None: 208 | (alt_text, location) = result.groups() 209 | except IndexError: 210 | print("Something went wrong! " + result.group(2)) 211 | 212 | return ([alt_text, location]) 213 | 214 | 215 | 216 | def get_posts(directory): 217 | markdown_files = None 218 | 219 | if os.path.exists(directory): 220 | # todo: make sure the directory ends with a trailing '/' 221 | posts_folder = directory + "_posts" 222 | if os.path.exists(posts_folder): 223 | print("Now checking for posts: " + posts_folder) 224 | markdown_files = glob.glob(posts_folder + '/' + '*.md') 225 | else: 226 | print("Unable to find posts in the _posts folder!") 227 | 228 | else: 229 | print("Unable to find directory: " + directory) 230 | 231 | return markdown_files 232 | 233 | if __name__ == "__main__": 234 | cli() -------------------------------------------------------------------------------- /gitlab-on-pi3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This is from https://github.com/wilsonmar/git-utilities/gitlab-on-pie3.sh 3 | # by WilsonMar@gmail.com 4 | # Described in https://wilsonmar.github.io/gitlab-on-pie3.md 5 | 6 | # This script installs GitLab CE on a Raspberry Pi 3 (64-bit) Stretch version, 7 | # so you can store stuff for less than $50 (less than a year of GitHub subscription) 8 | # sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/git-utilities/master/gitlab-on-pi3.sh)" 9 | 10 | # https://about.gitlab.com/installation/#raspberry-pi-2 11 | # https://x-team.com/blog/alternatives-to-github-including-github/ 12 | # https://hackernoon.com/create-your-own-git-server-using-raspberry-pi-and-gitlab-f64475901a66 13 | # https://howtoraspberrypi.com/private-git-raspberry-gitlab/ 9 March 2018 14 | # https://github.com/scaleway/image-builder 15 | # use the Docker's building system and convert it at the end to a disk image that will boot on real servers without Docker. 16 | 17 | # https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md 18 | 19 | #Raspbian armhf AFAIK is not binary compatible with debian armhf, unless omnibus packages ship all binary stuff (e.g. therubyracer) statically linked (or only depend on binary stuff present in jessie repository). 20 | # Raspbian armhf == armv6zk -mfpu=vfpv2 21 | # Debian armhf == armv7l -mfpu=vfpv3 22 | 23 | echo "1.1 install and configure the necessary dependencies." 24 | sudo apt-get install -y curl openssh-server ca-certificates apt-transport-https 25 | 26 | echo "1.2 install postfix. To send emails from your GitLab server select ‘Internet Site’ during setup." 27 | sudo apt-get install -y postfix 28 | # TODO: Manually set SMTP to local - See https://pimylifeup.com/raspberry-pi-gitlab/ 29 | 30 | echo "1.3 add GPG keys to update GitLab server." 31 | curl https://packages.gitlab.com/gpg.key | sudo apt-key add - 32 | 33 | echo "2. Install Gitlab CE" 34 | sudo curl -sS https://packages.gitlab.com/install/repositories/gitlab/raspberry-pi2/script.deb.sh | sudo bash 35 | sudo apt-get install gitlab-ce 36 | 37 | echo "cat /etc/gitlab/gitlab.rb" 38 | sudo nano /etc/gitlab/gitlab.rb 39 | # external_url 'http://localhost:9999' 40 | # nginx['listen_port'] = 9999 41 | # nginx['listen_https'] = false 42 | # unicorn['port'] = 7777 43 | # QUESTION: What's the unicorn port for? 44 | read -rsp $'Press any key after deleting ...\n' -n 1 key 45 | 46 | echo "3. Start gitlab-ctl" 47 | sudo gitlab-ctl reconfigure 48 | 49 | echo "4.1 Get the IP of your raspberry pi using ifconfig command." 50 | ifconfig 51 | 52 | echo "4.2 On your first visit, you’ll be redirected to a password reset screen" 53 | 54 | echo "5. Log in with your username (root by default) and the password you set in the previous step." 55 | # You will have the home page of your GitLab server, where all your future projects will be listed." 56 | 57 | echo "6. Start all GitLab components" 58 | sudo gitlab-ctl start 59 | 60 | echo "6.1 Restart all GitLab components" 61 | sudo gitlab-ctl restart 62 | 63 | echo "6.2 Stop all GitLab components" 64 | sudo gitlab-ctl stop 65 | 66 | echo "6.3 Tail GitLab logs" 67 | sudo gitlab-ctl tail 68 | 69 | # https://stackoverflow.com/questions/849308/pull-push-from-multiple-remote-locations -------------------------------------------------------------------------------- /gup.sh: -------------------------------------------------------------------------------- 1 | # gup.sh 2 | # git update shell script, using push and pop of directories. 3 | 4 | pushd 5 | cd ~/gits/wilsonmar/futures 6 | git add . 7 | git commit -m"update via upg.sh" 8 | git push 9 | popd 10 | -------------------------------------------------------------------------------- /hooks/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # post-checkout hook 3 | import argparse 4 | def parse_args(): 5 | pass 6 | def main(args=None): 7 | print("Hello from commit-msg.") 8 | pass 9 | if __name__ == "__main__": 10 | args = parse_args() 11 | main(args) 12 | # exit 0 13 | -------------------------------------------------------------------------------- /hooks/post-checkout: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # post-checkout from git-lfs. 3 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-checkout.\n"; exit 2; } 4 | git lfs post-checkout "$@" -------------------------------------------------------------------------------- /hooks/post-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Hello from post-commit." 3 | # From git-lfs: 4 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-commit.\n"; exit 2; } 5 | git lfs post-commit "$@" 6 | -------------------------------------------------------------------------------- /hooks/post-merge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # post-merge from git-lfs: 3 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-merge.\n"; exit 2; } 4 | git lfs post-merge "$@" -------------------------------------------------------------------------------- /hooks/pre-commit.dateverif.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # pre-commit file 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # To stop the commit, exit with non-zero status after issuing an appropriate message. 6 | 7 | if [ -z "$GIT_AUTHOR_DATE" ]; then # it's blank (testing standalone): 8 | GIT_AUTHOR_DATE="@1522308872 -0600" # provide sample input 9 | GIT_AUTHOR_NAME="Wilson Mar" 10 | GIT_AUTHOR_EMAIL="WilsonMar@gmail.com" 11 | fi 12 | #echo "GIT_AUTHOR_DATE=$GIT_AUTHOR_DATE" 13 | GIT_AUTHOR_YMD=${GIT_AUTHOR_DATE#"@"} # # refers to the beginning char to strip. 14 | GIT_AUTHOR_YMD=${GIT_AUTHOR_YMD%' '*} # strips chars from end of string after the space. 15 | GIT_AUTHOR_YMD=$(date -r "$GIT_AUTHOR_YMD" '+%Y-%m-%dT%H:%M:%S') # ISO 8601 format 16 | time=${GIT_AUTHOR_DATE:(-5)} # extracts last 5 chars from end of string. 17 | GIT_AUTHOR_TZ=${time:0:3}:${time:3:2} 18 | echo "pre-commit $GIT_AUTHOR_YMD$GIT_AUTHOR_TZ for $GIT_AUTHOR_NAME of $GIT_AUTHOR_EMAIL" 19 | exit 0 # 1 is error. 20 | -------------------------------------------------------------------------------- /hooks/pre-commit.shellcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # based on https://gist.github.com/nilsding/b6105a8949955ce81f82dabc37650640 3 | 4 | # Print a message 5 | # 6 | # Params: 7 | # $1: colour (red | green | yellow) 8 | # $*: status to print 9 | # 10 | # Example usage: 11 | # print_msg green "Successfully built $something" 12 | # 13 | # print_msg red "An error occurred:" $msg 14 | print_msg() { 15 | color="1" 16 | case $1 in 17 | red) color="31;1" ;; 18 | green) color="32;1" ;; 19 | yellow) color="33;1" ;; 20 | esac 21 | shift 22 | # shellcheck disable=SC1117 23 | printf " \033[${color}m*\033[0;1m %s\033[0m\n" "$*" 24 | } 25 | 26 | # Require an application to be in $PATH. 27 | # 28 | # Params: 29 | # $1: app name 30 | # 31 | # Example usage: 32 | # require_app ruby 33 | require_app() { 34 | if ! command -v "$1" > /dev/null; then 35 | print_msg red "$1 not found, please install it" 36 | return 1 37 | fi 38 | } 39 | 40 | ############################################################################### 41 | 42 | require_app shellcheck || exit 0 43 | 44 | changed_shell_files=$( 45 | git diff --cached --name-only --diff-filter=ACM | 46 | xargs grep -lE '^#!/.*(sh|bash|ksh)' 47 | ) 48 | 49 | print_msg yellow "Running shellcheck..." 50 | # shellcheck disable=SC2086 51 | if shellcheck -a $changed_shell_files; then 52 | print_msg green "shellcheck approved your shell scripts, nice" 53 | else 54 | print_msg red "shellcheck disapproves of your changes (return code: $?), "\ 55 | "fix the errors and come back later" 56 | exit 1 57 | fi 58 | -------------------------------------------------------------------------------- /hooks/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # pre-push from git-lfs. 3 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n"; exit 2; } 4 | git lfs pre-push "$@" 5 | -------------------------------------------------------------------------------- /hooks/prepare-commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # prepare-commit-msg 3 | 4 | COMMIT_MSG_FILE=$1 # ".git/COMMIT_EDITMSG" 5 | #COMMIT_SOURCE=$2 # "message" 6 | #SHA1=$3 # ? 7 | echo "prepare-commit-msg: $(cat $COMMIT_MSG_FILE)" 8 | echo " branch=$(git rev-parse --abbrev-ref HEAD) in $(basename $(git rev-parse --show-toplevel))" 9 | # SHA1=$SHA1" 10 | exit 0 # OK -------------------------------------------------------------------------------- /mac-prompt.bash: -------------------------------------------------------------------------------- 1 | # mac-prompt.bash in https://github.com/wilsonmar/git-utilities 2 | # For concatenating/pasting into ~/.bash_profile 3 | 4 | function gd() { # get dirty 5 | [[ $(git status 2> /dev/null | tail -n1) != *"working directory clean"* ]] && echo "*" 6 | } 7 | function parse_git_branch() { 8 | git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1$(gd)/" 9 | } 10 | #function parse_git_branch() { 11 | # git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/' 12 | #} 13 | export PS1="\n \w\[\033[33m\] \$(parse_git_branch)\[\033[00m\]\n$ " 14 | -------------------------------------------------------------------------------- /my_github_accts.csv: -------------------------------------------------------------------------------- 1 | _folder, _Name, _acct, _email, _note 2 | gmail_acct, John Doe, johndoe, johndoe@gmail.com, Personal GitHub account created using personal Gmail or other email 3 | client1_acct, John Doe, john-doe, john_doe@mck.com, Customer/client organization account 4 | job1_acct, John Doe, john-doe, john_doe@mck.com, Employer organization account 5 | vendor1_acct, John Doe, johndoe1, john-doe@soft.ai, vendor organization account 6 | -------------------------------------------------------------------------------- /my_github_accts_vars.sh: -------------------------------------------------------------------------------- 1 | # my_github_accts_vars.sh 2 | 3 | # This bash script reads flat file my_github_accts.csv to crate bash commands: 4 | # export LOCAL_SSH_KEYFILE="gmail_acct" 5 | # export MY_EMAIL_ADDRESS="johndoe@gmail.com" 6 | # export MY_GITHUB_ACCTNAME="johndoe" 7 | # export MY_FULL_NAME="John Doe" 8 | -------------------------------------------------------------------------------- /my_ps_functions.ps1: -------------------------------------------------------------------------------- 1 | # my_ps_functions.ps1 within https://github.com/wilsonmar/git-utilities 2 | # PowerShell functions custom library to workaround dificiencies. 3 | # for running under PowerShell on Mac or Windows 4 | # by wilsonmar@gmail.com @wilsonmar 5 | # Here are various custom functions 6 | # Sample invocation code: 7 | # & ((Split-Path $MyInvocation.InvocationName) + "\my_ps_functions.ps1") 8 | 9 | # From orad in http://stackoverflow.com/questions/31888580/a-better-way-to-check-if-a-path-exists-or-not-in-powershell 10 | # https://connect.microsoft.com/PowerShell/feedbackdetail/view/1643846/ 11 | # Add aliases that should be made available in PowerShell by default: 12 | function not-exist { -not (Test-Path $args) } 13 | Set-Alias !exist not-exist -Option "Constant, AllScope" 14 | Set-Alias exist Test-Path -Option "Constant, AllScope" 15 | 16 | # Use this in conditional statements such as: 17 | # if (exist $path) { ... } 18 | # and 19 | # if (not-exist $path)) { ... } 20 | # if (!exist $path)) { ... } 21 | 22 | function Get-MacOsXsysteminformation { 23 | [xml]$infos = system_profiler -xml 24 | 25 | return $infos 26 | } -------------------------------------------------------------------------------- /node-test1/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /node-test1/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "latedef": false, 5 | "evil": true, 6 | "noarg": true, 7 | "undef": true, 8 | "eqnull": true, 9 | "node": true 10 | } 11 | -------------------------------------------------------------------------------- /node-test1/README.md: -------------------------------------------------------------------------------- 1 | This provides a simple sample NodeJs application 2 | that makes use of the Husky library that 3 | Node.Js apps can use to setup Git to setup a 4 | hook to run JSHint library that validates JavaScript code. 5 | 6 | 7 | ## Prepare 8 | 9 | 0. cd to a folder to hold the folder to hold the folder 10 | created when git clone is run: 11 | 12 | git_hook_node_jshint 13 | 14 | 0. Open a Terminal shell window and cd to the folder, then run: 15 | 16 | ``` 17 | npm install 18 | ``` 19 | 20 | This creates an **npm_modules** folder and populates 21 | it with dependencies from the internet. 22 | 23 |
 24 | > husky@0.7.0 install /Users/mac/gits/wilsonmar/devops/node-sample1/node_modules/husky
 25 | > node ./bin/install.js
 26 |  
 27 | husky
 28 |   setting up hooks in .git/hooks/
 29 |   done
 30 |  
 31 | Prehooks@1.0.0 /Users/mac/gits/wilsonmar/devops/node-sample1
 32 | ├── husky@0.7.0
 33 | └─┬ jshint@2.9.4
 34 |   ├─┬ cli@1.0.1
 35 |   │ └─┬ glob@7.1.1
 36 |   │   ├── fs.realpath@1.0.0
 37 |   │   ├─┬ inflight@1.0.6
 38 |   │   │ └── wrappy@1.0.2
 39 |   │   ├── inherits@2.0.3
 40 |   │   ├── once@1.4.0
 41 |   │   └── path-is-absolute@1.0.1
 42 |   ├─┬ console-browserify@1.1.0
 43 |   │ └── date-now@0.1.4
 44 |   ├── exit@0.1.2
 45 |   ├─┬ htmlparser2@3.8.3
 46 |   │ ├── domelementtype@1.3.0
 47 |   │ ├── domhandler@2.3.0
 48 |   │ ├─┬ domutils@1.5.1
 49 |   │ │ └─┬ dom-serializer@0.1.0
 50 |   │ │   ├── domelementtype@1.1.3
 51 |   │ │   └── entities@1.1.1
 52 |   │ ├── entities@1.0.0
 53 |   │ └─┬ readable-stream@1.1.14
 54 |   │   ├── core-util-is@1.0.2
 55 |   │   ├── isarray@0.0.1
 56 |   │   └── string_decoder@0.10.31
 57 |   ├── lodash@3.7.0
 58 |   ├─┬ minimatch@3.0.3
 59 |   │ └─┬ brace-expansion@1.1.6
 60 |   │   ├── balanced-match@0.4.2
 61 |   │   └── concat-map@0.0.1
 62 |   ├── shelljs@0.3.0
 63 |   └── strip-json-comments@1.0.4
 64 |  
 65 | npm WARN Prehooks@1.0.0 No repository field.
 66 |    
67 | 68 | The **.gitignore** file defined for the project 69 | specifies that the folder is not uploaded back to GitHub. 70 | This is also the case for the npm-debug.log created in case there is an error. 71 | 72 | 73 | ## Run the app 74 | 75 | Invoke the Node.Js app 76 | 77 | ``` 78 | node index.js 79 | ``` 80 | 81 | The expected response is a new Terminal line. 82 | 83 | 84 | ## Git hooks 85 | 86 | The package.json file defines what Node does before Git actions. 87 | 88 | ### precommit 89 | 90 | If this is in the package.json file: 91 | 92 | ``` 93 | "scripts": { 94 | "precommit": "jshint index.js" 95 | }, 96 | ``` 97 | 98 | jshint is invoked on index.js on `git commit` based on settings in file **.jshintrc**. 99 | The file in the repo, these errors to appear based on the index.js in the repo: 100 | 101 |
102 | index.js: line 3, col 15, Expected '===' and instead saw '=='.
103 | index.js: line 4, col 40, Missing semicolon.
104 | index.js: line 8, col 9, Expected '{' and instead saw 'doSomething'.
105 | index.js: line 8, col 22, Missing semicolon.
106 | index.js: line 11, col 35, Missing semicolon.
107 | index.js: line 14, col 2, Missing semicolon.
108 | index.js: line 3, col 9, 'num' is not defined.
109 | index.js: line 7, col 12, 'num' is not defined.
110 |  
111 | 8 errors
112 |  
113 | husky - pre-commit hook failed (add --no-verify to bypass)
114 |    
115 | 116 | 117 | Options specified are according to 118 | 119 | http://jshint.com/docs/options 120 | 121 | 122 | 123 | ### override 124 | 125 | To commit without performing verification, use this command: 126 | 127 | ``` 128 | git commit -m"update index.js" --no-verify 129 | ``` 130 | 131 | ### Fix 132 | 133 | PROTIP: After you insert lines, save the file 134 | and get new line numbers in the error messages by running again. 135 | 136 | 137 | ### prepush 138 | 139 | If this is in the package.json file: 140 | 141 | ``` 142 | "scripts": { 143 | "prepush": "jshint index.js" 144 | }, 145 | ``` 146 | 147 | jshint is invoked on index.js on `git push`. 148 | 149 | To push without performing verification, 150 | change the package.json file to: 151 | 152 | ``` 153 | git push --no-verify 154 | ``` 155 | 156 | ## Video 157 | 158 | A video of this is at 159 | 160 | https://www.youtube.com/watch?v=sTnatBgmYsE 161 | and blog
162 | http://www.penta-code.com/prevent-bad-git-commits-and-pushes-with-husky/ 163 | -------------------------------------------------------------------------------- /node-test1/index-error.js: -------------------------------------------------------------------------------- 1 | var myFunction = function() { 2 | 3 | if (num == 10) { 4 | console.log('The number is 10') 5 | } 6 | 7 | while (num !== 10) 8 | doSomething() 9 | 10 | function doSomething() { 11 | console.log('hello world') 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /node-test1/index-valid.js: -------------------------------------------------------------------------------- 1 | var myFunction = function() { 2 | var num; 3 | 4 | if (num === 10) { 5 | console.log('The number is 10'); 6 | } 7 | 8 | while (num !== 10){ 9 | doSomething(); 10 | } 11 | 12 | function doSomething() { 13 | console.log('hello world'); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /node-test1/index.js: -------------------------------------------------------------------------------- 1 | var myFunction = function() { 2 | 3 | if (num == 10) { 4 | console.log('The number is 10') 5 | } 6 | 7 | while (num !== 10) 8 | doSomething() 9 | 10 | function doSomething() { 11 | console.log('hello world') 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /node-test1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Prehooks", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "precommit": "jshint index.js", 8 | "prepush": "jshint index.js" 9 | }, 10 | "devDependencies": { 11 | "husky": "0.7.0", 12 | "jshint": "^2.8.0" 13 | }, 14 | "author": "PentaCode", 15 | "license": "ISC" 16 | } 17 | -------------------------------------------------------------------------------- /ps-auto-log.ps1: -------------------------------------------------------------------------------- 1 | # ps-auto-log.ps1 2 | # by wilsonmar@gmail.com 3 | # Based on http://mctexpert.blogspot.com/2012/10/automatically-create-log-of-your.html 4 | # To run on Mac: 5 | # chmod +x ps-auto-log.ps1 6 | # ./ps-auto-log.ps1 7 | # 8 | # Create a filename based on a ISO 8601 time stamp: 9 | $Filename = ` 10 | ((Get-date).Year).ToString()+"-"+` 11 | ((Get-date).Month).ToString("00")+"-"+` 12 | ((Get-date).Day).ToString("00")+"T"+` 13 | ((Get-date).Hour).ToString("00")+"-"+` 14 | ((Get-date).Minute).ToString("00")+"-"+` 15 | ((Get-date).Second).ToString("00")+"-local.txt" 16 | # 12-9-2016-8-39-6.txt TODO: Add timezone. 17 | # echo $Filename 18 | 19 | # Set the storage path to a folder in $HOME/Documents: 20 | if( "$IsWindows" -eq $True ) { 21 | $Path = "C:\Users\$USER\Documents\PowerShell\Transcript" 22 | }else{ # Mac / Linux: 23 | $Path = "~/Documents/PowerShell/Transcript" 24 | } 25 | 26 | # Turn on PowerShell transcripting: 27 | Start-Transcript -Path "$Path\$Filename" 28 | # Sample output from command: 29 | # Transcript started, output file is ~/Documents/PowerShell/Transcript\2016-12-09T08-48-45-local.txt -------------------------------------------------------------------------------- /secrets.sh: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # secrets.sh in https://github.com/wilsonmar/mac-install-all 3 | # referenced by macos-install-all.sh in the same repo. 4 | # This file name secrets.sh should be specified in .gitignore so 5 | # it doesn't upload to a public GitHub/GitLab/BitBucket/etc. 6 | # Run command source secrets.sh pulls these variables in: 7 | # CAUTION: No spaces around = sign. 8 | GIT_NAME="Wilson Mar" 9 | GIT_ID="WilsonMar@gmail.com" 10 | GIT_EMAIL="WilsonMar+GitHub@gmail.com" 11 | GIT_USERNAME="hotwilson" 12 | GPG_PASSPHRASE="only you know this 2 well" 13 | GITS_PATH="~/gits" 14 | GITHUB_ACCOUNT="hotwilson" 15 | GITHUB_PASSWORD="change this to your GitHub account password" 16 | GITHUB_REPO="sample" 17 | 18 | # Lists can be specified below. The last one in a list is the Git default: 19 | MAC_TOOLS="" 20 | # mas, ansible, 1password, powershell, kindle, vmware-fusion? 21 | GIT_CLIENT="" 22 | # git, cola, github, gitkraken, smartgit, sourcetree, tower, magit, gitup 23 | GIT_EDITOR="" 24 | # atom, code, eclipse, emacs, intellij, macvim, nano, pico, sts, sublime, textmate, textedit, vim 25 | # NOTE: pico, nano, and vim are built into MacOS, so no install. 26 | # NOTE: textwrangler is a Mac app manually installed from the Apple Store. 27 | GIT_BROWSER="" 28 | # chrome, firefox, brave, phantomjs, NOT: Safari 29 | # others (flash-player, adobe-acrobat-reader, adobe-air, silverlight) 30 | GIT_TOOLS="" 31 | # none, hooks, tig, lfs, diff-so-fancy, grip, p4merge, git-flow, signing, hub 32 | GIT_LANG="python" 33 | # python, python3, java, node, go 34 | JAVA_TOOLS="" 35 | # maven, gradle, TestNG, cucumber, gcviewer, jmeter, jprofiler # REST-Assured, Spock 36 | # (Via maven, ant, or gradle: junit4, junit5, yarn, dbunit, mockito) 37 | PYTHON_TOOLS="" 38 | # virtualenv, anaconda, jupyter, ipython, numpy, scipy, matplotlib, pytest, robot 39 | # robotframework, others 40 | # See http://www.southampton.ac.uk/~fangohr/blog/installation-of-python-spyder-numpy-sympy-scipy-pytest-matplotlib-via-anaconda.html 41 | NODE_TOOLS="" 42 | # bower, gulp, gulp-cli, npm-check, jscs, less, jshint, eslint, webpack, 43 | # mocha, chai, protractor, 44 | # browserify, express, hapi, angular, react, redux 45 | # graphicmagick, aws-sdk, mongodb, redis, others 46 | DATA_TOOLS="" 47 | # mariadb, postgresql, mongodb 48 | # others (dbunit?, mysql?, evernote?) 49 | # others (google-drive-file-stream, dropbox, box, amazon-drive ) 50 | MONGODB_DATA_PATH="/usr/local/var/mongodb" # default. 51 | TEST_TOOLS="" 52 | # selenium, sikulix, golum, dbunit? 53 | # Drivers for scripting language depend on what is defined in $GIT_LANG. 54 | CLOUD="" 55 | # icloud, aws, gcp, azure, cf, heroku, docker, vagrant, 56 | # terraform, serverless, 57 | # NOT: openstack 58 | AWS_ACCOUNT="" 59 | AWS_ACCESS_KEY_ID="" 60 | AWS_SECRET_ACCESS_KEY="" 61 | AWS_REGION="us-west-1" 62 | 63 | AZ_PRINCIPAL="" 64 | AZ_USER="" 65 | AZ_PASSWORD="" 66 | AZ_TENANT="" 67 | AZ_REGION="" 68 | 69 | GCP_PROJECT="" 70 | GCP_USER="" 71 | GCP_KEY="" 72 | GCP_REGION="" 73 | 74 | SAUCE_USERNAME="" 75 | SAUCE_ACCESS_KEY="" 76 | COLAB_TOOLS="" 77 | # google-hangouts, hipchat, joinme, keybase, microsoft-lync, skype, slack, teamviewer, whatsapp, sococo, zoom 78 | # NO gotomeeting (32-bit) 79 | MEDIA_TOOLS="" 80 | # others (audacity?, snagit?, camtasia?) 81 | VIZ_TOOLS="" 82 | # grafana, 83 | LOCALHOSTS="" 84 | # minikube, nginx, tomcat, jenkins, grafana, 85 | MINIKUBE_PORT="8083" # from default 8080 86 | NGINX_PORT="8086" # from default 8080 87 | TOMCAT_PORT="8087" # from default 8080 88 | JENKINS_PORT="8088" # from default 8080 89 | GRAFANA_PORT="8089" # from default 8080 90 | TRYOUT="all" # smoke tests. 91 | # all, HelloJUnit5, TODO: `virtuaenv, phantomjs, docker, hooks, jmeter, minikube, cleanup, editor 92 | TRYOUT_KEEP="jenkins" 93 | 94 | # To upgrade, add parameter in the command line: 95 | # ./mac-git-install.sh upgrade 96 | -------------------------------------------------------------------------------- /sonar1.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # sonar.sh From https://github.com/wilsonmar/git-utilities 3 | 4 | chmod 555 sonar-scanner 5 | ./sonar-scanner \ 6 | -Dsonar.projectKey=sonarqube-1-vm \ 7 | -Dsonar.sources=/Users/wilsonmar/gits/ng/angular4-docker-example \ 8 | -Dsonar.host.url=http://23.236.48.147 \ 9 | -Dsonar.login=7a51cb71a48ea3d16f57fe66021867fc2a98771e -------------------------------------------------------------------------------- /temp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # temp.py 3 | 4 | import pytz, time 5 | from datetime import datetime, tzinfo, timedelta 6 | from random import randint 7 | 8 | def iso8601_utc(): 9 | class simple_utc(tzinfo): 10 | def tzname(self,**kwargs): 11 | return "UTC" 12 | def utcoffset(self, dt): 13 | return timedelta(0) 14 | return datetime.utcnow().replace(tzinfo=simple_utc()).isoformat() 15 | #print(iso8601_utc()+" = ISO8601 time at +00:00 UTC (Zulu time), with microseconds") 16 | 17 | def iso8601_local(): 18 | class local_tz(tzinfo): 19 | def utcoffset(self, dt): 20 | ts = time.time() 21 | offset_in_seconds = (datetime.fromtimestamp(ts) - datetime.utcfromtimestamp(ts)).total_seconds() 22 | return timedelta(seconds=offset_in_seconds) 23 | return datetime.now().replace(microsecond=randint(0, 999999)).replace(tzinfo=local_tz()).isoformat() 24 | # print(iso8601_local()+" = ISO8601 time at local time zone offset, with random microseconds") 25 | 26 | print(iso8601_utc()+" = ISO8601 time at +00:00 UTC (Zulu time), with microseconds") 27 | print(iso8601_local()+" = ISO8601 time at local time zone offset, with random microseconds") 28 | 29 | 30 | 31 | #tz = pytz.timezone('America/Los_Angeles') 32 | #print(datetime.fromtimestamp(1463288494, tz).isoformat()) 33 | 34 | #2016-05-14T22:01:34-07:00 35 | 36 | #import sys 37 | #import argparse # https://docs.python.org/2/howto/argparse.html 38 | #import time # tzinfo, timedelta 39 | 40 | #utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone 41 | #datetime.datetime.now().replace(tzinfo=datetime.timezone(offset=utc_offset_sec)).isoformat() 42 | 43 | #class TZ(tzinfo): 44 | # def utcoffset(self, dt): return timedelta(minutes=-399) 45 | #datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ') 46 | 47 | #print('jenkins_secret_chrome.py' +utc_offset_sec+ '.png') 48 | -------------------------------------------------------------------------------- /tests/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wilsonmar/git-utilities/21f7b904833a57289bab6ee144e5ec7185361144/tests/.DS_Store -------------------------------------------------------------------------------- /tests/HelloWorld.scala: -------------------------------------------------------------------------------- 1 | object HelloWorld extends App { println("Hello, Scala World!") } 2 | -------------------------------------------------------------------------------- /tests/chrome-google-search-quit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # chrome-google-search-quit.py 3 | # from https://sites.google.com/a/chromium.org/chromedriver/getting-started 4 | import time 5 | from selenium import webdriver 6 | 7 | driver = webdriver.Chrome() 8 | driver.get('http://www.google.com/xhtml'); 9 | time.sleep(5) # Let the user actually see something! 10 | search_box = driver.find_element_by_name('q') 11 | search_box.send_keys('ChromeDriver') 12 | search_box.submit() 13 | time.sleep(5) # Let the user actually see something! 14 | driver.quit() -------------------------------------------------------------------------------- /tests/chrome-headless.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # chrome_yun.py 3 | # From https://github.com/pyzzled/selenium/tree/master/headless_browser explained at 4 | # https://medium.com/@pyzzled/running-headless-chrome-with-selenium-in-python-3f42d1f5ff1d 5 | 6 | from selenium import webdriver 7 | from selenium.webdriver.chrome.options import Options 8 | import os 9 | 10 | # instantiate a chrome options object so you can set the size and headless preference 11 | chrome_options = Options() 12 | chrome_options.add_argument("--headless") 13 | chrome_options.add_argument("--window-size=1920x1080") 14 | 15 | # download the chrome driver from https://sites.google.com/a/chromium.org/chromedriver/downloads and put it in the 16 | # current directory 17 | chrome_driver = os.getcwd() +"\\chromedriver.exe" 18 | 19 | ### Launch: 20 | 21 | # go to Google and click the I'm Feeling Lucky button 22 | driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=chrome_driver) 23 | driver.get("https://www.google.com") 24 | lucky_button = driver.find_element_by_css_selector("[name=btnI]") 25 | lucky_button.click() 26 | 27 | # capture the screen 28 | driver.get_screenshot_as_file("capture.png") 29 | 30 | # You should now have a screenshot of the I’m Feeling Lucky page in your project folder! 31 | 32 | -------------------------------------------------------------------------------- /tests/chrome_github_login.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # chrome_pycon_search.py 3 | # from http://selenium-python.readthedocs.io/getting-started.html#selenium-remote-webdriver 4 | from selenium import webdriver 5 | from selenium.webdriver.common.keys import Keys 6 | 7 | #driver = webdriver.Chrome() 8 | driver = webdriver.Firefox() 9 | 10 | driver.get("https://github.com") 11 | assert "The world" in driver.title 12 | #elem = driver.find_element_by_name("q") 13 | elem = driver.find_elements_by_css_selector('header div.HeaderMenu div.HeaderNavlink a') 14 | print(elem) # [ div.position-relative.js-header-wrapper > header > div > div.HeaderMenu.HeaderMenu--bright.d-lg-flex.flex-justify-between.flex-auto > div > span > div > a:nth-child(1) 16 | # XPath: /html/body/div[1]/header/div/div[2]/div/span/div/a[1] 17 | # Sign in 18 | elem[0].click() 19 | #elem.send_keys("pycon") 20 | #elem.send_keys(Keys.RETURN) 21 | assert "No results found." not in driver.page_source 22 | #driver.close() 23 | -------------------------------------------------------------------------------- /tests/chrome_pycon_search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # chrome_pycon_search.py 3 | # from http://selenium-python.readthedocs.io/getting-started.html#selenium-remote-webdriver 4 | from selenium import webdriver 5 | from selenium.webdriver.common.keys import Keys 6 | 7 | driver = webdriver.Chrome() 8 | 9 | #driver.get("http://www.python.org") 10 | driver.get("https://github.com") 11 | assert "Python" in driver.title 12 | elem = driver.find_element_by_name("q") 13 | elem.clear() 14 | elem.send_keys("pycon") 15 | elem.send_keys(Keys.RETURN) 16 | assert "No results found." not in driver.page_source 17 | #driver.close() 18 | -------------------------------------------------------------------------------- /tests/firefox-google-search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # from http://www.techbeamers.com/selenium-webdriver-python-tutorial/ 3 | 4 | from selenium import webdriver 5 | from selenium.webdriver.common.keys import Keys 6 | 7 | # create a new Firefox session 8 | driver = webdriver.Firefox() 9 | driver.implicitly_wait(30) 10 | driver.maximize_window() 11 | 12 | # navigate to the application home page 13 | driver.get("http://www.google.com") 14 | 15 | # get the search textbox 16 | search_field = driver.find_element_by_id("lst-ib") 17 | search_field.clear() 18 | 19 | # enter search keyword and submit 20 | search_field.send_keys("Selenium WebDriver Interview questions") 21 | search_field.submit() 22 | 23 | # get the list of elements which are displayed after the search 24 | # currently on result page using find_elements_by_class_name method 25 | lists= driver.find_elements_by_class_name("_Rm") 26 | 27 | # get the number of elements found 28 | print ("Found " + str(len(lists)) + "searches:") 29 | 30 | # iterate through each element and print the text that is 31 | # name of the search 32 | 33 | i=0 34 | for listitem in lists: 35 | print (listitem) 36 | i=i+1 37 | if(i>10): 38 | break 39 | 40 | # close the browser window 41 | driver.quit() -------------------------------------------------------------------------------- /tests/firefox_github_ssh_add.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # firefox_github_ssh_add.py in https://github.com/wilsonmar/git-utilities 3 | # Invokes python Firefox driver to open GitHub, SSH Keys, insert what waw pbcopy to clipboard. 4 | 5 | import time, sys, argparse # getopt 6 | 7 | from selenium import webdriver 8 | from selenium.webdriver.common.keys import Keys 9 | 10 | # https://www.python-course.eu/python3_history_and_philosophy.php 11 | 12 | #def main(argv): 13 | # parser = argparse.ArgumentParser() 14 | # parser.add_argument("square", help="display a square of a given number") 15 | # args = parser.parse_args() 16 | # print(args.square**2) 17 | 18 | # print ('Number of arguments:', len(sys.argv), 'arguments.') 19 | # print ('Argument List:', str(sys.argv)) 20 | 21 | #parser = argparse.ArgumentParser(description='Process selenium.') 22 | #parser.add_argument('browser', help='browser type') 23 | #args = parser.parse_args() 24 | #parser.add_argument('integers', metavar='N', type=int, nargs='+', 25 | # help='an integer for the accumulator') 26 | #parser.add_argument('--sum', dest='accumulate', action='store_const', 27 | # const=sum, default=max, 28 | # help='sum the integers (default: find the max)') 29 | 30 | #print args.accumulate(args.integers) 31 | 32 | # Create new browser session: 33 | # for opt, arg in opts: 34 | # if opt == 'firefox': 35 | # print ("webdriver.Firefox") 36 | driver = webdriver.Firefox() 37 | # elif opt == 'chrome': 38 | # # get the path of ChromeDriverServer; 39 | # dir = os.path.dirname(__file__) 40 | # chrome_driver_path = dir + "\chromedriver.exe" 41 | # print ("webdriver.Chrome") 42 | # driver = webdriver.Chrome() 43 | # elif opt == 'ie': 44 | # # get the path of IEDriverServer 45 | # dir = os.path.dirname(__file__) 46 | # ie_driver_path = dir + "\IEDriverServer.exe" 47 | # print ("webdriver.Chrome") 48 | # driver = webdriver.Chrome() 49 | 50 | 51 | driver.implicitly_wait(1) # seconds for network delays 52 | #driver.maximize_window() # so positions are consistent across sessions. 53 | 54 | ### Navigate to the application home/landing page: 55 | driver.get("https://www.github.com/") 56 | assert "The world's leading" in driver.title 57 | 58 | #search_field = driver.find_element_by_id("lst-ib") 59 | #search_field.clear() 60 | 61 | ### get the number of elements found: 62 | #print ("Found " + str(len(lists)) + "searches:") 63 | 64 | ### Get to Sign-in page: 65 | # elem = driver.find_element_by_name("Sign in") 66 | # elem.send_keys(Keys.RETURN) 67 | # elem.clear() 68 | 69 | ### Sign-in form: 70 | #assert "Sign-in" in driver.title 71 | #elem = driver.find_element_by_name("login") # within Form 72 | #elem.clear() 73 | #elem.send_keys("UserID") # from ./secrets.sh 74 | 75 | #elem = driver.find_element_by_name("password") 76 | #elem.clear() 77 | #elem.send_keys("password") # from ./secrets.sh via MacOS Clipboard. 78 | 79 | #elem = driver.find_element_by_name("Sign In") # Green button 80 | #elem.send_keys(Keys.RETURN) 81 | 82 | ### New SSH Key: 83 | #elem = driver.find_element_by_name("SSH Key") 84 | #elem = driver.find_element_by_name("SSH key field") 85 | #elem.clear() 86 | #elem.send_keys("SSH Key") # from file (not Clipboard) 87 | #elem.send_keys(Keys.RETURN) 88 | 89 | #assert "No results found." not in driver.page_source 90 | 91 | #driver.quit() 92 | 93 | #if __name__ == "__main__": 94 | # main(sys.argv[1:]) -------------------------------------------------------------------------------- /tests/firefox_pycon_search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # firefox_pycon_search.py 3 | # from http://selenium-python.readthedocs.io/getting-started.html#selenium-remote-webdriver 4 | from selenium import webdriver 5 | from selenium.webdriver.common.keys import Keys 6 | 7 | driver = webdriver.Firefox() 8 | 9 | driver.get("http://www.python.org") 10 | assert "Python" in driver.title 11 | elem = driver.find_element_by_name("q") 12 | elem.clear() 13 | elem.send_keys("pycon") 14 | elem.send_keys(Keys.RETURN) 15 | assert "No results found." not in driver.page_source 16 | #driver.close() 17 | -------------------------------------------------------------------------------- /tests/firefox_unittest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # python_firefox_unittest.py 3 | # from https://saucelabs.com/resources/articles/getting-started-with-webdriver-in-python-on-osx 4 | import unittest 5 | from selenium import webdriver 6 | from selenium.webdriver.common.by import By 7 | 8 | class WebDriverPythonBasics(unittest.TestCase): 9 | def setUp(self): 10 | self.browser = webdriver.Firefox() 11 | 12 | def test_saucelabs_homepage_header_displayed(self): 13 | self.browser.get('http://saucelabs.com') 14 | header = self.browser.find_element(By.ID, 'site-header') 15 | self.assertTrue(header.is_displayed()) 16 | 17 | def tearDown(self): 18 | self.browser.close() 19 | 20 | if name == 'main': -------------------------------------------------------------------------------- /tests/jenkins_secret_setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # jenkins_secret_chrome.py in https://github.com/wilsonmar/git-utilities/tree/master/tests/ 3 | # Call pattern: 4 | # python tests/jenkins_secret_chrome.py 'chrome' $JENKINS_PORT $JENKINS_SECRET jenkins.png 5 | 6 | #import argparse # https://docs.python.org/2/howto/argparse.html 7 | import sys 8 | import pytz, time 9 | from datetime import datetime, tzinfo, timedelta 10 | from random import randint 11 | 12 | from selenium import webdriver 13 | from selenium.webdriver.common.keys import Keys 14 | 15 | # From timestamps.py 16 | def iso8601_local(): 17 | class local_tz(tzinfo): 18 | def utcoffset(self, dt): 19 | ts = time.time() 20 | offset_in_seconds = (datetime.fromtimestamp(ts) - datetime.utcfromtimestamp(ts)).total_seconds() 21 | return timedelta(seconds=offset_in_seconds) 22 | return datetime.now().replace(microsecond=randint(0, 999999)).replace(tzinfo=local_tz()).isoformat() 23 | # print(iso8601_local()+" = ISO8601 time at local time zone offset, with random microseconds") 24 | 25 | driver=sys.argv[1] 26 | jenkins_port=sys.argv[2] 27 | jenkins_secret=sys.argv[3] 28 | #picture_path=sys.argv[3] 29 | print('driver=', driver, ', port=', jenkins_port, ', secret=', jenkins_secret) 30 | 31 | # TODO: #parser = argparse.ArgumentParser("simple_example") 32 | #parser.add_argument("counter", help="An integer will be increased by 1 and printed.", type=int) 33 | #args = parser.parse_args() 34 | #print(args.counter + 1) 35 | 36 | if driver == "chrome": 37 | print("chrome being used ...") 38 | driver = webdriver.Chrome() 39 | elif driver == "firefox": 40 | print("chrome being used ...") 41 | driver = webdriver.Firefox() 42 | 43 | driver.get("http://localhost:" + jenkins_port) # TODO: pass port in 44 | assert "Jenkins [Jenkins]" in driver.title # bail out if not found. Already processed. 45 | #time.sleep(5) # to see it. 46 | 47 | # 48 | secret = driver.find_element_by_id('security-token') 49 | secret.send_keys(jenkins_secret) 50 | secret.submit() 51 | time.sleep(8) # to give it time to work. 52 | 53 | # If the secret has already been processed: 54 | # INFO: Session node0vq5f7379gwo49h7hz67yatn37 already being invalidated 55 | 56 | # Take a picture (screen shot) of "Getting Started, Customize Jenkins" 57 | driver.save_screenshot('jenkins_secret_chrome.py.' +iso8601_local()+ '.png') 58 | assert "SetupWizard [Jenkins]" in driver.title 59 | #time.sleep(5) # to see it 60 | 61 | driver.dispose() 62 | -------------------------------------------------------------------------------- /tests/phantomjs-duck-search-1120x550.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # from https://realpython.com/headless-selenium-testing-with-python-and-phantomjs/ 3 | import unittest 4 | from selenium import webdriver 5 | 6 | 7 | class TestOne(unittest.TestCase): 8 | 9 | def setUp(self): 10 | self.driver = webdriver.PhantomJS() 11 | self.driver.set_window_size(1120, 550) 12 | 13 | def test_url(self): 14 | self.driver.get("http://duckduckgo.com/") 15 | self.driver.find_element_by_id( 16 | 'search_form_input_homepage').send_keys("realpython") 17 | self.driver.find_element_by_id("search_button_homepage").click() 18 | self.assertIn( 19 | "https://duckduckgo.com/?q=realpython", self.driver.current_url 20 | ) 21 | 22 | def tearDown(self): 23 | self.driver.quit() 24 | 25 | if __name__ == '__main__': 26 | unittest.main() -------------------------------------------------------------------------------- /tests/phantomjs-duck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # from https://realpython.com/headless-selenium-testing-with-python-and-phantomjs/ 3 | import unittest 4 | from selenium import webdriver 5 | 6 | 7 | class TestOne(unittest.TestCase): 8 | 9 | def setUp(self): 10 | self.driver = webdriver.PhantomJS() 11 | self.driver.set_window_size(1120, 550) 12 | 13 | def test_url(self): 14 | self.driver.get("http://duckduckgo.com/") 15 | self.driver.find_element_by_id( 16 | 'search_form_input_homepage').send_keys("realpython") 17 | self.driver.find_element_by_id("search_button_homepage").click() 18 | self.assertIn( 19 | "https://duckduckgo.com/?q=realpython", self.driver.current_url 20 | ) 21 | 22 | def tearDown(self): 23 | self.driver.quit() 24 | 25 | if __name__ == '__main__': 26 | unittest.main() -------------------------------------------------------------------------------- /tests/phantomjs-smoke.js: -------------------------------------------------------------------------------- 1 | // phantomjs-smoke.js in https://github.com/wilsonmar/git-utilities 2 | // Smoke test for installation. 3 | "use strict"; 4 | console.log('Hello, from tests/phantomjs-smoke.js!'); 5 | phantom.exit(); 6 | -------------------------------------------------------------------------------- /tests/timestamps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # timestamps.py 3 | 4 | import pytz, time 5 | from datetime import datetime, tzinfo, timedelta 6 | from random import randint 7 | 8 | def iso8601_utc(): 9 | class simple_utc(tzinfo): 10 | def tzname(self,**kwargs): 11 | return "UTC" 12 | def utcoffset(self, dt): 13 | return timedelta(0) 14 | return datetime.utcnow().replace(tzinfo=simple_utc()).isoformat() 15 | #print(iso8601_utc()+" = ISO8601 time at +00:00 UTC (Zulu time), with microseconds") 16 | 17 | def iso8601_local(): 18 | class local_tz(tzinfo): 19 | def utcoffset(self, dt): 20 | ts = time.time() 21 | offset_in_seconds = (datetime.fromtimestamp(ts) - datetime.utcfromtimestamp(ts)).total_seconds() 22 | return timedelta(seconds=offset_in_seconds) 23 | return datetime.now().replace(microsecond=randint(0, 999999)).replace(tzinfo=local_tz()).isoformat() 24 | # print(iso8601_local()+" = ISO8601 time at local time zone offset, with random microseconds") 25 | 26 | print(iso8601_utc()+" = ISO8601 time at +00:00 UTC (Zulu time), with microseconds") 27 | print(iso8601_local()+" = ISO8601 time at local time zone offset, with random microseconds") 28 | -------------------------------------------------------------------------------- /wm-ps-utils.psm1: -------------------------------------------------------------------------------- 1 | # wm-ps-utils.psm1 in https://github.com/wilsonmar/git-utilities 2 | # .psm1 = PowerShell module 3 | # .ps1 files using this needs to have this at the top of the file: 4 | # Import-Module wm-ps-utils.psm1 5 | # See https://msdn.microsoft.com/en-us/library/dd878284(v=vs.85).aspx 6 | 7 | <# 8 | .Synopsis 9 | Provides utilities for use with PowerShell. 10 | #> 11 | 12 | function Get-MacOsXsysteminformation { 13 | # From Stephane's http://powershelldistrict.com/powershell-mac-os-x/ 14 | [xml]$infos = system_profiler -xml 15 | return $infos 16 | } 17 | 18 | Function Touch-File { 19 | $file = $args[0] 20 | if($file -eq $null) { 21 | throw "No filename supplied" 22 | } 23 | 24 | if(Test-Path $file) 25 | { 26 | (Get-ChildItem $file).LastWriteTime = Get-Date 27 | } 28 | else 29 | { 30 | echo $null > $file 31 | } 32 | } 33 | 34 | Function Color-All-Black { 35 | 36 | $strComputer = "." 37 | 38 | $colItems = get-wmiobject -class "Win32_Process" -namespace "root\CIMV2" ` 39 | -computername $strComputer | write-output 40 | 41 | foreach ($objItem in $colItems) { 42 | # if ($objItem.WorkingSetSize -gt 3000000) { 43 | # write-host $objItem.Name, $objItem.WorkingSetSize -foregroundcolor "magenta" } 44 | # else { 45 | write-host $objItem.Name, $objItem.WorkingSetSize 46 | # } 47 | } 48 | } 49 | 50 | export-modulemember -function Touch-File --------------------------------------------------------------------------------