From 3b5133d0e484bf8e0e68ca9a17ba809a7c43794e Mon Sep 17 00:00:00 2001 From: Jannik ZANDER Date: Tue, 24 Oct 2017 21:00:33 +0200 Subject: [PATCH] More cleanup for ubuntu --- .Xresources | 240 ++--- .bash_profile | 2 +- .config/bash/aliases | 1 + .cshrc | 24 +- .dir_colors | 850 +++++++-------- .gitignore | 2 +- .inputrc | 124 +-- .profile | 34 +- .screenrc | 16 +- .tmux.conf | 204 ++-- bin/build-akmod.sh | 10 +- bin/build-luajit.sh | 6 +- bin/build-vim.sh | 36 +- bin/colortest | 0 bin/genilog.cmd | 1 - bin/git-diffall.sh | 552 +++++----- bin/git-difftool.sh | 6 +- bin/git-editor.sh | 8 +- bin/git-mergetool.sh | 8 +- bin/git-review | 2438 +++++++++++++++++++++--------------------- bin/rte.cmd | 8 - 21 files changed, 2281 insertions(+), 2289 deletions(-) mode change 100644 => 100755 bin/build-akmod.sh mode change 100644 => 100755 bin/build-luajit.sh mode change 100644 => 100755 bin/build-vim.sh mode change 100644 => 100755 bin/colortest delete mode 100644 bin/genilog.cmd mode change 100644 => 100755 bin/git-diffall.sh mode change 100644 => 100755 bin/git-difftool.sh mode change 100644 => 100755 bin/git-editor.sh mode change 100644 => 100755 bin/git-mergetool.sh mode change 100644 => 100755 bin/git-review delete mode 100644 bin/rte.cmd diff --git a/.Xresources b/.Xresources index da2bd02..bcc4a32 100644 --- a/.Xresources +++ b/.Xresources @@ -1,120 +1,120 @@ -!!SOLARIZED HEX 16/8 TERMCOL XTERM/HEX L*A*B RGB HSB -!!--------- ------- ---- ------- ----------- ---------- ----------- ----------- -!!base03 #002b36 8/4 brblack 234 #1c1c1c 15 -12 -12 0 43 54 193 100 21 -!!base02 #073642 0/4 black 235 #262626 20 -12 -12 7 54 66 192 90 26 -!!base01 #586e75 10/7 brgreen 240 #585858 45 -07 -07 88 110 117 194 25 46 -!!base00 #657b83 11/7 bryellow 241 #626262 50 -07 -07 101 123 131 195 23 51 -!!base0 #839496 12/6 brblue 244 #808080 60 -06 -03 131 148 150 186 13 59 -!!base1 #93a1a1 14/4 brcyan 245 #8a8a8a 65 -05 -02 147 161 161 180 9 63 -!!base2 #eee8d5 7/7 white 254 #e4e4e4 92 -00 10 238 232 213 44 11 93 -!!base3 #fdf6e3 15/7 brwhite 230 #ffffd7 97 00 10 253 246 227 44 10 99 -!!yellow #b58900 3/3 yellow 136 #af8700 60 10 65 181 137 0 45 100 71 -!!orange #cb4b16 9/3 brred 166 #d75f00 50 50 55 203 75 22 18 89 80 -!!red #dc322f 1/1 red 160 #d70000 50 65 45 220 50 47 1 79 86 -!!magenta #d33682 5/5 magenta 125 #af005f 50 65 -05 211 54 130 331 74 83 -!!violet #6c71c4 13/5 brmagenta 61 #5f5faf 50 15 -45 108 113 196 237 45 77 -!!blue #268bd2 4/4 blue 33 #0087ff 55 -10 -45 38 139 210 205 82 82 -!!cyan #2aa198 6/6 cyan 37 #00afaf 60 -35 -05 42 161 152 175 74 63 -!!green #859900 2/2 green 64 #5f8700 60 -20 65 133 153 0 68 100 60 - -#define SOLARIZED_DARK -#ifdef SOLARIZED_DARK -#define S_base03 #002b36 -#define S_base02 #073642 -#define S_base01 #586e75 -#define S_base00 #657b83 -#define S_base0 #839496 -#define S_base1 #93a1a1 -#define S_base2 #eee8d5 -#define S_base3 #fdf6e3 -#endif - -#ifdef SOLARIZED_LIGHT -#define S_base3 #002b36 -#define S_base2 #073642 -#define S_base1 #586e75 -#define S_base0 #657b83 -#define S_base00 #839496 -#define S_base01 #93a1a1 -#define S_base02 #eee8d5 -#define S_base03 #fdf6e3 -#endif - -#define S_yellow #b58900 -#define S_orange #cb4b16 -#define S_red #dc322f -#define S_magenta #d33682 -#define S_violet #6c71c4 -#define S_blue #268bd2 -#define S_cyan #2aa198 -#define S_green #859900 - - -*background: S_base03 -*foreground: S_base00 -*fading: 40 -*fadeColor: S_base03 -*cursorColor: S_base1 -*pointerColorBackground:S_base01 -*pointerColorForeground:S_base1 - -!! black dark/light -*color0: S_base02 -*color8: S_base03 - -!! red dark/light -*color1: S_red -*color9: S_orange - -!! green dark/light -*color2: S_green -*color10: S_base01 - -!! yellow dark/light -*color3: S_yellow -*color11: S_base00 - -!! blue dark/light -*color4: S_blue -*color12: S_base0 - -!! magenta dark/light -*color5: S_magenta -*color13: S_violet - -!! cyan dark/light -*color6: S_cyan -*color14: S_base1 - -!! white dark/light -*color7: S_base2 -*color15: S_base3 - -!! xterm -XTerm*termName: xterm-256color -!XTerm*faceName: Mono -!XTerm*faceSize: 11 -XTerm*metaSendsEscape: true -XTerm*vt100.translations: #override \n\ - Ctrl ~Shift Tab: string(0x1b) string("[34~") \n -XTerm*toolBar: off -XTerm*scrollBar: true -XTerm*rightScrollBar: true - -!! better font rendering -Xft.dpi: 96 -Xft.antialias: true -Xft.rgba: rgb -Xft.hinting: false -Xft.hintstyle: hintnone -Xft.lcdfilter: lcddefault - -*reverseWrap: true -*scrollKey: true -*saveLines: 10000 -*scrollBar: true -*scrollTtyOutput: false -*cutToBeginningOfLine: true - - -dt.obsolete: true +!!SOLARIZED HEX 16/8 TERMCOL XTERM/HEX L*A*B RGB HSB +!!--------- ------- ---- ------- ----------- ---------- ----------- ----------- +!!base03 #002b36 8/4 brblack 234 #1c1c1c 15 -12 -12 0 43 54 193 100 21 +!!base02 #073642 0/4 black 235 #262626 20 -12 -12 7 54 66 192 90 26 +!!base01 #586e75 10/7 brgreen 240 #585858 45 -07 -07 88 110 117 194 25 46 +!!base00 #657b83 11/7 bryellow 241 #626262 50 -07 -07 101 123 131 195 23 51 +!!base0 #839496 12/6 brblue 244 #808080 60 -06 -03 131 148 150 186 13 59 +!!base1 #93a1a1 14/4 brcyan 245 #8a8a8a 65 -05 -02 147 161 161 180 9 63 +!!base2 #eee8d5 7/7 white 254 #e4e4e4 92 -00 10 238 232 213 44 11 93 +!!base3 #fdf6e3 15/7 brwhite 230 #ffffd7 97 00 10 253 246 227 44 10 99 +!!yellow #b58900 3/3 yellow 136 #af8700 60 10 65 181 137 0 45 100 71 +!!orange #cb4b16 9/3 brred 166 #d75f00 50 50 55 203 75 22 18 89 80 +!!red #dc322f 1/1 red 160 #d70000 50 65 45 220 50 47 1 79 86 +!!magenta #d33682 5/5 magenta 125 #af005f 50 65 -05 211 54 130 331 74 83 +!!violet #6c71c4 13/5 brmagenta 61 #5f5faf 50 15 -45 108 113 196 237 45 77 +!!blue #268bd2 4/4 blue 33 #0087ff 55 -10 -45 38 139 210 205 82 82 +!!cyan #2aa198 6/6 cyan 37 #00afaf 60 -35 -05 42 161 152 175 74 63 +!!green #859900 2/2 green 64 #5f8700 60 -20 65 133 153 0 68 100 60 + +#define SOLARIZED_DARK +#ifdef SOLARIZED_DARK +#define S_base03 #002b36 +#define S_base02 #073642 +#define S_base01 #586e75 +#define S_base00 #657b83 +#define S_base0 #839496 +#define S_base1 #93a1a1 +#define S_base2 #eee8d5 +#define S_base3 #fdf6e3 +#endif + +#ifdef SOLARIZED_LIGHT +#define S_base3 #002b36 +#define S_base2 #073642 +#define S_base1 #586e75 +#define S_base0 #657b83 +#define S_base00 #839496 +#define S_base01 #93a1a1 +#define S_base02 #eee8d5 +#define S_base03 #fdf6e3 +#endif + +#define S_yellow #b58900 +#define S_orange #cb4b16 +#define S_red #dc322f +#define S_magenta #d33682 +#define S_violet #6c71c4 +#define S_blue #268bd2 +#define S_cyan #2aa198 +#define S_green #859900 + + +*background: S_base03 +*foreground: S_base00 +*fading: 40 +*fadeColor: S_base03 +*cursorColor: S_base1 +*pointerColorBackground:S_base01 +*pointerColorForeground:S_base1 + +!! black dark/light +*color0: S_base02 +*color8: S_base03 + +!! red dark/light +*color1: S_red +*color9: S_orange + +!! green dark/light +*color2: S_green +*color10: S_base01 + +!! yellow dark/light +*color3: S_yellow +*color11: S_base00 + +!! blue dark/light +*color4: S_blue +*color12: S_base0 + +!! magenta dark/light +*color5: S_magenta +*color13: S_violet + +!! cyan dark/light +*color6: S_cyan +*color14: S_base1 + +!! white dark/light +*color7: S_base2 +*color15: S_base3 + +!! xterm +XTerm*termName: xterm-256color +!XTerm*faceName: Mono +!XTerm*faceSize: 11 +XTerm*metaSendsEscape: true +XTerm*vt100.translations: #override \n\ + Ctrl ~Shift Tab: string(0x1b) string("[34~") \n +XTerm*toolBar: off +XTerm*scrollBar: true +XTerm*rightScrollBar: true + +!! better font rendering +Xft.dpi: 96 +Xft.antialias: true +Xft.rgba: rgb +Xft.hinting: false +Xft.hintstyle: hintnone +Xft.lcdfilter: lcddefault + +*reverseWrap: true +*scrollKey: true +*saveLines: 10000 +*scrollBar: true +*scrollTtyOutput: false +*cutToBeginningOfLine: true + + +dt.obsolete: true diff --git a/.bash_profile b/.bash_profile index e8e53b6..f8f9564 100644 --- a/.bash_profile +++ b/.bash_profile @@ -1 +1 @@ -[ -f ~/.profile ] && source ~/.profile +[ -f ~/.profile ] && source ~/.profile diff --git a/.config/bash/aliases b/.config/bash/aliases index aea7fb8..31f64c8 100644 --- a/.config/bash/aliases +++ b/.config/bash/aliases @@ -23,6 +23,7 @@ alias fgrep='fgrep --color=auto' if [ -e /usr/bin/vimx ]; then alias vim='/usr/bin/vimx'; fi # Shortcuts +alias dot='git --git-dir=$HOME/.dotfiles --work-tree=$HOME' alias g='git' alias h='history' alias j='jobs' diff --git a/.cshrc b/.cshrc index d62cb82..9a21b6d 100644 --- a/.cshrc +++ b/.cshrc @@ -1,12 +1,12 @@ -# .cshrc: executed by C shells on startup - -# If this is login or command shell then change to a sane shell -if ($SHELL != /bin/bash) then - setenv SHELL /bin/bash - if ($?command) then - exec /bin/bash -c "$command" - else - exec /bin/bash - endif -endif - +# .cshrc: executed by C shells on startup + +# If this is login or command shell then change to a sane shell +if ($SHELL != /bin/bash) then + setenv SHELL /bin/bash + if ($?command) then + exec /bin/bash -c "$command" + else + exec /bin/bash + endif +endif + diff --git a/.dir_colors b/.dir_colors index ed06760..f32324a 100644 --- a/.dir_colors +++ b/.dir_colors @@ -1,425 +1,425 @@ -# Exact Solarized Dark color theme for the color GNU ls utility. -# Designed for dircolors (GNU coreutils) 5.97 -# -# This simple theme was simultaneously designed for these terminal color schemes: -# - Solarized dark (best) -# - Solarized light -# - default dark -# - default light -# with a slight optimization for Solarized Dark. -# -# How the colors were selected: -# - Terminal emulators often have an option typically enabled by default that makes -# bold a different color. It is important to leave this option enabled so that -# you can access the entire 16-color Solarized palette, and not just 8 colors. -# - We favor universality over a greater number of colors. So we limit the number -# of colors so that this theme will work out of the box in all terminals, -# Solarized or not, dark or light. -# - We choose to have the following category of files: -# NORMAL & FILE, DIR, LINK, EXEC and -# editable text including source, unimportant text, binary docs & multimedia source -# files, viewable multimedia, archived/compressed, and unimportant non-text -# - For uniqueness, we stay away from the Solarized foreground colors are -- either -# base00 (brightyellow) or base0 (brighblue). However, they can be used if -# you know what the bg/fg colors of your terminal are, in order to optimize the display. -# - 3 different options are provided: universal, solarized dark, and solarized light. -# The only difference between the universal scheme and one that's optimized for -# dark/light is the color of "unimportant" files, which should blend more with the -# background -# - We note that blue is the hardest color to see on dark bg and yellow is the hardest -# color to see on light bg (with blue being particularly bad). So we choose yellow -# for multimedia files which are usually accessed in a GUI folder browser anyway. -# And blue is kept for custom use of this scheme's user. -# - See table below to see the assignments. - - -# Insatllation instructions: -# This file goes in the /etc directory, and must be world readable. -# You can copy this file to .dir_colors in your $HOME directory to override -# the system defaults. - -# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not -# pipes. 'all' adds color characters to all output. 'none' shuts colorization -# off. -COLOR tty - -# Below, there should be one TERM entry for each termtype that is colorizable -TERM ansi -TERM color_xterm -TERM color-xterm -TERM con132x25 -TERM con132x30 -TERM con132x43 -TERM con132x60 -TERM con80x25 -TERM con80x28 -TERM con80x30 -TERM con80x43 -TERM con80x50 -TERM con80x60 -TERM cons25 -TERM console -TERM cygwin -TERM dtterm -TERM Eterm -TERM eterm-color -TERM gnome -TERM gnome-256color -TERM jfbterm -TERM konsole -TERM kterm -TERM linux -TERM linux-c -TERM mach-color -TERM mlterm -TERM nxterm -TERM putty -TERM rxvt -TERM rxvt-256color -TERM rxvt-cygwin -TERM rxvt-cygwin-native -TERM rxvt-unicode -TERM rxvt-unicode256 -TERM rxvt-unicode-256color -TERM screen -TERM screen-256color -TERM screen-256color-bce -TERM screen-bce -TERM screen.linux -TERM screen-w -TERM vt100 -TERM xterm -TERM xterm-16color -TERM xterm-256color -TERM xterm-88color -TERM xterm-color -TERM xterm-debian - -# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) -EIGHTBIT 1 - -############################################################################# -# Below are the color init strings for the basic file types. A color init -# string consists of one or more of the following numeric codes: -# -# Attribute codes: -# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed -# Text color codes: -# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white -# Background color codes: -# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -# -# NOTES: -# - See http://www.oreilly.com/catalog/wdnut/excerpt/color_names.html -# - Color combinations -# ANSI Color code Solarized Notes Universal SolDark SolLight -# ~~~~~~~~~~~~~~~ ~~~~~~~~~ ~~~~~ ~~~~~~~~~ ~~~~~~~ ~~~~~~~~ -# 00 none NORMAL, FILE -# 30 black base02 -# 01;30 bright black base03 bg of SolDark -# 31 red red docs & mm src -# 01;31 bright red orange EXEC -# 32 green green editable text -# 01;32 bright green base01 unimportant text -# 33 yellow yellow unclear in light bg multimedia -# 01;33 bright yellow base00 fg of SolLight unimportant non-text -# 34 blue blue unclear in dark bg user customized -# 01;34 bright blue base0 fg in SolDark unimportant text -# 35 magenta magenta LINK -# 01;35 bright magenta violet archive/compressed -# 36 cyan cyan DIR -# 01;36 bright cyan base1 unimportant non-text -# 37 white base2 -# 01;37 bright white base3 bg in SolLight -# 05;37;41 unclear in Putty dark - - -### By file type - -# global default -NORMAL 00 -# normal file -FILE 00 -# directory -DIR 36 -# symbolic link -LINK 35 - -# pipe, socket, block device, character device (blue bg) -FIFO 30;44 -SOCK 35;44 -DOOR 35;44 # Solaris 2.5 and later -BLK 33;44 -CHR 37;44 - - -############################################################################# -### By file attributes - -# Orphaned symlinks (blinking white on red) -# Blink may or may not work (works on iTerm dark or light, and Putty dark) -ORPHAN 05;37;41 -# ... and the files that orphaned symlinks point to (blinking white on red) -MISSING 05;37;41 - -# files with execute permission -EXEC 01;31 # Unix -.cmd 01;31 # Win -.exe 01;31 # Win -.com 01;31 # Win -.bat 01;31 # Win -.reg 01;31 # Win -.app 01;31 # OSX - -############################################################################# -### By extension - -# List any file extensions like '.gz' or '.tar' that you would like ls -# to colorize below. Put the extension, a space, and the color init string. -# (and any comments you want to add after a '#') - -### Text formats - -# Text that we can edit with a regular editor -.txt 32 -.org 32 -.md 32 -.mkd 32 - -# Source text -.h 32 -.c 32 -.C 32 -.cc 32 -.cxx 32 -.objc 32 -.sh 32 -.csh 32 -.zsh 32 -.el 32 -.vim 32 -.java 32 -.pl 32 -.pm 32 -.py 32 -.rb 32 -.hs 32 -.php 32 -.htm 32 -.html 32 -.shtml 32 -.xml 32 -.rdf 32 -.css 32 -.js 32 -.man 32 -.0 32 -.1 32 -.2 32 -.3 32 -.4 32 -.5 32 -.6 32 -.7 32 -.8 32 -.9 32 -.l 32 -.n 32 -.p 32 -.pod 32 -.tex 32 - -### Multimedia formats - -# Image -.bmp 33 -.cgm 33 -.dl 33 -.dvi 33 -.emf 33 -.eps 33 -.gif 33 -.jpeg 33 -.jpg 33 -.JPG 33 -.mng 33 -.pbm 33 -.pcx 33 -.pdf 33 -.pgm 33 -.png 33 -.ppm 33 -.pps 33 -.ppsx 33 -.ps 33 -.svg 33 -.svgz 33 -.tga 33 -.tif 33 -.tiff 33 -.xbm 33 -.xcf 33 -.xpm 33 -.xwd 33 -.xwd 33 -.yuv 33 - -# Audio -.aac 33 -.au 33 -.flac 33 -.mid 33 -.midi 33 -.mka 33 -.mp3 33 -.mpa 33 -.mpeg 33 -.mpg 33 -.ogg 33 -.ra 33 -.wav 33 - -# Video -.anx 33 -.asf 33 -.avi 33 -.axv 33 -.flc 33 -.fli 33 -.flv 33 -.gl 33 -.m2v 33 -.m4v 33 -.mkv 33 -.mov 33 -.mp4 33 -.mp4v 33 -.mpeg 33 -.mpg 33 -.nuv 33 -.ogm 33 -.ogv 33 -.ogx 33 -.qt 33 -.rm 33 -.rmvb 33 -.swf 33 -.vob 33 -.wmv 33 - -### Misc - -# Binary document formats and multimedia source -.doc 31 -.docx 31 -.rtf 31 -.dot 31 -.dotx 31 -.xls 31 -.xlsx 31 -.ppt 31 -.pptx 31 -.fla 31 -.psd 31 - -# Archives, compressed -.7z 1;35 -.apk 1;35 -.arj 1;35 -.bin 1;35 -.bz 1;35 -.bz2 1;35 -.cab 1;35 # Win -.deb 1;35 -.dmg 1;35 # OSX -.gem 1;35 -.gz 1;35 -.iso 1;35 -.jar 1;35 -.msi 1;35 # Win -.rar 1;35 -.rpm 1;35 -.tar 1;35 -.tbz 1;35 -.tbz2 1;35 -.tgz 1;35 -.tx 1;35 -.war 1;35 -.xpi 1;35 -.xz 1;35 -.z 1;35 -.Z 1;35 -.zip 1;35 - -# For testing -.ANSI-30-black 30 -.ANSI-01;30-brblack 01;30 -.ANSI-31-red 31 -.ANSI-01;31-brred 01;31 -.ANSI-32-green 32 -.ANSI-01;32-brgreen 01;32 -.ANSI-33-yellow 33 -.ANSI-01;33-bryellow 01;33 -.ANSI-34-blue 34 -.ANSI-01;34-brblue 01;34 -.ANSI-35-magenta 35 -.ANSI-01;35-brmagenta 01;35 -.ANSI-36-cyan 36 -.ANSI-01;36-brcyan 01;36 -.ANSI-37-white 37 -.ANSI-01;37-brwhite 01;37 - -############################################################################# -# Your customizations - -# Unimportant text files -# For universal scheme, use brightgreen 01;32 -# For optimal on light bg (but too prominent on dark bg), use white 01;34 -.log 01;32 -*~ 01;32 -*# 01;32 -#.log 01;34 -#*~ 01;34 -#*# 01;34 - -# Unimportant non-text files -# For universal scheme, use brightcyan 01;36 -# For optimal on dark bg (but too prominent on light bg), change to 01;33 -#.bak 01;36 -#.BAK 01;36 -#.old 01;36 -#.OLD 01;36 -#.org_archive 01;36 -#.off 01;36 -#.OFF 01;36 -#.dist 01;36 -#.DIST 01;36 -#.orig 01;36 -#.ORIG 01;36 -#.swp 01;36 -#.swo 01;36 -#*,v 01;36 -.bak 01;33 -.BAK 01;33 -.old 01;33 -.OLD 01;33 -.org_archive 01;33 -.off 01;33 -.OFF 01;33 -.dist 01;33 -.DIST 01;33 -.orig 01;33 -.ORIG 01;33 -.swp 01;33 -.swo 01;33 -*,v 01;33 - -# The brightmagenta (Solarized: purple) color is free for you to use for your -# custom file type -.gpg 34 -.gpg 34 -.pgp 34 -.asc 34 -.3des 34 -.aes 34 -.enc 34 +# Exact Solarized Dark color theme for the color GNU ls utility. +# Designed for dircolors (GNU coreutils) 5.97 +# +# This simple theme was simultaneously designed for these terminal color schemes: +# - Solarized dark (best) +# - Solarized light +# - default dark +# - default light +# with a slight optimization for Solarized Dark. +# +# How the colors were selected: +# - Terminal emulators often have an option typically enabled by default that makes +# bold a different color. It is important to leave this option enabled so that +# you can access the entire 16-color Solarized palette, and not just 8 colors. +# - We favor universality over a greater number of colors. So we limit the number +# of colors so that this theme will work out of the box in all terminals, +# Solarized or not, dark or light. +# - We choose to have the following category of files: +# NORMAL & FILE, DIR, LINK, EXEC and +# editable text including source, unimportant text, binary docs & multimedia source +# files, viewable multimedia, archived/compressed, and unimportant non-text +# - For uniqueness, we stay away from the Solarized foreground colors are -- either +# base00 (brightyellow) or base0 (brighblue). However, they can be used if +# you know what the bg/fg colors of your terminal are, in order to optimize the display. +# - 3 different options are provided: universal, solarized dark, and solarized light. +# The only difference between the universal scheme and one that's optimized for +# dark/light is the color of "unimportant" files, which should blend more with the +# background +# - We note that blue is the hardest color to see on dark bg and yellow is the hardest +# color to see on light bg (with blue being particularly bad). So we choose yellow +# for multimedia files which are usually accessed in a GUI folder browser anyway. +# And blue is kept for custom use of this scheme's user. +# - See table below to see the assignments. + + +# Insatllation instructions: +# This file goes in the /etc directory, and must be world readable. +# You can copy this file to .dir_colors in your $HOME directory to override +# the system defaults. + +# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not +# pipes. 'all' adds color characters to all output. 'none' shuts colorization +# off. +COLOR tty + +# Below, there should be one TERM entry for each termtype that is colorizable +TERM ansi +TERM color_xterm +TERM color-xterm +TERM con132x25 +TERM con132x30 +TERM con132x43 +TERM con132x60 +TERM con80x25 +TERM con80x28 +TERM con80x30 +TERM con80x43 +TERM con80x50 +TERM con80x60 +TERM cons25 +TERM console +TERM cygwin +TERM dtterm +TERM Eterm +TERM eterm-color +TERM gnome +TERM gnome-256color +TERM jfbterm +TERM konsole +TERM kterm +TERM linux +TERM linux-c +TERM mach-color +TERM mlterm +TERM nxterm +TERM putty +TERM rxvt +TERM rxvt-256color +TERM rxvt-cygwin +TERM rxvt-cygwin-native +TERM rxvt-unicode +TERM rxvt-unicode256 +TERM rxvt-unicode-256color +TERM screen +TERM screen-256color +TERM screen-256color-bce +TERM screen-bce +TERM screen.linux +TERM screen-w +TERM vt100 +TERM xterm +TERM xterm-16color +TERM xterm-256color +TERM xterm-88color +TERM xterm-color +TERM xterm-debian + +# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) +EIGHTBIT 1 + +############################################################################# +# Below are the color init strings for the basic file types. A color init +# string consists of one or more of the following numeric codes: +# +# Attribute codes: +# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed +# Text color codes: +# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white +# Background color codes: +# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white +# +# NOTES: +# - See http://www.oreilly.com/catalog/wdnut/excerpt/color_names.html +# - Color combinations +# ANSI Color code Solarized Notes Universal SolDark SolLight +# ~~~~~~~~~~~~~~~ ~~~~~~~~~ ~~~~~ ~~~~~~~~~ ~~~~~~~ ~~~~~~~~ +# 00 none NORMAL, FILE +# 30 black base02 +# 01;30 bright black base03 bg of SolDark +# 31 red red docs & mm src +# 01;31 bright red orange EXEC +# 32 green green editable text +# 01;32 bright green base01 unimportant text +# 33 yellow yellow unclear in light bg multimedia +# 01;33 bright yellow base00 fg of SolLight unimportant non-text +# 34 blue blue unclear in dark bg user customized +# 01;34 bright blue base0 fg in SolDark unimportant text +# 35 magenta magenta LINK +# 01;35 bright magenta violet archive/compressed +# 36 cyan cyan DIR +# 01;36 bright cyan base1 unimportant non-text +# 37 white base2 +# 01;37 bright white base3 bg in SolLight +# 05;37;41 unclear in Putty dark + + +### By file type + +# global default +NORMAL 00 +# normal file +FILE 00 +# directory +DIR 36 +# symbolic link +LINK 35 + +# pipe, socket, block device, character device (blue bg) +FIFO 30;44 +SOCK 35;44 +DOOR 35;44 # Solaris 2.5 and later +BLK 33;44 +CHR 37;44 + + +############################################################################# +### By file attributes + +# Orphaned symlinks (blinking white on red) +# Blink may or may not work (works on iTerm dark or light, and Putty dark) +ORPHAN 05;37;41 +# ... and the files that orphaned symlinks point to (blinking white on red) +MISSING 05;37;41 + +# files with execute permission +EXEC 01;31 # Unix +.cmd 01;31 # Win +.exe 01;31 # Win +.com 01;31 # Win +.bat 01;31 # Win +.reg 01;31 # Win +.app 01;31 # OSX + +############################################################################# +### By extension + +# List any file extensions like '.gz' or '.tar' that you would like ls +# to colorize below. Put the extension, a space, and the color init string. +# (and any comments you want to add after a '#') + +### Text formats + +# Text that we can edit with a regular editor +.txt 32 +.org 32 +.md 32 +.mkd 32 + +# Source text +.h 32 +.c 32 +.C 32 +.cc 32 +.cxx 32 +.objc 32 +.sh 32 +.csh 32 +.zsh 32 +.el 32 +.vim 32 +.java 32 +.pl 32 +.pm 32 +.py 32 +.rb 32 +.hs 32 +.php 32 +.htm 32 +.html 32 +.shtml 32 +.xml 32 +.rdf 32 +.css 32 +.js 32 +.man 32 +.0 32 +.1 32 +.2 32 +.3 32 +.4 32 +.5 32 +.6 32 +.7 32 +.8 32 +.9 32 +.l 32 +.n 32 +.p 32 +.pod 32 +.tex 32 + +### Multimedia formats + +# Image +.bmp 33 +.cgm 33 +.dl 33 +.dvi 33 +.emf 33 +.eps 33 +.gif 33 +.jpeg 33 +.jpg 33 +.JPG 33 +.mng 33 +.pbm 33 +.pcx 33 +.pdf 33 +.pgm 33 +.png 33 +.ppm 33 +.pps 33 +.ppsx 33 +.ps 33 +.svg 33 +.svgz 33 +.tga 33 +.tif 33 +.tiff 33 +.xbm 33 +.xcf 33 +.xpm 33 +.xwd 33 +.xwd 33 +.yuv 33 + +# Audio +.aac 33 +.au 33 +.flac 33 +.mid 33 +.midi 33 +.mka 33 +.mp3 33 +.mpa 33 +.mpeg 33 +.mpg 33 +.ogg 33 +.ra 33 +.wav 33 + +# Video +.anx 33 +.asf 33 +.avi 33 +.axv 33 +.flc 33 +.fli 33 +.flv 33 +.gl 33 +.m2v 33 +.m4v 33 +.mkv 33 +.mov 33 +.mp4 33 +.mp4v 33 +.mpeg 33 +.mpg 33 +.nuv 33 +.ogm 33 +.ogv 33 +.ogx 33 +.qt 33 +.rm 33 +.rmvb 33 +.swf 33 +.vob 33 +.wmv 33 + +### Misc + +# Binary document formats and multimedia source +.doc 31 +.docx 31 +.rtf 31 +.dot 31 +.dotx 31 +.xls 31 +.xlsx 31 +.ppt 31 +.pptx 31 +.fla 31 +.psd 31 + +# Archives, compressed +.7z 1;35 +.apk 1;35 +.arj 1;35 +.bin 1;35 +.bz 1;35 +.bz2 1;35 +.cab 1;35 # Win +.deb 1;35 +.dmg 1;35 # OSX +.gem 1;35 +.gz 1;35 +.iso 1;35 +.jar 1;35 +.msi 1;35 # Win +.rar 1;35 +.rpm 1;35 +.tar 1;35 +.tbz 1;35 +.tbz2 1;35 +.tgz 1;35 +.tx 1;35 +.war 1;35 +.xpi 1;35 +.xz 1;35 +.z 1;35 +.Z 1;35 +.zip 1;35 + +# For testing +.ANSI-30-black 30 +.ANSI-01;30-brblack 01;30 +.ANSI-31-red 31 +.ANSI-01;31-brred 01;31 +.ANSI-32-green 32 +.ANSI-01;32-brgreen 01;32 +.ANSI-33-yellow 33 +.ANSI-01;33-bryellow 01;33 +.ANSI-34-blue 34 +.ANSI-01;34-brblue 01;34 +.ANSI-35-magenta 35 +.ANSI-01;35-brmagenta 01;35 +.ANSI-36-cyan 36 +.ANSI-01;36-brcyan 01;36 +.ANSI-37-white 37 +.ANSI-01;37-brwhite 01;37 + +############################################################################# +# Your customizations + +# Unimportant text files +# For universal scheme, use brightgreen 01;32 +# For optimal on light bg (but too prominent on dark bg), use white 01;34 +.log 01;32 +*~ 01;32 +*# 01;32 +#.log 01;34 +#*~ 01;34 +#*# 01;34 + +# Unimportant non-text files +# For universal scheme, use brightcyan 01;36 +# For optimal on dark bg (but too prominent on light bg), change to 01;33 +#.bak 01;36 +#.BAK 01;36 +#.old 01;36 +#.OLD 01;36 +#.org_archive 01;36 +#.off 01;36 +#.OFF 01;36 +#.dist 01;36 +#.DIST 01;36 +#.orig 01;36 +#.ORIG 01;36 +#.swp 01;36 +#.swo 01;36 +#*,v 01;36 +.bak 01;33 +.BAK 01;33 +.old 01;33 +.OLD 01;33 +.org_archive 01;33 +.off 01;33 +.OFF 01;33 +.dist 01;33 +.DIST 01;33 +.orig 01;33 +.ORIG 01;33 +.swp 01;33 +.swo 01;33 +*,v 01;33 + +# The brightmagenta (Solarized: purple) color is free for you to use for your +# custom file type +.gpg 34 +.gpg 34 +.pgp 34 +.asc 34 +.3des 34 +.aes 34 +.enc 34 diff --git a/.gitignore b/.gitignore index 3ec65ff..a7db3a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -.dotfiles +.dotfiles diff --git a/.inputrc b/.inputrc index bba392d..630cf3c 100644 --- a/.inputrc +++ b/.inputrc @@ -1,62 +1,62 @@ -# Use vi keybindings for everything that uses readline. - -# Adds punctuation as word delimiters -set bind-tty-special-chars off - -# Completion Options -set completion-ignore-case on -set show-all-if-ambiguous on -set show-all-if-unmodified on -set mark-symlinked-directories on -set match-hidden-files off -set page-completions on -set completion-query-items 200 -set visible-stats on -set skip-completed-text on - -set editing-mode vi -set keymap vi -$if mode=vi - # Prompt will be prefixed with a `+` while in insert mode and a `:` when in command mode - #set show-mode-in-prompt on - set keymap vi-command - "gg": beginning-of-history - "G": end-of-history - "k": history-search-backward - "j": history-search-forward - - set keymap vi-insert - "jj": vi-movement-mode - "\C-l": clear-screen - "\C-w": backward-kill-word - "\C-k": history-search-backward - "\C-j": history-search-forward -$endif - -$if Bash - # do history expansion when space entered - Space: magic-space -$endif - -$if Python -$endif - -$if Gdb - "\e[15~": "continue\n" - "\e[21~": "next\n" - "\e[23~": "step\n" - "\eOQ": "nexti\n" - "\eOR": "stepi\n" -$endif - -"\es": menu-complete - -# Useful stuff for UTF-8 -set meta-flag on -set input-meta on -set output-meta on -set convert-meta off - -# Include system wide settings which is ignored -# by default if one has own .inputrc -$include ~/inputrc_local +# Use vi keybindings for everything that uses readline. + +# Adds punctuation as word delimiters +set bind-tty-special-chars off + +# Completion Options +set completion-ignore-case on +set show-all-if-ambiguous on +set show-all-if-unmodified on +set mark-symlinked-directories on +set match-hidden-files off +set page-completions on +set completion-query-items 200 +set visible-stats on +set skip-completed-text on + +set editing-mode vi +set keymap vi +$if mode=vi + # Prompt will be prefixed with a `+` while in insert mode and a `:` when in command mode + #set show-mode-in-prompt on + set keymap vi-command + "gg": beginning-of-history + "G": end-of-history + "k": history-search-backward + "j": history-search-forward + + set keymap vi-insert + "jj": vi-movement-mode + "\C-l": clear-screen + "\C-w": backward-kill-word + "\C-k": history-search-backward + "\C-j": history-search-forward +$endif + +$if Bash + # do history expansion when space entered + Space: magic-space +$endif + +$if Python +$endif + +$if Gdb + "\e[15~": "continue\n" + "\e[21~": "next\n" + "\e[23~": "step\n" + "\eOQ": "nexti\n" + "\eOR": "stepi\n" +$endif + +"\es": menu-complete + +# Useful stuff for UTF-8 +set meta-flag on +set input-meta on +set output-meta on +set convert-meta off + +# Include system wide settings which is ignored +# by default if one has own .inputrc +$include ~/inputrc_local diff --git a/.profile b/.profile index f6bcf3c..ac752e1 100644 --- a/.profile +++ b/.profile @@ -1,17 +1,17 @@ -# User dependent .profile file - -# This file is not read by bash(1) if ~/.bash_profile or ~/.bash_login -# exists. - -# the default umask is set in /etc/profile; -umask 022 - -# if running bash -if [ -n "${BASH_VERSION}" ]; then - [ -f "${HOME}/.bashrc" ] && . "${HOME}/.bashrc" -fi - -# set path, environment, prompt etc -for file in ${HOME}/.config/profile/*.sh; do - [ -f "$file" ] && . "$file"; -done; +# User dependent .profile file + +# This file is not read by bash(1) if ~/.bash_profile or ~/.bash_login +# exists. + +# the default umask is set in /etc/profile; +umask 022 + +# if running bash +if [ -n "${BASH_VERSION}" ]; then + [ -f "${HOME}/.bashrc" ] && . "${HOME}/.bashrc" +fi + +# set path, environment, prompt etc +for file in ${HOME}/.config/profile/*.sh; do + [ -f "$file" ] && . "$file"; +done; diff --git a/.screenrc b/.screenrc index 5b9d007..a4a33ba 100644 --- a/.screenrc +++ b/.screenrc @@ -1,8 +1,8 @@ -# Disable the startup message -startup_message off - -# Set a large scrollback buffer -defscrollback 32000 - -# Always start `screen` with UTF-8 enabled (`screen -U`) -defutf8 on +# Disable the startup message +startup_message off + +# Set a large scrollback buffer +defscrollback 32000 + +# Always start `screen` with UTF-8 enabled (`screen -U`) +defutf8 on diff --git a/.tmux.conf b/.tmux.conf index ecbbbdc..4c56589 100644 --- a/.tmux.conf +++ b/.tmux.conf @@ -1,102 +1,102 @@ -# Setting the prefix from C-b to C-a -set -g prefix C-a -# Free the original Ctrl-b prefix keybinding -unbind C-b -#setting the delay between prefix and command -set -sg escape-time 1 -# Ensure that we can send Ctrl-A to other apps -bind C-a send-prefix -# Set the base index for windows to 1 instead of 0 -set -g base-index 1 -# Set the base index for panes to 1 instead of 0 -setw -g pane-base-index 1 - -# Set the default terminal mode to 256color mode -set -g default-terminal "screen-256color" -# enable activity alerts -setw -g monitor-activity on -set -g visual-activity on -# set the status line's colors -set -g status-fg white -set -g status-bg black -# set the color of the window list -setw -g window-status-fg cyan -setw -g window-status-bg default -setw -g window-status-attr dim -# set colors for the active window -setw -g window-status-current-fg white -setw -g window-status-current-bg red -setw -g window-status-current-attr bright -# pane colors -set -g pane-border-fg green -set -g pane-border-bg black -set -g pane-active-border-fg white -set -g pane-active-border-bg yellow -# Command / message line -set -g message-fg white -set -g message-bg black -set -g message-attr bright -# Status line left side -set -g status-left-length 40 -set -g status-left "#[fg=green]Session: #S #[fg=yellow]#I #[fg=cyan]#P" -set -g status-utf8 on -# Status line right side -# 15% | 28 Nov 18:15 -set -g status-right "#(~/battery Discharging) | #[fg=cyan]%d %b %R" -# Update the status bar every sixty seconds -set -g status-interval 60 -# Center the window list -set -g status-justify centre -set -g detach-on-destroy off -# Increase history-limit for scrolling (default is 2000) -set-option -g history-limit 15000 -# mouse support - set to on if you want to use the mouse -#setw -g mode-mouse on -#set -g mouse-select-pane on -#set -g mouse-resize-pane on -#set -g mouse-select-window on -#set -g mouse-utf8 on -# enable vi keys. -setw -g mode-keys vi -# Reload the file with Prefix r -bind r source-file ~/.tmux.conf \; display "Reloaded!" -# splitting panes -bind c neww -c "#{pane_current_path}" -bind | split-window -h -c "#{pane_current_path}" -bind - split-window -v -c "#{pane_current_path}" -# moving between panes -bind h select-pane -L -bind j select-pane -D -bind k select-pane -U -bind l select-pane -R -# Quick pane selection -bind -r C-h select-window -t :- -bind -r C-l select-window -t :+ -# Pane resizing -bind -r H resize-pane -L 5 -bind -r J resize-pane -D 5 -bind -r K resize-pane -U 5 -bind -r L resize-pane -R 5 -# Open panes in the same directory using the tmux-panes script -unbind v -unbind n -bind v send-keys " ~/tmux-panes -h" C-m -bind n send-keys " ~/tmux-panes -v" C-m -# Maximize and restore a pane -unbind Up -bind Up new-window -d -n tmp \; swap-pane -s tmp.1 \; select-window -t tmp -unbind Down -bind Down last-window \; swap-pane -s tmp.1 \; kill-window -t tmp -# Log output to a text file on demand -bind P pipe-pane -o "cat >>~/#W.log" \; display "Toggled logging to ~/#W.log" -# better binding for copy mode -bind v copy-mode -# Select/yank like vim -bind -t vi-copy 'v' begin-selection -bind -t vi-copy 'y' copy-selection -# open tree instead of session list -bind s run 'tmuxer choose-session' -bind-key -t vi-choice h tree-collapse -bind-key -t vi-choice l tree-expand -# local/private settings -source-file ~/.tmux_local.conf +# Setting the prefix from C-b to C-a +set -g prefix C-a +# Free the original Ctrl-b prefix keybinding +unbind C-b +#setting the delay between prefix and command +set -sg escape-time 1 +# Ensure that we can send Ctrl-A to other apps +bind C-a send-prefix +# Set the base index for windows to 1 instead of 0 +set -g base-index 1 +# Set the base index for panes to 1 instead of 0 +setw -g pane-base-index 1 + +# Set the default terminal mode to 256color mode +set -g default-terminal "screen-256color" +# enable activity alerts +setw -g monitor-activity on +set -g visual-activity on +# set the status line's colors +set -g status-fg white +set -g status-bg black +# set the color of the window list +setw -g window-status-fg cyan +setw -g window-status-bg default +setw -g window-status-attr dim +# set colors for the active window +setw -g window-status-current-fg white +setw -g window-status-current-bg red +setw -g window-status-current-attr bright +# pane colors +set -g pane-border-fg green +set -g pane-border-bg black +set -g pane-active-border-fg white +set -g pane-active-border-bg yellow +# Command / message line +set -g message-fg white +set -g message-bg black +set -g message-attr bright +# Status line left side +set -g status-left-length 40 +set -g status-left "#[fg=green]Session: #S #[fg=yellow]#I #[fg=cyan]#P" +set -g status-utf8 on +# Status line right side +# 15% | 28 Nov 18:15 +set -g status-right "#(~/battery Discharging) | #[fg=cyan]%d %b %R" +# Update the status bar every sixty seconds +set -g status-interval 60 +# Center the window list +set -g status-justify centre +set -g detach-on-destroy off +# Increase history-limit for scrolling (default is 2000) +set-option -g history-limit 15000 +# mouse support - set to on if you want to use the mouse +#setw -g mode-mouse on +#set -g mouse-select-pane on +#set -g mouse-resize-pane on +#set -g mouse-select-window on +#set -g mouse-utf8 on +# enable vi keys. +setw -g mode-keys vi +# Reload the file with Prefix r +bind r source-file ~/.tmux.conf \; display "Reloaded!" +# splitting panes +bind c neww -c "#{pane_current_path}" +bind | split-window -h -c "#{pane_current_path}" +bind - split-window -v -c "#{pane_current_path}" +# moving between panes +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R +# Quick pane selection +bind -r C-h select-window -t :- +bind -r C-l select-window -t :+ +# Pane resizing +bind -r H resize-pane -L 5 +bind -r J resize-pane -D 5 +bind -r K resize-pane -U 5 +bind -r L resize-pane -R 5 +# Open panes in the same directory using the tmux-panes script +unbind v +unbind n +bind v send-keys " ~/tmux-panes -h" C-m +bind n send-keys " ~/tmux-panes -v" C-m +# Maximize and restore a pane +unbind Up +bind Up new-window -d -n tmp \; swap-pane -s tmp.1 \; select-window -t tmp +unbind Down +bind Down last-window \; swap-pane -s tmp.1 \; kill-window -t tmp +# Log output to a text file on demand +bind P pipe-pane -o "cat >>~/#W.log" \; display "Toggled logging to ~/#W.log" +# better binding for copy mode +bind v copy-mode +# Select/yank like vim +bind -t vi-copy 'v' begin-selection +bind -t vi-copy 'y' copy-selection +# open tree instead of session list +bind s run 'tmuxer choose-session' +bind-key -t vi-choice h tree-collapse +bind-key -t vi-choice l tree-expand +# local/private settings +source-file ~/.tmux_local.conf diff --git a/bin/build-akmod.sh b/bin/build-akmod.sh old mode 100644 new mode 100755 index c451db7..ddcec7d --- a/bin/build-akmod.sh +++ b/bin/build-akmod.sh @@ -1,5 +1,5 @@ -#!/bin/sh - -sudo dnf install kernel-$1 -sudo dnf install akmod-wl "kernel-devel-uname-r == $(uname -r)" -sudo akmods +#!/bin/sh + +sudo dnf install kernel-$1 +sudo dnf install akmod-wl "kernel-devel-uname-r == $(uname -r)" +sudo akmods diff --git a/bin/build-luajit.sh b/bin/build-luajit.sh old mode 100644 new mode 100755 index 2989278..5d635d9 --- a/bin/build-luajit.sh +++ b/bin/build-luajit.sh @@ -1,3 +1,3 @@ -#!/bin/sh -make PREFIX=$PREFIX MULTILIB=lib -make install PREFIX=$PREFIX/apps/luajit MULTILIB=lib +#!/bin/sh +make PREFIX=$PREFIX MULTILIB=lib +make install PREFIX=$PREFIX/apps/luajit MULTILIB=lib diff --git a/bin/build-vim.sh b/bin/build-vim.sh old mode 100644 new mode 100755 index b0938cc..09274d0 --- a/bin/build-vim.sh +++ b/bin/build-vim.sh @@ -1,18 +1,18 @@ -#!/bin/sh - -./configure \ ---prefix=$PREFIX \ ---with-features=huge \ ---with-compiledby="ejannza" \ ---enable-multibyte \ ---enable-gui=gtk2 \ ---enable-luainterp \ ---with-lua-prefix=$PREFIX --with-luajit \ ---enable-gpm \ ---enable-cscope \ ---enable-fontset \ ---enable-fail-if-missing - - -make -make install prefix=$PREFIX/apps/vim +#!/bin/sh + +./configure \ +--prefix=$PREFIX \ +--with-features=huge \ +--with-compiledby="ejannza" \ +--enable-multibyte \ +--enable-gui=gtk2 \ +--enable-luainterp \ +--with-lua-prefix=$PREFIX --with-luajit \ +--enable-gpm \ +--enable-cscope \ +--enable-fontset \ +--enable-fail-if-missing + + +make +make install prefix=$PREFIX/apps/vim diff --git a/bin/colortest b/bin/colortest old mode 100644 new mode 100755 diff --git a/bin/genilog.cmd b/bin/genilog.cmd deleted file mode 100644 index 740bdf7..0000000 --- a/bin/genilog.cmd +++ /dev/null @@ -1 +0,0 @@ -@call "c:\program files (x86)\python35-32\python.exe" C:\Projects\repos\grundfos\jaz\genilog\genilog.py %* diff --git a/bin/git-diffall.sh b/bin/git-diffall.sh old mode 100644 new mode 100755 index 25fdda9..2ae11ea --- a/bin/git-diffall.sh +++ b/bin/git-diffall.sh @@ -1,277 +1,277 @@ -#!/bin/sh -# Copyright 2010 - 2012, Tim Henigan -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -# Perform a directory diff between commits in the repository using -# the external diff or merge tool specified in the user's config. - -USAGE='[--cached] [--copy-back] [-x|--extcmd=] {0,2} [-- *] - - --cached Compare to the index rather than the working tree. - - --copy-back Copy files back to the working tree when the diff - tool exits (in case they were modified by the - user). This option is only valid if the diff - compared with the working tree. - - -x= - --extcmd= Specify a custom command for viewing diffs. - git-diffall ignores the configured defaults and - runs $command $LOCAL $REMOTE when this option is - specified. Additionally, $BASE is set in the - environment. -' - -SUBDIRECTORY_OK=1 -. "$(git --exec-path)/git-sh-setup" - -TOOL_MODE=diff -. "$(git --exec-path)/git-mergetool--lib" - -merge_tool="$(get_merge_tool)" -if test -z "$merge_tool" -then - echo "Error: Either the 'diff.tool' or 'merge.tool' option must be set." - usage -fi - -start_dir=$(pwd) - -# All the file paths returned by the diff command are relative to the root -# of the working copy. So if the script is called from a subdirectory, it -# must switch to the root of working copy before trying to use those paths. -cdup=$(git rev-parse --show-cdup) && -cd "$cdup" || { - echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree" - exit 1 -} - -# set up temp dir -tmp=$(perl -e 'use File::Temp qw(tempdir); - $t=tempdir("/tmp/git-diffall.XXXXX") or exit(1); - print $t') || exit 1 -#trap 'rm -rf "$tmp"' EXIT - -left= -right= -paths= -dashdash_seen= -compare_staged= -merge_base= -left_dir= -right_dir= -diff_tool= -copy_back= - -while test $# != 0 -do - case "$1" in - -h|--h|--he|--hel|--help) - usage - ;; - --cached) - compare_staged=1 - ;; - --copy-back) - copy_back=1 - ;; - -x|--e|--ex|--ext|--extc|--extcm|--extcmd) - if test $# = 1 - then - echo You must specify the tool for use with --extcmd - usage - else - diff_tool=$2 - shift - fi - ;; - --) - dashdash_seen=1 - ;; - -*) - echo Invalid option: "$1" - usage - ;; - *) - # could be commit, commit range or path limiter - case "$1" in - *...*) - left=${1%...*} - right=${1#*...} - merge_base=1 - ;; - *..*) - left=${1%..*} - right=${1#*..} - ;; - *) - if test -n "$dashdash_seen" - then - paths="$paths$1 " - elif test -z "$left" - then - left=$1 - elif test -z "$right" - then - right=$1 - else - paths="$paths$1 " - fi - ;; - esac - ;; - esac - shift -done - -# Determine the set of files which changed -if test -n "$left" && test -n "$right" -then - left_dir="cmt-$(git rev-parse --short $left)" - right_dir="cmt-$(git rev-parse --short $right)" - - if test -n "$compare_staged" - then - usage - elif test -n "$merge_base" - then - git diff --name-only "$left"..."$right" -- $paths >"$tmp/filelist" - else - git diff --name-only "$left" "$right" -- $paths >"$tmp/filelist" - fi -elif test -n "$left" -then - left_dir="cmt-$(git rev-parse --short $left)" - - if test -n "$compare_staged" - then - right_dir="staged" - git diff --name-only --cached "$left" -- $paths >"$tmp/filelist" - else - right_dir="working_tree" - git diff --name-only "$left" -- $paths >"$tmp/filelist" - fi -else - left_dir="HEAD" - - if test -n "$compare_staged" - then - right_dir="staged" - git diff --name-only --cached -- $paths >"$tmp/filelist" - else - right_dir="working_tree" - git diff --name-only -- $paths >"$tmp/filelist" - fi -fi - -# Exit immediately if there are no diffs -if test ! -s "$tmp/filelist" -then - exit 0 -fi - -if test -n "$copy_back" && test "$right_dir" != "working_tree" -then - echo "--copy-back is only valid when diff includes the working tree." - exit 1 -fi - -# Create the named tmp directories that will hold the files to be compared -mkdir -p "$tmp/$left_dir" "$tmp/$right_dir" - -# Populate the tmp/right_dir directory with the files to be compared -while read name -do - if test -n "$right" - then - ls_list=$(git ls-tree $right "$name") - if test -n "$ls_list" - then - mkdir -p "$tmp/$right_dir/$(dirname "$name")" - git show "$right":"$name" >"$tmp/$right_dir/$name" || true - fi - elif test -n "$compare_staged" - then - ls_list=$(git ls-files -- "$name") - if test -n "$ls_list" - then - mkdir -p "$tmp/$right_dir/$(dirname "$name")" - git show :"$name" >"$tmp/$right_dir/$name" - fi - else - if test -e "$name" - then - mkdir -p "$tmp/$right_dir/$(dirname "$name")" - cp "$name" "$tmp/$right_dir/$name" - fi - fi -done < "$tmp/filelist" - -# Populate the tmp/left_dir directory with the files to be compared -while read name -do - if test -n "$left" - then - ls_list=$(git ls-tree $left "$name") - if test -n "$ls_list" - then - mkdir -p "$tmp/$left_dir/$(dirname "$name")" - git show "$left":"$name" >"$tmp/$left_dir/$name" || true - fi - else - if test -n "$compare_staged" - then - ls_list=$(git ls-tree HEAD "$name") - if test -n "$ls_list" - then - mkdir -p "$tmp/$left_dir/$(dirname "$name")" - git show HEAD:"$name" >"$tmp/$left_dir/$name" - fi - else - mkdir -p "$tmp/$left_dir/$(dirname "$name")" - git show :"$name" >"$tmp/$left_dir/$name" - fi - fi -done < "$tmp/filelist" - -LOCAL="$tmp/$left_dir" -REMOTE="$tmp/$right_dir" - -if test -n "$diff_tool" -then - export BASE - eval $diff_tool '"$LOCAL"' '"$REMOTE"' -else - run_merge_tool "$merge_tool" false -fi - -# Copy files back to the working dir, if requested -if test -n "$copy_back" && test "$right_dir" = "working_tree" -then - cd "$start_dir" - git_top_dir=$(git rev-parse --show-toplevel) - find "$tmp/$right_dir" -type f | - while read file - do - cp "$file" "$git_top_dir/${file#$tmp/$right_dir/}" - done +#!/bin/sh +# Copyright 2010 - 2012, Tim Henigan +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +# Perform a directory diff between commits in the repository using +# the external diff or merge tool specified in the user's config. + +USAGE='[--cached] [--copy-back] [-x|--extcmd=] {0,2} [-- *] + + --cached Compare to the index rather than the working tree. + + --copy-back Copy files back to the working tree when the diff + tool exits (in case they were modified by the + user). This option is only valid if the diff + compared with the working tree. + + -x= + --extcmd= Specify a custom command for viewing diffs. + git-diffall ignores the configured defaults and + runs $command $LOCAL $REMOTE when this option is + specified. Additionally, $BASE is set in the + environment. +' + +SUBDIRECTORY_OK=1 +. "$(git --exec-path)/git-sh-setup" + +TOOL_MODE=diff +. "$(git --exec-path)/git-mergetool--lib" + +merge_tool="$(get_merge_tool)" +if test -z "$merge_tool" +then + echo "Error: Either the 'diff.tool' or 'merge.tool' option must be set." + usage +fi + +start_dir=$(pwd) + +# All the file paths returned by the diff command are relative to the root +# of the working copy. So if the script is called from a subdirectory, it +# must switch to the root of working copy before trying to use those paths. +cdup=$(git rev-parse --show-cdup) && +cd "$cdup" || { + echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree" + exit 1 +} + +# set up temp dir +tmp=$(perl -e 'use File::Temp qw(tempdir); + $t=tempdir("/tmp/git-diffall.XXXXX") or exit(1); + print $t') || exit 1 +#trap 'rm -rf "$tmp"' EXIT + +left= +right= +paths= +dashdash_seen= +compare_staged= +merge_base= +left_dir= +right_dir= +diff_tool= +copy_back= + +while test $# != 0 +do + case "$1" in + -h|--h|--he|--hel|--help) + usage + ;; + --cached) + compare_staged=1 + ;; + --copy-back) + copy_back=1 + ;; + -x|--e|--ex|--ext|--extc|--extcm|--extcmd) + if test $# = 1 + then + echo You must specify the tool for use with --extcmd + usage + else + diff_tool=$2 + shift + fi + ;; + --) + dashdash_seen=1 + ;; + -*) + echo Invalid option: "$1" + usage + ;; + *) + # could be commit, commit range or path limiter + case "$1" in + *...*) + left=${1%...*} + right=${1#*...} + merge_base=1 + ;; + *..*) + left=${1%..*} + right=${1#*..} + ;; + *) + if test -n "$dashdash_seen" + then + paths="$paths$1 " + elif test -z "$left" + then + left=$1 + elif test -z "$right" + then + right=$1 + else + paths="$paths$1 " + fi + ;; + esac + ;; + esac + shift +done + +# Determine the set of files which changed +if test -n "$left" && test -n "$right" +then + left_dir="cmt-$(git rev-parse --short $left)" + right_dir="cmt-$(git rev-parse --short $right)" + + if test -n "$compare_staged" + then + usage + elif test -n "$merge_base" + then + git diff --name-only "$left"..."$right" -- $paths >"$tmp/filelist" + else + git diff --name-only "$left" "$right" -- $paths >"$tmp/filelist" + fi +elif test -n "$left" +then + left_dir="cmt-$(git rev-parse --short $left)" + + if test -n "$compare_staged" + then + right_dir="staged" + git diff --name-only --cached "$left" -- $paths >"$tmp/filelist" + else + right_dir="working_tree" + git diff --name-only "$left" -- $paths >"$tmp/filelist" + fi +else + left_dir="HEAD" + + if test -n "$compare_staged" + then + right_dir="staged" + git diff --name-only --cached -- $paths >"$tmp/filelist" + else + right_dir="working_tree" + git diff --name-only -- $paths >"$tmp/filelist" + fi +fi + +# Exit immediately if there are no diffs +if test ! -s "$tmp/filelist" +then + exit 0 +fi + +if test -n "$copy_back" && test "$right_dir" != "working_tree" +then + echo "--copy-back is only valid when diff includes the working tree." + exit 1 +fi + +# Create the named tmp directories that will hold the files to be compared +mkdir -p "$tmp/$left_dir" "$tmp/$right_dir" + +# Populate the tmp/right_dir directory with the files to be compared +while read name +do + if test -n "$right" + then + ls_list=$(git ls-tree $right "$name") + if test -n "$ls_list" + then + mkdir -p "$tmp/$right_dir/$(dirname "$name")" + git show "$right":"$name" >"$tmp/$right_dir/$name" || true + fi + elif test -n "$compare_staged" + then + ls_list=$(git ls-files -- "$name") + if test -n "$ls_list" + then + mkdir -p "$tmp/$right_dir/$(dirname "$name")" + git show :"$name" >"$tmp/$right_dir/$name" + fi + else + if test -e "$name" + then + mkdir -p "$tmp/$right_dir/$(dirname "$name")" + cp "$name" "$tmp/$right_dir/$name" + fi + fi +done < "$tmp/filelist" + +# Populate the tmp/left_dir directory with the files to be compared +while read name +do + if test -n "$left" + then + ls_list=$(git ls-tree $left "$name") + if test -n "$ls_list" + then + mkdir -p "$tmp/$left_dir/$(dirname "$name")" + git show "$left":"$name" >"$tmp/$left_dir/$name" || true + fi + else + if test -n "$compare_staged" + then + ls_list=$(git ls-tree HEAD "$name") + if test -n "$ls_list" + then + mkdir -p "$tmp/$left_dir/$(dirname "$name")" + git show HEAD:"$name" >"$tmp/$left_dir/$name" + fi + else + mkdir -p "$tmp/$left_dir/$(dirname "$name")" + git show :"$name" >"$tmp/$left_dir/$name" + fi + fi +done < "$tmp/filelist" + +LOCAL="$tmp/$left_dir" +REMOTE="$tmp/$right_dir" + +if test -n "$diff_tool" +then + export BASE + eval $diff_tool '"$LOCAL"' '"$REMOTE"' +else + run_merge_tool "$merge_tool" false +fi + +# Copy files back to the working dir, if requested +if test -n "$copy_back" && test "$right_dir" = "working_tree" +then + cd "$start_dir" + git_top_dir=$(git rev-parse --show-toplevel) + find "$tmp/$right_dir" -type f | + while read file + do + cp "$file" "$git_top_dir/${file#$tmp/$right_dir/}" + done fi \ No newline at end of file diff --git a/bin/git-difftool.sh b/bin/git-difftool.sh old mode 100644 new mode 100755 index 6260e94..19fdcd5 --- a/bin/git-difftool.sh +++ b/bin/git-difftool.sh @@ -1,3 +1,3 @@ -TOOL=vimdiff -ARG=$@ -$TOOL $ARG +TOOL=vimdiff +ARG=$@ +$TOOL $ARG diff --git a/bin/git-editor.sh b/bin/git-editor.sh old mode 100644 new mode 100755 index 10932c4..0e904c2 --- a/bin/git-editor.sh +++ b/bin/git-editor.sh @@ -1,4 +1,4 @@ -#!/bin/bash -TOOL=vim -ARG=$@ -$TOOL $ARG +#!/bin/bash +TOOL=vim +ARG=$@ +$TOOL $ARG diff --git a/bin/git-mergetool.sh b/bin/git-mergetool.sh old mode 100644 new mode 100755 index 5837b55..3c1e79e --- a/bin/git-mergetool.sh +++ b/bin/git-mergetool.sh @@ -1,4 +1,4 @@ -#! /bin/bash -TOOL=vimdiff -ARG=$@ -$TOOL $ARG +#! /bin/bash +TOOL=vimdiff +ARG=$@ +$TOOL $ARG diff --git a/bin/git-review b/bin/git-review old mode 100644 new mode 100755 index 0a9a580..9c1ba04 --- a/bin/git-review +++ b/bin/git-review @@ -1,1219 +1,1219 @@ -#!/usr/bin/env python -from __future__ import print_function - -COPYRIGHT = """\ -Copyright (C) 2011-2012 OpenStack LLC. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied. - -See the License for the specific language governing permissions and -limitations under the License.""" - -import datetime -import json -import os -import re -import shlex -import subprocess -import sys -import time - -if sys.version < '3': - import ConfigParser - import urllib - import urlparse - urlopen = urllib.urlopen - urlparse = urlparse.urlparse - do_input = raw_input -else: - import configparser as ConfigParser - import urllib.parse - import urllib.request - urlopen = urllib.request.urlopen - urlparse = urllib.parse.urlparse - do_input = input - -from distutils import version as du_version - -version = "1.22" - -VERBOSE = False -UPDATE = False -CONFIGDIR = os.path.expanduser("~/.config/git-review") -GLOBAL_CONFIG = "/etc/git-review/git-review.conf" -USER_CONFIG = os.path.join(CONFIGDIR, "git-review.conf") -PYPI_URL = "http://pypi.python.org/pypi/git-review/json" -PYPI_CACHE_TIME = 60 * 60 * 24 # 24 hours -DEFAULTS = dict(hostname='gerrit.lud.stericsson.com', port='29418', project=False, - defaultbranch='master', defaultremote="gerrit", - defaultrebase="0") - -_branch_name = None -_has_color = None -_no_color_support = False - - -class colors: - yellow = '\033[33m' - green = '\033[92m' - reset = '\033[0m' - - -class GitReviewException(Exception): - pass - - -class CommandFailed(GitReviewException): - - def __init__(self, *args): - Exception.__init__(self, *args) - (self.rc, self.output, self.argv, self.envp) = args - self.quickmsg = dict([ - ("argv", " ".join(self.argv)), - ("rc", self.rc), - ("output", self.output)]) - - def __str__(self): - return self.__doc__ + """ -The following command failed with exit code %(rc)d - "%(argv)s" ------------------------ -%(output)s ------------------------""" % self.quickmsg - - -class ChangeSetException(GitReviewException): - - def __init__(self, e): - GitReviewException.__init__(self) - self.e = str(e) - - def __str__(self): - return self.__doc__ % self.e - - -def parse_review_number(review): - parts = review.split(',') - if len(parts) < 2: - parts.append(None) - return parts - - -def build_review_number(review, patchset): - if patchset is not None: - return '%s,%s' % (review, patchset) - return review - - -def run_command_status(*argv, **env): - if VERBOSE: - print(datetime.datetime.now(), "Running:", " ".join(argv)) - if len(argv) == 1: - argv = shlex.split(str(argv[0])) - newenv = os.environ - newenv.update(env) - p = subprocess.Popen(argv, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, env=newenv) - (out, nothing) = p.communicate() - out = out.decode('utf-8') - return (p.returncode, out.strip()) - - -def run_command(*argv, **env): - (rc, output) = run_command_status(*argv, **env) - return output - - -def run_command_exc(klazz, *argv, **env): - """Run command *argv, on failure raise 'klazz - - klass should be derived from CommandFailed - """ - (rc, output) = run_command_status(*argv, **env) - if rc != 0: - raise klazz(rc, output, argv, env) - return output - - -def update_latest_version(version_file_path): - """Cache the latest version of git-review for the upgrade check.""" - - if not os.path.exists(CONFIGDIR): - os.makedirs(CONFIGDIR) - - if os.path.exists(version_file_path) and not UPDATE: - if (time.time() - os.path.getmtime(version_file_path)) < 28800: - return - - latest_version = version - try: - latest_version = json.load(urlopen(PYPI_URL))['info']['version'] - except Exception: - pass - - with open(version_file_path, "w") as version_file: - version_file.write(latest_version) - - -def latest_is_newer(): - """Check if there is a new version of git-review.""" - - # Skip version check if distro package turns it off - if os.path.exists(GLOBAL_CONFIG): - config = dict(check=False) - configParser = ConfigParser.ConfigParser(config) - configParser.read(GLOBAL_CONFIG) - if not configParser.getboolean("updates", "check"): - return False - - version_file_path = os.path.join(CONFIGDIR, "latest-version") - update_latest_version(version_file_path) - - latest_version = None - with open(version_file_path, "r") as version_file: - latest_version = du_version.StrictVersion(version_file.read()) - if latest_version > du_version.StrictVersion(version): - return True - return False - - -def git_directories(): - """Determine (absolute git work directory path, .git subdirectory path).""" - cmd = ("git", "rev-parse", "--show-toplevel", "--git-dir") - out = run_command_exc(GitDirectoriesException, *cmd) - try: - return out.split() - except ValueError: - raise GitDirectoriesException(0, out, cmd, {}) - - -class GitDirectoriesException(CommandFailed): - "Cannot determine where .git directory is." - EXIT_CODE = 70 - - -class CustomScriptException(CommandFailed): - """Custom script execution failed.""" - EXIT_CODE = 71 - - -def run_custom_script(action): - """Get status and output of .git/hooks/$action-review or/and - ~/.config/hooks/$action-review if existing. - """ - returns = [] - script_file = "%s-review" % (action) - (top_dir, git_dir) = git_directories() - paths = [os.path.join(CONFIGDIR, "hooks", script_file), - os.path.join(git_dir, "hooks", script_file)] - for fpath in paths: - if os.path.isfile(fpath) and os.access(fpath, os.X_OK): - status, output = run_command_status(fpath) - returns.append((status, output, fpath)) - - for (status, output, path) in returns: - if status is not None and status != 0: - raise CustomScriptException(status, output, [path], {}) - elif output and VERBOSE: - print("script %s output is:" % (path)) - print(output) - - -def git_config_get_value(section, option, default=None): - try: - return run_command_exc(GitConfigException, - "git", "config", - "--get", - "%s.%s" % (section, option)).strip() - except GitConfigException as exc: - if exc.rc == 1: - return default - raise - - -class GitConfigException(CommandFailed): - """Git config value retrieval failed.""" - EXIT_CODE = 128 - - -class CannotInstallHook(CommandFailed): - "Problems encountered installing commit-msg hook" - EXIT_CODE = 2 - - -def set_hooks_commit_msg(remote, target_file): - """Install the commit message hook if needed.""" - - # Create the hooks directory if it's not there already - hooks_dir = os.path.dirname(target_file) - if not os.path.isdir(hooks_dir): - os.mkdir(hooks_dir) - - (hostname, username, port, project_name) = \ - parse_git_show(remote, "Push") - - if not os.path.exists(target_file) or UPDATE: - if VERBOSE: - print("Fetching commit hook from: scp://%s:%s" % (hostname, port)) - if port is not None: - port = "-P %s" % port - else: - port = "" - if username is None: - userhost = hostname - else: - userhost = "%s@%s" % (username, hostname) - run_command_exc( - CannotInstallHook, - "scp", port, - userhost + ":hooks/commit-msg", - target_file) - - if not os.access(target_file, os.X_OK): - os.chmod(target_file, os.path.stat.S_IREAD | os.path.stat.S_IEXEC) - - -def test_remote(username, hostname, port, project): - """Tests that a possible gerrit remote works.""" - - if port is not None: - port = "-p %s" % port - else: - port = "" - if username is None: - userhost = hostname - else: - userhost = "%s@%s" % (username, hostname) - - (status, ssh_output) = run_command_status( - "ssh", "-x", port, userhost, - "gerrit", "ls-projects") - - if status == 0: - if VERBOSE: - print("%s@%s:%s worked." % (username, hostname, port)) - return True - else: - if VERBOSE: - print("%s@%s:%s did not work." % (username, hostname, port)) - return False - - -def make_remote_url(username, hostname, port, project): - """Builds a gerrit remote URL.""" - if username is None: - return "ssh://%s:%s/%s" % (hostname, port, project) - else: - return "ssh://%s@%s:%s/%s" % (username, hostname, port, project) - - -def add_remote(hostname, port, project, remote): - """Adds a gerrit remote.""" - asked_for_username = False - - username = os.getenv("USERNAME") - if not username: - username = git_config_get_value("gitreview", "username") - if not username: - username = os.getenv("USER") - if port is None: - port = 29418 - - remote_url = make_remote_url(username, hostname, port, project) - if VERBOSE: - print("No remote set, testing %s" % remote_url) - if not test_remote(username, hostname, port, project): - print("Could not connect to gerrit.") - username = do_input("Enter your gerrit username: ") - remote_url = make_remote_url(username, hostname, port, project) - print("Trying again with %s" % remote_url) - if not test_remote(username, hostname, port, project): - raise Exception("Could not connect to gerrit at %s" % remote_url) - asked_for_username = True - - print("Creating a git remote called \"%s\" that maps to:" % remote) - print("\t%s" % remote_url) - cmd = "git remote add -f %s %s" % (remote, remote_url) - (status, remote_output) = run_command_status(cmd) - - if status != 0: - raise Exception("Error running %s" % cmd) - - if asked_for_username: - print() - print("This repository is now set up for use with git-review.") - print("You can set the default username for future repositories with:") - print(' git config --global --add gitreview.username "%s"' % username) - print() - - -def parse_git_show(remote, verb): - fetch_url = "" - for line in run_command("git remote show -n %s" % remote).split("\n"): - if line.strip().startswith("%s" % verb): - fetch_url = line.split()[2] - - parsed_url = urlparse(fetch_url) - project_name = parsed_url.path.lstrip("/") - if project_name.endswith(".git"): - project_name = project_name[:-4] - - hostname = parsed_url.netloc - username = None - port = parsed_url.port - - if VERBOSE: - print("Found origin %s URL:" % verb, fetch_url) - - # Workaround bug in urlparse on OSX - if parsed_url.scheme == "ssh" and parsed_url.path[:2] == "//": - hostname = parsed_url.path[2:].split("/")[0] - - if "@" in hostname: - (username, hostname) = hostname.split("@") - if ":" in hostname: - (hostname, port) = hostname.split(":") - - # Is origin an ssh location? Let's pull more info - if parsed_url.scheme == "ssh" and port is None: - port = 22 - - return (hostname, username, str(port), project_name) - - -def check_color_support(): - global _has_color - global _no_color_support - if _has_color is None: - test_command = "git log --color=never --oneline HEAD^1..HEAD" - (status, output) = run_command_status(test_command) - if status == 0: - _has_color = True - else: - _has_color = False - - if _no_color_support: - _has_color = False - - return _has_color - - -def get_config(config_file=None): - """Generate the configuration map by starting with some built-in defaults - and then loading GLOBAL_CONFIG, USER_CONFIG, and a repository-specific - .gitreview file, if they exist. In case of conflict, the configuration file - with the narrowest scope wins. - """ - config = DEFAULTS.copy() - for filename in (GLOBAL_CONFIG, USER_CONFIG, config_file): - if filename is not None and os.path.exists(filename): - config.update(load_config_file(filename)) - return config - - -def load_config_file(config_file): - """Load configuration options from a file.""" - configParser = ConfigParser.ConfigParser() - configParser.read(config_file) - options = { - 'hostname': 'host', - 'port': 'port', - 'project': 'project', - 'defaultbranch': 'defaultbranch', - 'defaultremote': 'defaultremote', - 'defaultrebase': 'defaultrebase', - } - config = {} - for config_key, option_name in options.items(): - if configParser.has_option('gerrit', option_name): - config[config_key] = configParser.get('gerrit', option_name) - return config - - -def update_remote(remote): - cmd = "git remote update %s" % remote - (status, output) = run_command_status(cmd) - if VERBOSE: - print(output) - if status != 0: - print("Problem running '%s'" % cmd) - if not VERBOSE: - print(output) - return False - return True - - -def check_remote(branch, remote, hostname, port, project): - """Check that a Gerrit Git remote repo exists, if not, set one.""" - - has_color = check_color_support() - if has_color: - color_never = "--color=never" - else: - color_never = "" - - if remote in run_command("git remote").split("\n"): - - remotes = run_command("git branch -a %s" % color_never).split("\n") - for current_remote in remotes: - if (current_remote.strip() == "remotes/%s/%s" % (remote, branch) - and not UPDATE): - return - # We have the remote, but aren't set up to fetch. Fix it - if VERBOSE: - print("Setting up gerrit branch tracking for better rebasing") - update_remote(remote) - return - - if hostname is False or port is False or project is False: - # This means there was no .gitreview file - print("No '.gitreview' file found in this repository.") - print("We don't know where your gerrit is. Please manually create ") - print("a remote named \"%s\" and try again." % remote) - sys.exit(1) - - # Gerrit remote not present, try to add it - try: - add_remote(hostname, port, project, remote) - except Exception: - print(sys.exc_info()[2]) - print("We don't know where your gerrit is. Please manually create ") - print("a remote named \"%s\" and try again." % remote) - raise - - -def rebase_changes(branch, remote, interactive=True): - - remote_branch = "remotes/%s/%s" % (remote, branch) - - if not update_remote(remote): - return False - - if interactive: - cmd = "git rebase -i %s" % remote_branch - else: - cmd = "git rebase %s" % remote_branch - - (status, output) = run_command_status(cmd, GIT_EDITOR='true') - if status != 0: - print("Errors running %s" % cmd) - if interactive: - print(output) - return False - return True - - -def undo_rebase(): - cmd = "git reset --hard ORIG_HEAD" - (status, output) = run_command_status(cmd) - if status != 0: - print("Errors running %s" % cmd) - print(output) - return False - return True - - -def get_branch_name(target_branch): - global _branch_name - if _branch_name is not None: - return _branch_name - _branch_name = None - has_color = check_color_support() - if has_color: - color_never = "--color=never" - else: - color_never = "" - for branch in run_command("git branch %s" % color_never).split("\n"): - if branch.startswith('*'): - _branch_name = branch.split()[1].strip() - if _branch_name == "(no": - _branch_name = target_branch - return _branch_name - - -def assert_one_change(remote, branch, yes, have_hook): - has_color = check_color_support() - if has_color: - color = git_config_get_value("color", "ui") - if color is None: - color = "auto" - else: - color = color.lower() - if (color == "" or color == "true"): - color = "auto" - elif color == "false": - color = "never" - elif color == "auto": - # Python is not a tty, we have to force colors - color = "always" - use_color = "--color=%s" % color - else: - use_color = "" - cmd = "git log %s --decorate --oneline HEAD --not remotes/%s/%s --" % ( - use_color, remote, branch) - (status, output) = run_command_status(cmd) - if status != 0: - print("Had trouble running %s" % cmd) - print(output) - sys.exit(1) - output_lines = len(output.split("\n")) - if output_lines == 1 and not have_hook: - print("Your change was committed before the commit hook was installed") - print("Amending the commit to add a gerrit change id") - run_command("git commit --amend", GIT_EDITOR='true') - elif output_lines == 0: - print("No changes between HEAD and %s/%s." % (remote, branch)) - print("Submitting for review would be pointless.") - sys.exit(1) - elif output_lines > 1: - if not yes: - print("You have more than one commit" - " that you are about to submit.") - print("The outstanding commits are:\n\n%s\n" % output) - print("Is this really what you meant to do?") - yes_no = do_input("Type 'yes' to confirm: ") - if yes_no.lower().strip() != "yes": - print("Aborting.") - print("Please rebase/squash your changes and try again") - sys.exit(1) - - -def use_topic(why, topic): - """Inform the user about why a particular topic has been selected.""" - if VERBOSE: - print(why % ('"%s"' % topic,)) - return topic - - -def get_topic(target_branch): - - branch_name = get_branch_name(target_branch) - - branch_parts = branch_name.split("/") - if len(branch_parts) >= 3 and branch_parts[0] == "review": - return use_topic("Using change number %s " - "for the topic of the change submitted", - "/".join(branch_parts[2:])) - - log_output = run_command("git log HEAD^1..HEAD") - bug_re = r'\b([Bb]ug|[Ll][Pp])\s*[#:]?\s*(\d+)' - - match = re.search(bug_re, log_output) - if match is not None: - return use_topic("Using bug number %s " - "for the topic of the change submitted", - "bug/%s" % match.group(2)) - - bp_re = r'\b([Bb]lue[Pp]rint|[Bb][Pp])\s*[#:]?\s*([0-9a-zA-Z-_]+)' - match = re.search(bp_re, log_output) - if match is not None: - return use_topic("Using blueprint number %s " - "for the topic of the change submitted", - "bp/%s" % match.group(2)) - - return use_topic("Using local branch name %s " - "for the topic of the change submitted", - branch_name) - - -class CannotQueryOpenChangesets(CommandFailed): - "Cannot fetch review information from gerrit" - EXIT_CODE = 32 - - -class CannotParseOpenChangesets(ChangeSetException): - "Cannot parse JSON review information from gerrit" - EXIT_CODE = 33 - - -def list_reviews(remote): - - (hostname, username, port, project_name) = \ - parse_git_show(remote, "Push") - - if port is not None: - port = "-p %s" % port - else: - port = "" - if username is None: - userhost = hostname - else: - userhost = "%s@%s" % (username, hostname) - - review_info = None - output = run_command_exc( - CannotQueryOpenChangesets, - "ssh", "-x", port, userhost, - "gerrit", "query", - "--current-patch-set --format=JSON project:%s status:open reviewer:self" % project_name) - - review_list = [] - review_field_width = {} - REVIEW_FIELDS = ('number', 'currentPatchSet', 'branch', 'subject') - FIELDS = range(0, len(REVIEW_FIELDS)) - if check_color_support(): - review_field_color = (colors.yellow, colors.yellow, colors.green, "") - color_reset = colors.reset - else: - review_field_color = ("", "", "", "") - color_reset = "" - review_field_width = [0, 0, 0, 0] - review_field_format = ["%*s", "%*s", "%*s", "%*s"] - review_field_justify = [+1, +1, +1, -1] # -1 is justify to right - - for line in output.split("\n"): - # Warnings from ssh wind up in this output - if line[0] != "{": - print(line) - continue - try: - review_info = json.loads(line) - except Exception: - if VERBOSE: - print(output) - raise(CannotParseOpenChangesets, sys.exc_info()[1]) - - if 'type' in review_info: - break - - tempPS = review_info['currentPatchSet'] - appPS = tempPS['approvals'] - appValue = '-'; - for appLine in appPS: - appBy = appLine['by'] - appUser = appBy['username'] - if appUser == username: - appValue = appLine['value'] - review_info['currentPatchSet'] = tempPS['number'] + ' ' + appValue - - review_list.append([review_info[f] for f in REVIEW_FIELDS]) - for i in FIELDS: - review_field_width[i] = max( - review_field_width[i], - len(review_info[REVIEW_FIELDS[i]]) - ) - - review_field_format = " ".join([ - review_field_color[i] + - review_field_format[i] + - color_reset - for i in FIELDS]) - - review_field_width = [ - review_field_width[i] * review_field_justify[i] - for i in FIELDS] - for review_value in review_list: - # At this point we have review_field_format - # like "%*s %*s %*s" and we need to supply - # (width1, value1, width2, value2, ...) tuple to print - # It's easy to zip() widths with actual values, - # but we need to flatten the resulting - # ((width1, value1), (width2, value2), ...) map. - formatted_fields = [] - for (width, value) in zip(review_field_width, review_value): - formatted_fields.extend([width, value]) - print(review_field_format % tuple(formatted_fields)) - print("Found %d items for review" % review_info['rowCount']) - - return 0 - - -class CannotQueryPatchSet(CommandFailed): - "Cannot query patchset information" - EXIT_CODE = 34 - - -class ReviewInformationNotFound(ChangeSetException): - "Could not fetch review information for change %s" - EXIT_CODE = 35 - - -class ReviewNotFound(ChangeSetException): - "Gerrit review %s not found" - EXIT_CODE = 36 - - -class PatchSetGitFetchFailed(CommandFailed): - """Cannot fetch patchset contents - -Does specified change number belong to this project? -""" - EXIT_CODE = 37 - - -class PatchSetNotFound(ChangeSetException): - "Review patchset %s not found" - EXIT_CODE = 38 - - -class CheckoutNewBranchFailed(CommandFailed): - "Cannot checkout to new branch" - EXIT_CODE = 64 - - -class CheckoutExistingBranchFailed(CommandFailed): - "Cannot checkout existing branch" - EXIT_CODE = 65 - - -class ResetHardFailed(CommandFailed): - "Failed to hard reset downloaded branch" - EXIT_CODE = 66 - - -def fetch_review(review, masterbranch, remote): - - (hostname, username, port, project_name) = \ - parse_git_show(remote, "Push") - - if port is not None: - port = "-p %s" % port - else: - port = "" - if username is None: - userhost = hostname - else: - userhost = "%s@%s" % (username, hostname) - - review_arg = review - patchset_opt = '--current-patch-set' - - review, patchset_number = parse_review_number(review) - if patchset_number is not None: - patchset_opt = '--patch-sets' - - review_info = None - output = run_command_exc( - CannotQueryPatchSet, - "ssh", "-x", port, userhost, - "gerrit", "query", - "--format=JSON %s change:%s" % (patchset_opt, review)) - - review_jsons = output.split("\n") - found_review = False - for review_json in review_jsons: - try: - review_info = json.loads(review_json) - found_review = True - except Exception: - pass - if found_review: - break - if not found_review: - if VERBOSE: - print(output) - raise ReviewInformationNotFound(review) - - try: - if patchset_number is None: - refspec = review_info['currentPatchSet']['ref'] - else: - refspec = [ps for ps - in review_info['patchSets'] - if ps['number'] == patchset_number][0]['ref'] - except IndexError: - raise PatchSetNotFound(review_arg) - except KeyError: - raise ReviewNotFound(review) - - try: - topic = review_info['topic'] - if topic == masterbranch: - topic = review - except KeyError: - topic = review - try: - author = re.sub('\W+', '_', review_info['owner']['name']).lower() - except KeyError: - author = 'unknown' - - if patchset_number is None: - branch_name = "review/%s/%s" % (author, topic) - else: - branch_name = "review/%s/%s-patch%s" % (author, topic, patchset_number) - - print("Downloading %s from gerrit" % refspec) - run_command_exc(PatchSetGitFetchFailed, - "git", "fetch", remote, refspec) - return branch_name - - -def checkout_review(branch_name): - """Checkout a newly fetched (FETCH_HEAD) change - into a branch - """ - - try: - run_command_exc(CheckoutNewBranchFailed, - "git", "checkout", "-b", - branch_name, "FETCH_HEAD") - - except CheckoutNewBranchFailed as e: - if re.search("already exists\.?", e.output): - print("Branch already exists - reusing") - run_command_exc(CheckoutExistingBranchFailed, - "git", "checkout", branch_name) - run_command_exc(ResetHardFailed, - "git", "reset", "--hard", "FETCH_HEAD") - else: - raise - - print("Switched to branch \"%s\"" % branch_name) - - -class PatchSetGitCherrypickFailed(CommandFailed): - "There was a problem applying changeset contents to the current branch." - EXIT_CODE = 69 - - -def cherrypick_review(option=None): - cmd = ["git", "cherry-pick"] - if option: - cmd.append(option) - cmd.append("FETCH_HEAD") - print(run_command_exc(PatchSetGitCherrypickFailed, *cmd)) - - -class CheckoutBackExistingBranchFailed(CommandFailed): - "Cannot switch back to existing branch" - EXIT_CODE = 67 - - -class DeleteBranchFailed(CommandFailed): - "Failed to delete branch" - EXIT_CODE = 68 - - -class InvalidPatchsetsToCompare(GitReviewException): - def __init__(self, patchsetA, patchsetB): - Exception.__init__( - self, - "Invalid patchsets for comparison specified (old=%s,new=%s)" % ( - patchsetA, - patchsetB)) - EXIT_CODE = 39 - - -def compare_review(review_spec, branch, remote, rebase=False): - new_ps = None # none means latest - - if '-' in review_spec: - review_spec, new_ps = review_spec.split('-') - review, old_ps = parse_review_number(review_spec) - - if old_ps is None or old_ps == new_ps: - raise InvalidPatchsetsToCompare(old_ps, new_ps) - - old_review = build_review_number(review, old_ps) - new_review = build_review_number(review, new_ps) - - old_branch = fetch_review(old_review, branch, remote) - checkout_review(old_branch) - - if rebase: - print('Rebasing %s' % old_branch) - rebase = rebase_changes(branch, remote, False) - if not rebase: - print('Skipping rebase because of conflicts') - run_command_exc(CommandFailed, 'git', 'rebase', '--abort') - - new_branch = fetch_review(new_review, branch, remote) - checkout_review(new_branch) - - if rebase: - print('Rebasing also %s' % new_branch) - if not rebase_changes(branch, remote, False): - print("Rebasing of the new branch failed, " - "diff can be messed up (use -R to not rebase at all)!") - run_command_exc(CommandFailed, 'git', 'rebase', '--abort') - - subprocess.check_call(['git', 'difftool', old_branch]) - - -def finish_branch(target_branch): - local_branch = get_branch_name(target_branch) - if VERBOSE: - print("Switching back to '%s' and deleting '%s'" % (target_branch, - local_branch)) - run_command_exc(CheckoutBackExistingBranchFailed, - "git", "checkout", target_branch) - print("Switched to branch '%s'" % target_branch) - - run_command_exc(DeleteBranchFailed, - "git", "branch", "-D", local_branch) - print("Deleted branch '%s'" % local_branch) - - -def convert_bool(one_or_zero): - "Return a bool on a one or zero string." - return one_or_zero in ["1", "true", "True"] - - -def print_exit_message(status, needs_update): - - if needs_update: - print(""" -*********************************************************** -A new version of git-review is available on PyPI. Please -update your copy with: - - pip install -U git-review - -to ensure proper behavior with gerrit. Thanks! -*********************************************************** -""") - sys.exit(status) - - -def main(): - global _no_color_support - usage = "git review [OPTIONS] ... [BRANCH]" - - import argparse - - class DownloadFlag(argparse.Action): - """Additional option parsing: store value in 'dest', but - at the same time set one of the flag options to True - """ - def __call__(self, parser, namespace, values, option_string=None): - setattr(namespace, self.dest, values) - setattr(namespace, self.const, True) - - parser = argparse.ArgumentParser(usage=usage, description=COPYRIGHT) - - parser.add_argument("-t", "--topic", dest="topic", - help="Topic to submit branch to") - parser.add_argument("-D", "--draft", dest="draft", action="store_true", - help="Submit review as a draft") - parser.add_argument("-c", "--compatible", dest="compatible", - action="store_true", - help="Push change to refs/for/* for compatibility " - "with Gerrit versions < 2.3. Ignored if " - "-D/--draft is used.") - parser.add_argument("-n", "--dry-run", dest="dry", action="store_true", - help="Don't actually submit the branch for review") - parser.add_argument("-i", "--new-changeid", dest="regenerate", - action="store_true", - help="Regenerate Change-id before submitting") - parser.add_argument("-r", "--remote", dest="remote", - help="git remote to use for gerrit") - parser.add_argument("-R", "--no-rebase", dest="rebase", - action="store_false", - help="Don't rebase changes before submitting.") - parser.add_argument("-F", "--force-rebase", dest="force_rebase", - action="store_true", - help="Force rebase even when not needed.") - parser.add_argument("-B", "--no-color", dest="no_color_support", - action="store_true", - help="No color support.") - - - fetch = parser.add_mutually_exclusive_group() - fetch.set_defaults(download=False, compare=False, cherrypickcommit=False, - cherrypickindicate=False, cherrypickonly=False) - fetch.add_argument("-d", "--download", dest="changeidentifier", - action=DownloadFlag, metavar="CHANGE", - const="download", - help="Download the contents of an existing gerrit " - "review into a branch") - fetch.add_argument("-x", "--cherrypick", dest="changeidentifier", - action=DownloadFlag, metavar="CHANGE", - const="cherrypickcommit", - help="Apply the contents of an existing gerrit " - "review onto the current branch and commit " - "(cherry pick; not recommended in most " - "situations)") - fetch.add_argument("-X", "--cherrypickindicate", dest="changeidentifier", - action=DownloadFlag, metavar="CHANGE", - const="cherrypickindicate", - help="Apply the contents of an existing gerrit " - "review onto the current branch and commit, " - "indicating its origin") - fetch.add_argument("-N", "--cherrypickonly", dest="changeidentifier", - action=DownloadFlag, metavar="CHANGE", - const="cherrypickonly", - help="Apply the contents of an existing gerrit " - "review to the working directory and prepare " - "for commit") - fetch.add_argument("-m", "--compare", dest="changeidentifier", - action=DownloadFlag, metavar="CHANGE,PS[-NEW_PS]", - const="compare", - help="Download specified and latest (or NEW_PS) " - "patchsets of an existing gerrit review into " - "a branches, rebase on master " - "(skipped on conflicts or when -R is specified) " - "and show their differences") - - parser.add_argument("-u", "--update", dest="update", action="store_true", - help="Force updates from remote locations") - parser.add_argument("-s", "--setup", dest="setup", action="store_true", - help="Just run the repo setup commands but don't " - "submit anything") - parser.add_argument("-f", "--finish", dest="finish", action="store_true", - help="Close down this branch and switch back to " - "master on successful submission") - parser.add_argument("-l", "--list", dest="list", action="store_true", - help="List available reviews for the current project") - parser.add_argument("-y", "--yes", dest="yes", action="store_true", - help="Indicate that you do, in fact, understand if " - "you are submitting more than one patch") - parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", - help="Output more information about what's going on") - parser.add_argument("--no-custom-script", dest="custom_script", - action="store_false", default=True, - help="Do not run custom scripts.") - parser.add_argument("--license", dest="license", action="store_true", - help="Print the license and exit") - parser.add_argument("--version", action="version", - version='%s version %s' % - (os.path.split(sys.argv[0])[-1], version)) - parser.add_argument("branch", nargs="?") - - try: - (top_dir, git_dir) = git_directories() - except GitDirectoriesException: - if sys.argv[1:] in ([], ['-h'], ['--help']): - parser.print_help() - sys.exit(1) - raise - -# config = get_config(os.path.join(top_dir, ".gitreview")) - config = DEFAULTS.copy() - cur_proj = run_command("git remote -v") - import re - m = re.search('(?<=29418\/)(\S+)', cur_proj) - config['project'] = m.group(0) - - - defaultrebase = convert_bool( - git_config_get_value("gitreview", "rebase", - default=str(config['defaultrebase']))) - parser.set_defaults(dry=False, - draft=False, - rebase=defaultrebase, - verbose=False, - update=False, - setup=False, - list=False, - yes=False, - branch=config['defaultbranch'], - remote=config['defaultremote']) - options = parser.parse_args() - - if options.license: - print(COPYRIGHT) - sys.exit(0) - - branch = options.branch - global VERBOSE - global UPDATE - VERBOSE = options.verbose - UPDATE = options.update - remote = options.remote - yes = options.yes - status = 0 - - needs_update = latest_is_newer() - check_remote(branch, remote, - config['hostname'], config['port'], config['project']) - - if options.no_color_support: - _no_color_support = True - - if options.changeidentifier: - if options.compare: - compare_review(options.changeidentifier, - branch, remote, options.rebase) - return - local_branch = fetch_review(options.changeidentifier, branch, remote) - if options.download: - checkout_review(local_branch) - else: - if options.cherrypickcommit: - cherrypick_review() - elif options.cherrypickonly: - cherrypick_review("-n") - if options.cherrypickindicate: - cherrypick_review("-x") - return - elif options.list: - list_reviews(remote) - return - - if options.custom_script: - run_custom_script("pre") - - hook_file = os.path.join(git_dir, "hooks", "commit-msg") - have_hook = os.path.exists(hook_file) and os.access(hook_file, os.X_OK) - - if not have_hook: - set_hooks_commit_msg(remote, hook_file) - - if options.setup: - if options.finish and not options.dry: - finish_branch(branch) - return - - if options.rebase: - if not rebase_changes(branch, remote): - print_exit_message(1, needs_update) - if not options.force_rebase and not undo_rebase(): - print_exit_message(1, needs_update) - assert_one_change(remote, branch, yes, have_hook) - - ref = "publish" - - if options.draft: - ref = "drafts" - if options.custom_script: - run_custom_script("draft") - elif options.compatible: - ref = "for" - - cmd = "git push %s HEAD:refs/%s/%s" % (remote, ref, branch) - topic = options.topic or get_topic(branch) - if topic != branch: - cmd += "/%s" % topic - if options.regenerate: - print("Amending the commit to regenerate the change id\n") - regenerate_cmd = "git commit --amend" - if options.dry: - print("\tGIT_EDITOR=\"sed -i -e '/^Change-Id:/d'\" %s\n" % - regenerate_cmd) - else: - run_command(regenerate_cmd, - GIT_EDITOR="sed -i -e " - "'/^Change-Id:/d'") - - if options.dry: - print("Please use the following command " - "to send your commits to review:\n") - print("\t%s\n" % cmd) - else: - (status, output) = run_command_status(cmd) - print(output) - - if options.finish and not options.dry and status == 0: - finish_branch(branch) - return - - if options.custom_script: - run_custom_script("post") - print_exit_message(status, needs_update) - - -if __name__ == "__main__": - try: - main() - except GitReviewException as e: - print(e) - sys.exit(e.EXIT_CODE) +#!/usr/bin/env python +from __future__ import print_function + +COPYRIGHT = """\ +Copyright (C) 2011-2012 OpenStack LLC. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. + +See the License for the specific language governing permissions and +limitations under the License.""" + +import datetime +import json +import os +import re +import shlex +import subprocess +import sys +import time + +if sys.version < '3': + import ConfigParser + import urllib + import urlparse + urlopen = urllib.urlopen + urlparse = urlparse.urlparse + do_input = raw_input +else: + import configparser as ConfigParser + import urllib.parse + import urllib.request + urlopen = urllib.request.urlopen + urlparse = urllib.parse.urlparse + do_input = input + +from distutils import version as du_version + +version = "1.22" + +VERBOSE = False +UPDATE = False +CONFIGDIR = os.path.expanduser("~/.config/git-review") +GLOBAL_CONFIG = "/etc/git-review/git-review.conf" +USER_CONFIG = os.path.join(CONFIGDIR, "git-review.conf") +PYPI_URL = "http://pypi.python.org/pypi/git-review/json" +PYPI_CACHE_TIME = 60 * 60 * 24 # 24 hours +DEFAULTS = dict(hostname='gerrit.lud.stericsson.com', port='29418', project=False, + defaultbranch='master', defaultremote="gerrit", + defaultrebase="0") + +_branch_name = None +_has_color = None +_no_color_support = False + + +class colors: + yellow = '\033[33m' + green = '\033[92m' + reset = '\033[0m' + + +class GitReviewException(Exception): + pass + + +class CommandFailed(GitReviewException): + + def __init__(self, *args): + Exception.__init__(self, *args) + (self.rc, self.output, self.argv, self.envp) = args + self.quickmsg = dict([ + ("argv", " ".join(self.argv)), + ("rc", self.rc), + ("output", self.output)]) + + def __str__(self): + return self.__doc__ + """ +The following command failed with exit code %(rc)d + "%(argv)s" +----------------------- +%(output)s +-----------------------""" % self.quickmsg + + +class ChangeSetException(GitReviewException): + + def __init__(self, e): + GitReviewException.__init__(self) + self.e = str(e) + + def __str__(self): + return self.__doc__ % self.e + + +def parse_review_number(review): + parts = review.split(',') + if len(parts) < 2: + parts.append(None) + return parts + + +def build_review_number(review, patchset): + if patchset is not None: + return '%s,%s' % (review, patchset) + return review + + +def run_command_status(*argv, **env): + if VERBOSE: + print(datetime.datetime.now(), "Running:", " ".join(argv)) + if len(argv) == 1: + argv = shlex.split(str(argv[0])) + newenv = os.environ + newenv.update(env) + p = subprocess.Popen(argv, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, env=newenv) + (out, nothing) = p.communicate() + out = out.decode('utf-8') + return (p.returncode, out.strip()) + + +def run_command(*argv, **env): + (rc, output) = run_command_status(*argv, **env) + return output + + +def run_command_exc(klazz, *argv, **env): + """Run command *argv, on failure raise 'klazz + + klass should be derived from CommandFailed + """ + (rc, output) = run_command_status(*argv, **env) + if rc != 0: + raise klazz(rc, output, argv, env) + return output + + +def update_latest_version(version_file_path): + """Cache the latest version of git-review for the upgrade check.""" + + if not os.path.exists(CONFIGDIR): + os.makedirs(CONFIGDIR) + + if os.path.exists(version_file_path) and not UPDATE: + if (time.time() - os.path.getmtime(version_file_path)) < 28800: + return + + latest_version = version + try: + latest_version = json.load(urlopen(PYPI_URL))['info']['version'] + except Exception: + pass + + with open(version_file_path, "w") as version_file: + version_file.write(latest_version) + + +def latest_is_newer(): + """Check if there is a new version of git-review.""" + + # Skip version check if distro package turns it off + if os.path.exists(GLOBAL_CONFIG): + config = dict(check=False) + configParser = ConfigParser.ConfigParser(config) + configParser.read(GLOBAL_CONFIG) + if not configParser.getboolean("updates", "check"): + return False + + version_file_path = os.path.join(CONFIGDIR, "latest-version") + update_latest_version(version_file_path) + + latest_version = None + with open(version_file_path, "r") as version_file: + latest_version = du_version.StrictVersion(version_file.read()) + if latest_version > du_version.StrictVersion(version): + return True + return False + + +def git_directories(): + """Determine (absolute git work directory path, .git subdirectory path).""" + cmd = ("git", "rev-parse", "--show-toplevel", "--git-dir") + out = run_command_exc(GitDirectoriesException, *cmd) + try: + return out.split() + except ValueError: + raise GitDirectoriesException(0, out, cmd, {}) + + +class GitDirectoriesException(CommandFailed): + "Cannot determine where .git directory is." + EXIT_CODE = 70 + + +class CustomScriptException(CommandFailed): + """Custom script execution failed.""" + EXIT_CODE = 71 + + +def run_custom_script(action): + """Get status and output of .git/hooks/$action-review or/and + ~/.config/hooks/$action-review if existing. + """ + returns = [] + script_file = "%s-review" % (action) + (top_dir, git_dir) = git_directories() + paths = [os.path.join(CONFIGDIR, "hooks", script_file), + os.path.join(git_dir, "hooks", script_file)] + for fpath in paths: + if os.path.isfile(fpath) and os.access(fpath, os.X_OK): + status, output = run_command_status(fpath) + returns.append((status, output, fpath)) + + for (status, output, path) in returns: + if status is not None and status != 0: + raise CustomScriptException(status, output, [path], {}) + elif output and VERBOSE: + print("script %s output is:" % (path)) + print(output) + + +def git_config_get_value(section, option, default=None): + try: + return run_command_exc(GitConfigException, + "git", "config", + "--get", + "%s.%s" % (section, option)).strip() + except GitConfigException as exc: + if exc.rc == 1: + return default + raise + + +class GitConfigException(CommandFailed): + """Git config value retrieval failed.""" + EXIT_CODE = 128 + + +class CannotInstallHook(CommandFailed): + "Problems encountered installing commit-msg hook" + EXIT_CODE = 2 + + +def set_hooks_commit_msg(remote, target_file): + """Install the commit message hook if needed.""" + + # Create the hooks directory if it's not there already + hooks_dir = os.path.dirname(target_file) + if not os.path.isdir(hooks_dir): + os.mkdir(hooks_dir) + + (hostname, username, port, project_name) = \ + parse_git_show(remote, "Push") + + if not os.path.exists(target_file) or UPDATE: + if VERBOSE: + print("Fetching commit hook from: scp://%s:%s" % (hostname, port)) + if port is not None: + port = "-P %s" % port + else: + port = "" + if username is None: + userhost = hostname + else: + userhost = "%s@%s" % (username, hostname) + run_command_exc( + CannotInstallHook, + "scp", port, + userhost + ":hooks/commit-msg", + target_file) + + if not os.access(target_file, os.X_OK): + os.chmod(target_file, os.path.stat.S_IREAD | os.path.stat.S_IEXEC) + + +def test_remote(username, hostname, port, project): + """Tests that a possible gerrit remote works.""" + + if port is not None: + port = "-p %s" % port + else: + port = "" + if username is None: + userhost = hostname + else: + userhost = "%s@%s" % (username, hostname) + + (status, ssh_output) = run_command_status( + "ssh", "-x", port, userhost, + "gerrit", "ls-projects") + + if status == 0: + if VERBOSE: + print("%s@%s:%s worked." % (username, hostname, port)) + return True + else: + if VERBOSE: + print("%s@%s:%s did not work." % (username, hostname, port)) + return False + + +def make_remote_url(username, hostname, port, project): + """Builds a gerrit remote URL.""" + if username is None: + return "ssh://%s:%s/%s" % (hostname, port, project) + else: + return "ssh://%s@%s:%s/%s" % (username, hostname, port, project) + + +def add_remote(hostname, port, project, remote): + """Adds a gerrit remote.""" + asked_for_username = False + + username = os.getenv("USERNAME") + if not username: + username = git_config_get_value("gitreview", "username") + if not username: + username = os.getenv("USER") + if port is None: + port = 29418 + + remote_url = make_remote_url(username, hostname, port, project) + if VERBOSE: + print("No remote set, testing %s" % remote_url) + if not test_remote(username, hostname, port, project): + print("Could not connect to gerrit.") + username = do_input("Enter your gerrit username: ") + remote_url = make_remote_url(username, hostname, port, project) + print("Trying again with %s" % remote_url) + if not test_remote(username, hostname, port, project): + raise Exception("Could not connect to gerrit at %s" % remote_url) + asked_for_username = True + + print("Creating a git remote called \"%s\" that maps to:" % remote) + print("\t%s" % remote_url) + cmd = "git remote add -f %s %s" % (remote, remote_url) + (status, remote_output) = run_command_status(cmd) + + if status != 0: + raise Exception("Error running %s" % cmd) + + if asked_for_username: + print() + print("This repository is now set up for use with git-review.") + print("You can set the default username for future repositories with:") + print(' git config --global --add gitreview.username "%s"' % username) + print() + + +def parse_git_show(remote, verb): + fetch_url = "" + for line in run_command("git remote show -n %s" % remote).split("\n"): + if line.strip().startswith("%s" % verb): + fetch_url = line.split()[2] + + parsed_url = urlparse(fetch_url) + project_name = parsed_url.path.lstrip("/") + if project_name.endswith(".git"): + project_name = project_name[:-4] + + hostname = parsed_url.netloc + username = None + port = parsed_url.port + + if VERBOSE: + print("Found origin %s URL:" % verb, fetch_url) + + # Workaround bug in urlparse on OSX + if parsed_url.scheme == "ssh" and parsed_url.path[:2] == "//": + hostname = parsed_url.path[2:].split("/")[0] + + if "@" in hostname: + (username, hostname) = hostname.split("@") + if ":" in hostname: + (hostname, port) = hostname.split(":") + + # Is origin an ssh location? Let's pull more info + if parsed_url.scheme == "ssh" and port is None: + port = 22 + + return (hostname, username, str(port), project_name) + + +def check_color_support(): + global _has_color + global _no_color_support + if _has_color is None: + test_command = "git log --color=never --oneline HEAD^1..HEAD" + (status, output) = run_command_status(test_command) + if status == 0: + _has_color = True + else: + _has_color = False + + if _no_color_support: + _has_color = False + + return _has_color + + +def get_config(config_file=None): + """Generate the configuration map by starting with some built-in defaults + and then loading GLOBAL_CONFIG, USER_CONFIG, and a repository-specific + .gitreview file, if they exist. In case of conflict, the configuration file + with the narrowest scope wins. + """ + config = DEFAULTS.copy() + for filename in (GLOBAL_CONFIG, USER_CONFIG, config_file): + if filename is not None and os.path.exists(filename): + config.update(load_config_file(filename)) + return config + + +def load_config_file(config_file): + """Load configuration options from a file.""" + configParser = ConfigParser.ConfigParser() + configParser.read(config_file) + options = { + 'hostname': 'host', + 'port': 'port', + 'project': 'project', + 'defaultbranch': 'defaultbranch', + 'defaultremote': 'defaultremote', + 'defaultrebase': 'defaultrebase', + } + config = {} + for config_key, option_name in options.items(): + if configParser.has_option('gerrit', option_name): + config[config_key] = configParser.get('gerrit', option_name) + return config + + +def update_remote(remote): + cmd = "git remote update %s" % remote + (status, output) = run_command_status(cmd) + if VERBOSE: + print(output) + if status != 0: + print("Problem running '%s'" % cmd) + if not VERBOSE: + print(output) + return False + return True + + +def check_remote(branch, remote, hostname, port, project): + """Check that a Gerrit Git remote repo exists, if not, set one.""" + + has_color = check_color_support() + if has_color: + color_never = "--color=never" + else: + color_never = "" + + if remote in run_command("git remote").split("\n"): + + remotes = run_command("git branch -a %s" % color_never).split("\n") + for current_remote in remotes: + if (current_remote.strip() == "remotes/%s/%s" % (remote, branch) + and not UPDATE): + return + # We have the remote, but aren't set up to fetch. Fix it + if VERBOSE: + print("Setting up gerrit branch tracking for better rebasing") + update_remote(remote) + return + + if hostname is False or port is False or project is False: + # This means there was no .gitreview file + print("No '.gitreview' file found in this repository.") + print("We don't know where your gerrit is. Please manually create ") + print("a remote named \"%s\" and try again." % remote) + sys.exit(1) + + # Gerrit remote not present, try to add it + try: + add_remote(hostname, port, project, remote) + except Exception: + print(sys.exc_info()[2]) + print("We don't know where your gerrit is. Please manually create ") + print("a remote named \"%s\" and try again." % remote) + raise + + +def rebase_changes(branch, remote, interactive=True): + + remote_branch = "remotes/%s/%s" % (remote, branch) + + if not update_remote(remote): + return False + + if interactive: + cmd = "git rebase -i %s" % remote_branch + else: + cmd = "git rebase %s" % remote_branch + + (status, output) = run_command_status(cmd, GIT_EDITOR='true') + if status != 0: + print("Errors running %s" % cmd) + if interactive: + print(output) + return False + return True + + +def undo_rebase(): + cmd = "git reset --hard ORIG_HEAD" + (status, output) = run_command_status(cmd) + if status != 0: + print("Errors running %s" % cmd) + print(output) + return False + return True + + +def get_branch_name(target_branch): + global _branch_name + if _branch_name is not None: + return _branch_name + _branch_name = None + has_color = check_color_support() + if has_color: + color_never = "--color=never" + else: + color_never = "" + for branch in run_command("git branch %s" % color_never).split("\n"): + if branch.startswith('*'): + _branch_name = branch.split()[1].strip() + if _branch_name == "(no": + _branch_name = target_branch + return _branch_name + + +def assert_one_change(remote, branch, yes, have_hook): + has_color = check_color_support() + if has_color: + color = git_config_get_value("color", "ui") + if color is None: + color = "auto" + else: + color = color.lower() + if (color == "" or color == "true"): + color = "auto" + elif color == "false": + color = "never" + elif color == "auto": + # Python is not a tty, we have to force colors + color = "always" + use_color = "--color=%s" % color + else: + use_color = "" + cmd = "git log %s --decorate --oneline HEAD --not remotes/%s/%s --" % ( + use_color, remote, branch) + (status, output) = run_command_status(cmd) + if status != 0: + print("Had trouble running %s" % cmd) + print(output) + sys.exit(1) + output_lines = len(output.split("\n")) + if output_lines == 1 and not have_hook: + print("Your change was committed before the commit hook was installed") + print("Amending the commit to add a gerrit change id") + run_command("git commit --amend", GIT_EDITOR='true') + elif output_lines == 0: + print("No changes between HEAD and %s/%s." % (remote, branch)) + print("Submitting for review would be pointless.") + sys.exit(1) + elif output_lines > 1: + if not yes: + print("You have more than one commit" + " that you are about to submit.") + print("The outstanding commits are:\n\n%s\n" % output) + print("Is this really what you meant to do?") + yes_no = do_input("Type 'yes' to confirm: ") + if yes_no.lower().strip() != "yes": + print("Aborting.") + print("Please rebase/squash your changes and try again") + sys.exit(1) + + +def use_topic(why, topic): + """Inform the user about why a particular topic has been selected.""" + if VERBOSE: + print(why % ('"%s"' % topic,)) + return topic + + +def get_topic(target_branch): + + branch_name = get_branch_name(target_branch) + + branch_parts = branch_name.split("/") + if len(branch_parts) >= 3 and branch_parts[0] == "review": + return use_topic("Using change number %s " + "for the topic of the change submitted", + "/".join(branch_parts[2:])) + + log_output = run_command("git log HEAD^1..HEAD") + bug_re = r'\b([Bb]ug|[Ll][Pp])\s*[#:]?\s*(\d+)' + + match = re.search(bug_re, log_output) + if match is not None: + return use_topic("Using bug number %s " + "for the topic of the change submitted", + "bug/%s" % match.group(2)) + + bp_re = r'\b([Bb]lue[Pp]rint|[Bb][Pp])\s*[#:]?\s*([0-9a-zA-Z-_]+)' + match = re.search(bp_re, log_output) + if match is not None: + return use_topic("Using blueprint number %s " + "for the topic of the change submitted", + "bp/%s" % match.group(2)) + + return use_topic("Using local branch name %s " + "for the topic of the change submitted", + branch_name) + + +class CannotQueryOpenChangesets(CommandFailed): + "Cannot fetch review information from gerrit" + EXIT_CODE = 32 + + +class CannotParseOpenChangesets(ChangeSetException): + "Cannot parse JSON review information from gerrit" + EXIT_CODE = 33 + + +def list_reviews(remote): + + (hostname, username, port, project_name) = \ + parse_git_show(remote, "Push") + + if port is not None: + port = "-p %s" % port + else: + port = "" + if username is None: + userhost = hostname + else: + userhost = "%s@%s" % (username, hostname) + + review_info = None + output = run_command_exc( + CannotQueryOpenChangesets, + "ssh", "-x", port, userhost, + "gerrit", "query", + "--current-patch-set --format=JSON project:%s status:open reviewer:self" % project_name) + + review_list = [] + review_field_width = {} + REVIEW_FIELDS = ('number', 'currentPatchSet', 'branch', 'subject') + FIELDS = range(0, len(REVIEW_FIELDS)) + if check_color_support(): + review_field_color = (colors.yellow, colors.yellow, colors.green, "") + color_reset = colors.reset + else: + review_field_color = ("", "", "", "") + color_reset = "" + review_field_width = [0, 0, 0, 0] + review_field_format = ["%*s", "%*s", "%*s", "%*s"] + review_field_justify = [+1, +1, +1, -1] # -1 is justify to right + + for line in output.split("\n"): + # Warnings from ssh wind up in this output + if line[0] != "{": + print(line) + continue + try: + review_info = json.loads(line) + except Exception: + if VERBOSE: + print(output) + raise(CannotParseOpenChangesets, sys.exc_info()[1]) + + if 'type' in review_info: + break + + tempPS = review_info['currentPatchSet'] + appPS = tempPS['approvals'] + appValue = '-'; + for appLine in appPS: + appBy = appLine['by'] + appUser = appBy['username'] + if appUser == username: + appValue = appLine['value'] + review_info['currentPatchSet'] = tempPS['number'] + ' ' + appValue + + review_list.append([review_info[f] for f in REVIEW_FIELDS]) + for i in FIELDS: + review_field_width[i] = max( + review_field_width[i], + len(review_info[REVIEW_FIELDS[i]]) + ) + + review_field_format = " ".join([ + review_field_color[i] + + review_field_format[i] + + color_reset + for i in FIELDS]) + + review_field_width = [ + review_field_width[i] * review_field_justify[i] + for i in FIELDS] + for review_value in review_list: + # At this point we have review_field_format + # like "%*s %*s %*s" and we need to supply + # (width1, value1, width2, value2, ...) tuple to print + # It's easy to zip() widths with actual values, + # but we need to flatten the resulting + # ((width1, value1), (width2, value2), ...) map. + formatted_fields = [] + for (width, value) in zip(review_field_width, review_value): + formatted_fields.extend([width, value]) + print(review_field_format % tuple(formatted_fields)) + print("Found %d items for review" % review_info['rowCount']) + + return 0 + + +class CannotQueryPatchSet(CommandFailed): + "Cannot query patchset information" + EXIT_CODE = 34 + + +class ReviewInformationNotFound(ChangeSetException): + "Could not fetch review information for change %s" + EXIT_CODE = 35 + + +class ReviewNotFound(ChangeSetException): + "Gerrit review %s not found" + EXIT_CODE = 36 + + +class PatchSetGitFetchFailed(CommandFailed): + """Cannot fetch patchset contents + +Does specified change number belong to this project? +""" + EXIT_CODE = 37 + + +class PatchSetNotFound(ChangeSetException): + "Review patchset %s not found" + EXIT_CODE = 38 + + +class CheckoutNewBranchFailed(CommandFailed): + "Cannot checkout to new branch" + EXIT_CODE = 64 + + +class CheckoutExistingBranchFailed(CommandFailed): + "Cannot checkout existing branch" + EXIT_CODE = 65 + + +class ResetHardFailed(CommandFailed): + "Failed to hard reset downloaded branch" + EXIT_CODE = 66 + + +def fetch_review(review, masterbranch, remote): + + (hostname, username, port, project_name) = \ + parse_git_show(remote, "Push") + + if port is not None: + port = "-p %s" % port + else: + port = "" + if username is None: + userhost = hostname + else: + userhost = "%s@%s" % (username, hostname) + + review_arg = review + patchset_opt = '--current-patch-set' + + review, patchset_number = parse_review_number(review) + if patchset_number is not None: + patchset_opt = '--patch-sets' + + review_info = None + output = run_command_exc( + CannotQueryPatchSet, + "ssh", "-x", port, userhost, + "gerrit", "query", + "--format=JSON %s change:%s" % (patchset_opt, review)) + + review_jsons = output.split("\n") + found_review = False + for review_json in review_jsons: + try: + review_info = json.loads(review_json) + found_review = True + except Exception: + pass + if found_review: + break + if not found_review: + if VERBOSE: + print(output) + raise ReviewInformationNotFound(review) + + try: + if patchset_number is None: + refspec = review_info['currentPatchSet']['ref'] + else: + refspec = [ps for ps + in review_info['patchSets'] + if ps['number'] == patchset_number][0]['ref'] + except IndexError: + raise PatchSetNotFound(review_arg) + except KeyError: + raise ReviewNotFound(review) + + try: + topic = review_info['topic'] + if topic == masterbranch: + topic = review + except KeyError: + topic = review + try: + author = re.sub('\W+', '_', review_info['owner']['name']).lower() + except KeyError: + author = 'unknown' + + if patchset_number is None: + branch_name = "review/%s/%s" % (author, topic) + else: + branch_name = "review/%s/%s-patch%s" % (author, topic, patchset_number) + + print("Downloading %s from gerrit" % refspec) + run_command_exc(PatchSetGitFetchFailed, + "git", "fetch", remote, refspec) + return branch_name + + +def checkout_review(branch_name): + """Checkout a newly fetched (FETCH_HEAD) change + into a branch + """ + + try: + run_command_exc(CheckoutNewBranchFailed, + "git", "checkout", "-b", + branch_name, "FETCH_HEAD") + + except CheckoutNewBranchFailed as e: + if re.search("already exists\.?", e.output): + print("Branch already exists - reusing") + run_command_exc(CheckoutExistingBranchFailed, + "git", "checkout", branch_name) + run_command_exc(ResetHardFailed, + "git", "reset", "--hard", "FETCH_HEAD") + else: + raise + + print("Switched to branch \"%s\"" % branch_name) + + +class PatchSetGitCherrypickFailed(CommandFailed): + "There was a problem applying changeset contents to the current branch." + EXIT_CODE = 69 + + +def cherrypick_review(option=None): + cmd = ["git", "cherry-pick"] + if option: + cmd.append(option) + cmd.append("FETCH_HEAD") + print(run_command_exc(PatchSetGitCherrypickFailed, *cmd)) + + +class CheckoutBackExistingBranchFailed(CommandFailed): + "Cannot switch back to existing branch" + EXIT_CODE = 67 + + +class DeleteBranchFailed(CommandFailed): + "Failed to delete branch" + EXIT_CODE = 68 + + +class InvalidPatchsetsToCompare(GitReviewException): + def __init__(self, patchsetA, patchsetB): + Exception.__init__( + self, + "Invalid patchsets for comparison specified (old=%s,new=%s)" % ( + patchsetA, + patchsetB)) + EXIT_CODE = 39 + + +def compare_review(review_spec, branch, remote, rebase=False): + new_ps = None # none means latest + + if '-' in review_spec: + review_spec, new_ps = review_spec.split('-') + review, old_ps = parse_review_number(review_spec) + + if old_ps is None or old_ps == new_ps: + raise InvalidPatchsetsToCompare(old_ps, new_ps) + + old_review = build_review_number(review, old_ps) + new_review = build_review_number(review, new_ps) + + old_branch = fetch_review(old_review, branch, remote) + checkout_review(old_branch) + + if rebase: + print('Rebasing %s' % old_branch) + rebase = rebase_changes(branch, remote, False) + if not rebase: + print('Skipping rebase because of conflicts') + run_command_exc(CommandFailed, 'git', 'rebase', '--abort') + + new_branch = fetch_review(new_review, branch, remote) + checkout_review(new_branch) + + if rebase: + print('Rebasing also %s' % new_branch) + if not rebase_changes(branch, remote, False): + print("Rebasing of the new branch failed, " + "diff can be messed up (use -R to not rebase at all)!") + run_command_exc(CommandFailed, 'git', 'rebase', '--abort') + + subprocess.check_call(['git', 'difftool', old_branch]) + + +def finish_branch(target_branch): + local_branch = get_branch_name(target_branch) + if VERBOSE: + print("Switching back to '%s' and deleting '%s'" % (target_branch, + local_branch)) + run_command_exc(CheckoutBackExistingBranchFailed, + "git", "checkout", target_branch) + print("Switched to branch '%s'" % target_branch) + + run_command_exc(DeleteBranchFailed, + "git", "branch", "-D", local_branch) + print("Deleted branch '%s'" % local_branch) + + +def convert_bool(one_or_zero): + "Return a bool on a one or zero string." + return one_or_zero in ["1", "true", "True"] + + +def print_exit_message(status, needs_update): + + if needs_update: + print(""" +*********************************************************** +A new version of git-review is available on PyPI. Please +update your copy with: + + pip install -U git-review + +to ensure proper behavior with gerrit. Thanks! +*********************************************************** +""") + sys.exit(status) + + +def main(): + global _no_color_support + usage = "git review [OPTIONS] ... [BRANCH]" + + import argparse + + class DownloadFlag(argparse.Action): + """Additional option parsing: store value in 'dest', but + at the same time set one of the flag options to True + """ + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, values) + setattr(namespace, self.const, True) + + parser = argparse.ArgumentParser(usage=usage, description=COPYRIGHT) + + parser.add_argument("-t", "--topic", dest="topic", + help="Topic to submit branch to") + parser.add_argument("-D", "--draft", dest="draft", action="store_true", + help="Submit review as a draft") + parser.add_argument("-c", "--compatible", dest="compatible", + action="store_true", + help="Push change to refs/for/* for compatibility " + "with Gerrit versions < 2.3. Ignored if " + "-D/--draft is used.") + parser.add_argument("-n", "--dry-run", dest="dry", action="store_true", + help="Don't actually submit the branch for review") + parser.add_argument("-i", "--new-changeid", dest="regenerate", + action="store_true", + help="Regenerate Change-id before submitting") + parser.add_argument("-r", "--remote", dest="remote", + help="git remote to use for gerrit") + parser.add_argument("-R", "--no-rebase", dest="rebase", + action="store_false", + help="Don't rebase changes before submitting.") + parser.add_argument("-F", "--force-rebase", dest="force_rebase", + action="store_true", + help="Force rebase even when not needed.") + parser.add_argument("-B", "--no-color", dest="no_color_support", + action="store_true", + help="No color support.") + + + fetch = parser.add_mutually_exclusive_group() + fetch.set_defaults(download=False, compare=False, cherrypickcommit=False, + cherrypickindicate=False, cherrypickonly=False) + fetch.add_argument("-d", "--download", dest="changeidentifier", + action=DownloadFlag, metavar="CHANGE", + const="download", + help="Download the contents of an existing gerrit " + "review into a branch") + fetch.add_argument("-x", "--cherrypick", dest="changeidentifier", + action=DownloadFlag, metavar="CHANGE", + const="cherrypickcommit", + help="Apply the contents of an existing gerrit " + "review onto the current branch and commit " + "(cherry pick; not recommended in most " + "situations)") + fetch.add_argument("-X", "--cherrypickindicate", dest="changeidentifier", + action=DownloadFlag, metavar="CHANGE", + const="cherrypickindicate", + help="Apply the contents of an existing gerrit " + "review onto the current branch and commit, " + "indicating its origin") + fetch.add_argument("-N", "--cherrypickonly", dest="changeidentifier", + action=DownloadFlag, metavar="CHANGE", + const="cherrypickonly", + help="Apply the contents of an existing gerrit " + "review to the working directory and prepare " + "for commit") + fetch.add_argument("-m", "--compare", dest="changeidentifier", + action=DownloadFlag, metavar="CHANGE,PS[-NEW_PS]", + const="compare", + help="Download specified and latest (or NEW_PS) " + "patchsets of an existing gerrit review into " + "a branches, rebase on master " + "(skipped on conflicts or when -R is specified) " + "and show their differences") + + parser.add_argument("-u", "--update", dest="update", action="store_true", + help="Force updates from remote locations") + parser.add_argument("-s", "--setup", dest="setup", action="store_true", + help="Just run the repo setup commands but don't " + "submit anything") + parser.add_argument("-f", "--finish", dest="finish", action="store_true", + help="Close down this branch and switch back to " + "master on successful submission") + parser.add_argument("-l", "--list", dest="list", action="store_true", + help="List available reviews for the current project") + parser.add_argument("-y", "--yes", dest="yes", action="store_true", + help="Indicate that you do, in fact, understand if " + "you are submitting more than one patch") + parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", + help="Output more information about what's going on") + parser.add_argument("--no-custom-script", dest="custom_script", + action="store_false", default=True, + help="Do not run custom scripts.") + parser.add_argument("--license", dest="license", action="store_true", + help="Print the license and exit") + parser.add_argument("--version", action="version", + version='%s version %s' % + (os.path.split(sys.argv[0])[-1], version)) + parser.add_argument("branch", nargs="?") + + try: + (top_dir, git_dir) = git_directories() + except GitDirectoriesException: + if sys.argv[1:] in ([], ['-h'], ['--help']): + parser.print_help() + sys.exit(1) + raise + +# config = get_config(os.path.join(top_dir, ".gitreview")) + config = DEFAULTS.copy() + cur_proj = run_command("git remote -v") + import re + m = re.search('(?<=29418\/)(\S+)', cur_proj) + config['project'] = m.group(0) + + + defaultrebase = convert_bool( + git_config_get_value("gitreview", "rebase", + default=str(config['defaultrebase']))) + parser.set_defaults(dry=False, + draft=False, + rebase=defaultrebase, + verbose=False, + update=False, + setup=False, + list=False, + yes=False, + branch=config['defaultbranch'], + remote=config['defaultremote']) + options = parser.parse_args() + + if options.license: + print(COPYRIGHT) + sys.exit(0) + + branch = options.branch + global VERBOSE + global UPDATE + VERBOSE = options.verbose + UPDATE = options.update + remote = options.remote + yes = options.yes + status = 0 + + needs_update = latest_is_newer() + check_remote(branch, remote, + config['hostname'], config['port'], config['project']) + + if options.no_color_support: + _no_color_support = True + + if options.changeidentifier: + if options.compare: + compare_review(options.changeidentifier, + branch, remote, options.rebase) + return + local_branch = fetch_review(options.changeidentifier, branch, remote) + if options.download: + checkout_review(local_branch) + else: + if options.cherrypickcommit: + cherrypick_review() + elif options.cherrypickonly: + cherrypick_review("-n") + if options.cherrypickindicate: + cherrypick_review("-x") + return + elif options.list: + list_reviews(remote) + return + + if options.custom_script: + run_custom_script("pre") + + hook_file = os.path.join(git_dir, "hooks", "commit-msg") + have_hook = os.path.exists(hook_file) and os.access(hook_file, os.X_OK) + + if not have_hook: + set_hooks_commit_msg(remote, hook_file) + + if options.setup: + if options.finish and not options.dry: + finish_branch(branch) + return + + if options.rebase: + if not rebase_changes(branch, remote): + print_exit_message(1, needs_update) + if not options.force_rebase and not undo_rebase(): + print_exit_message(1, needs_update) + assert_one_change(remote, branch, yes, have_hook) + + ref = "publish" + + if options.draft: + ref = "drafts" + if options.custom_script: + run_custom_script("draft") + elif options.compatible: + ref = "for" + + cmd = "git push %s HEAD:refs/%s/%s" % (remote, ref, branch) + topic = options.topic or get_topic(branch) + if topic != branch: + cmd += "/%s" % topic + if options.regenerate: + print("Amending the commit to regenerate the change id\n") + regenerate_cmd = "git commit --amend" + if options.dry: + print("\tGIT_EDITOR=\"sed -i -e '/^Change-Id:/d'\" %s\n" % + regenerate_cmd) + else: + run_command(regenerate_cmd, + GIT_EDITOR="sed -i -e " + "'/^Change-Id:/d'") + + if options.dry: + print("Please use the following command " + "to send your commits to review:\n") + print("\t%s\n" % cmd) + else: + (status, output) = run_command_status(cmd) + print(output) + + if options.finish and not options.dry and status == 0: + finish_branch(branch) + return + + if options.custom_script: + run_custom_script("post") + print_exit_message(status, needs_update) + + +if __name__ == "__main__": + try: + main() + except GitReviewException as e: + print(e) + sys.exit(e.EXIT_CODE) diff --git a/bin/rte.cmd b/bin/rte.cmd deleted file mode 100644 index e87ab42..0000000 --- a/bin/rte.cmd +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -if "%1" == "-C" pushd "%2" -call "c:\program files (x86)\python35-32\python.exe" bbrte_release\rte_release\rtepreproc.py --dryrun --testsonly --o _appbuild -pushd _appbuild\alltestcases -call "c:\programs\cmake\bin\cmake.exe" -G "Visual Studio 12 2013" -popd -popd -pause -- 2.43.0