SOME OF ITS ENHANCING YOUR GIT WORKFLOW BY BYPASSING SOME OF ITS VERBOSE SYNTAX AND CUSTOMIZING IT TO DO MORE FOR YOU. VERBOSE SYNTAX AND CUSTOMIZING IT TO DO MORE FOR YOU. Chris Arcand / @chrisarcand www.chrisarcand.com Follow along online at http://slides.com/chrisarcand/git_unleashed/live
Git workflow by bypassing some of its verbose syntax and customizing it to do more for you™ THIS TALK IS NOT ABOUT: THIS TALK IS NOT ABOUT: How to use Git in the first place Replacing every Git interaction you can think of with aliases How to do anything in the left column on Windows (Sorry...kinda) BEFORE WE BEGIN... BEFORE WE BEGIN... Just kidding, I'm not.
INSPIRED BY "ENHANCED ASS KICKING WITH GIT" BY PATRICK BYRNE BEFORE WE BEGIN... BEFORE WE BEGIN... pbyrne @pbyrne http://patrickbyrne.net/presentations/enhanced-ass-kicking-with-git
~/.bashrc or ~/.profile, etc. As with all of your customized dotfiles, it's a good idea to share them amongst your computers It is highly recommended you keep all of your dotfiles in a Git project - but that's a topic for another day. http://www.github.com/chrisarcand/dotfiles
git a lot throughout the day. Why not make it a little easier? alias g=git NOT JUST GIT, EITHER NOT JUST GIT, EITHER be for bundle exec psg for ps aux | grep nrw for npm run-script watch etc, etc...
g * vs. git * saves two keystrokes (oh the humanity) From .zsh_history, ~300 git commands on a busy work day = 600 extra keystrokes per day ~260 work days per year = 156,000 extra keystrokes per year 50 words per minute (modest generalization) = 15,000 keystrokes per hour *300 keystrokes might be a bit high for every single workday in a year; 260 days doesn't include vacation; average typing speeds are very spread. The point is that it's on the order of hours. = Over 10 hours wasted typing the letters 'i' and 't' in a year
in any Git project WHAT'S THERE NOW? WHAT'S THERE NOW? g config --list to see all of the current settings Add --global to see just the global settings (~/.gitconfig) Add --local to see just the local settings (.git/config) TO CHANGE A CONFIGURATION VALUE TO CHANGE A CONFIGURATION VALUE g config --global foo.bar baz to set foo.bar to baz Or just edit the configuration file directly
upstream branch by default push.default upstream Don't write Windows linefeeds to repo core.autocrlf input Reuse Recorded Resolution rerere.enabled true Autocorrect help.autocorrect 1 Disable repetitive advice messages advice.detachedHead false SOME USEFUL EXAMPLES... SOME USEFUL EXAMPLES... (Windows users, use true instead) (Default pre Git2.0 is matching, pushes all branches) (Many different advice.* options available)
for diffs/merges (Example: Filemerge via Xcode) diff.tool opendiff merge.tool opendiff difftool.prompt false mergetool.prompt false Set editor for Git to use (commit messages, etc) core.editor vim (Default is $EDITOR) The list goes on and on... g help config
bash-completion brew install bash-completion # Add this to your bash config to load # completion scripts from Homebrew packages [ -f `brew --prefix`/etc/bash_completion ] && . `brew -- prefix`/etc/bash_completion # Lastly, enable completion for # your `g` alias in addition to `git` complete -o default -o nospace -F _git g Note that much of this is usually done for you if you use Z shell (zsh) and plugins like oh-my-zsh
if you use other shells/tools like Z shell (zsh) and oh-my-zsh ADD-ONS | ADD-ONS | $PS1 FOR GIT $PS1 FOR GIT # The __git_ps1 function is incredibly useful for customizing $PS1 \w $(rvm-prompt i v 2> /dev/null)\[\e[1m\] $(__git_ps1 2> /dev/null)\[\e[0m\] \n$ # Configurable with environment variables such as: GIT_PS1_SHOWDIRTYSTATE=1 # show * if there are unstaged changes and + if staged # and uncommitted changes. GIT_PS1_SHOWSTASHSTATE=1 # show $ if there are stashed changes. GIT_PS1_SHOWUNTRACKEDFILES=1 # to show % if there are untracked files. GIT_PS1_SHOWUPSTREAM=1 # show < if there are unpulled changes, > if there are # unpushed changes, <> if there are both, or = if everything’s synced.
configurable commands Long, verbose commands you'd never type out regularly or remember every option for it Complex functionality not available with Git itself In essence, the addition of the shell to do complex things specific to your workflow The two types of aliases (Standard, Shell) can be broken down further: THE THREE ROLES OF ALIASES THE THREE ROLES OF ALIASES
br = branch co = checkout df = diff dc = diff --cached ls = ls-files Some of my own... And some I don't use... p = push u = pull tgif = git push --force origin master Why don't I use the commands on the right? Explanation forthcoming.
tools with Git Can be a trival combination of Git commands... u = "!git add -u && git status" ...or added functionality that Git, by itself, can't provide clear-local-branches = "!git branch | grep -v "master" | xargs git branch -D"
-f 2 | sort -u" "conflict" = Shows unmerged files in a merge conflict Now when you have a merge conflict, you can easily open all the files that require your attention: $ subl `g cnf` (Example using SublimeText)
do you draw the line with aliases? (This is related to what I asked earlier; the ones I don't use) Copy/pasting aliases off of StackOverflow. Rummaging through people's dotfiles. How mind blowing. How can this really affect how I view my workflow?
draw the line is obviously subjective CONS OF ALIASES CONS OF ALIASES Eventually become so terse they betray almost no meaning (Even the author of the alias can't remember what it all does again) User practically forgets how to use out-of-box Git
commands in a way that isn't intuitive from an outside viewpoint g u ? g pu ? = git push, duh! To me, this includes any sort of push action (mostly) Reminder: Once you push, you cannot completely revert something ...without pissing people off You don't need an alias for git diff $(git merge-base master HEAD) HEAD You need to know how to use git diff master... (which is git diff master...HEAD) Use aliases to circumvent Git's complexities, not its simplicities Don't alias extremely important actions
MY WORKFLOW? Aliases are great for stealing random functionality that didn't know you needed in your workflow Their true power lies in being able to customize Git to do what you need it to do in your own personal workflow BUT ALIASES - ALONG WITH THOUGHTFUL CONFIGURATION - ARE MORE BUT ALIASES - ALONG WITH THOUGHTFUL CONFIGURATION - ARE MORE THAN JUST COPY PASTA THAN JUST COPY PASTA
modifications to a new stash git stash pop [<stash>] Remove a single stashed state from the stash list and apply it on top of the current working tree state git stash list List the stashes that you currently have git stash apply [<stash>] Like pop, but do not remove the state from the stash list
and attend to other things. GREAT! GREAT! $ git stash Saved working directory and index state \ "WIP on master: 049d078 added the index file" HEAD is now at 049d078 added the index file (To restore them type "git stash apply")
= "!git stash list | cat" ~/workspace/cool_project(branch:master) » g sls stash@{0}: WIP on master: f5b42a9 Updating Changelog for 2014.09.05.14.10 stash@{1}: On master: another something ~/workspace/cool_project(branch:master) » g stash apply stash@{1}
drop requires index. Could fix through tricksy means, but more effort required Not actually that intuitive Useful only for a preset git stash apply, honestly
needs and do the heavy lifting in your preferred workflow Use aliases to... Make frequent commands faster Make highly configurable commands more accessible Unlock functionality Git doesn't provide by itself Don't let customization/aliases throw off your understanding and Git Fu Constantly reassess what is useful, what isn't, and what new things might make you more efficient. Keep in mind what is actually useful to you in your workflow.