Wednesday, February 09, 2011

Git on the command line

[Update]: When dealing with multiple repositories I know use what's described in: http://pydev.blogspot.com.br/2012/07/git-multiple-repos.html

Yes, sometimes I still use the command line for git (even with EGit getting better and an integration on Aptana Studio 3).

This is an update to a previous post about git (with msysgit).

[Update] October 31st, 2011: Improved gitdd command a bit
[Update] February 6th, 2012: Adedd command to preview incoming changes on a branch

1. Configure running shell

Usually I use TCC/LE as a shell, so, there's an alias to start the git bash shell from it (tcc allows editing the a 4START.BAT which will run when it's started, so, the configuration may be added there):

alias gitshell=path_to_git/bin/sh.exe --login -i

Other aliases:

alias git1=git log --graph --oneline --decorate

Shows the log with nice graph.

1a Use pageant/plink so that the password does not need to be entered all the time

Download pageant/plink, set environment variable GIT_SSH to the plink location, start pageant and load the private ssh key with pageant.

1b Global git configurations

git config --global user.name "fabioz"
git config --global core.autocrlf input

2. Fix history behavior

I find it annoying that the default history completion behavior (when up/down is used) is always getting the previous command instead of completing based on what's already there. To fix that, create a .inputrc file in your user home directory and set the following contents to it:

## By default up/down are bound to previous-history
## and next-history respectively. The following does the
## same but gives the extra functionality where if you
## type any text (or more accurately, if there is any text
## between the start of the line and the cursor),
## the subset of the history starting with that text
## is searched (like 4dos for e.g.).
## Note to get rid of a line just Ctrl-C
"\e[B": history-search-forward
"\e[A": history-search-backward

$if Bash
## F10 toggles mc on and off
## Note Ctrl-o toggles panes on and off in mc
"\e[21~": "mc\C-M"

##do history expansion when space entered
Space: magic-space
$endif

## Include system wide settings which are ignored
## by default if one has their own .inputrc
$include /etc/inputrc


3. Diff changes

For diffing the current changes with WinMerge, there's a file called gitdd (added to the git bin dir) with the contents below:

#!/bin/sh

# usage: gitdd
# Compares the current differences in winmerge with links to original files.
# Note that it must be executed at the root of the git repository.

SUBDIRECTORY_OK=1

O=".git-winmerge-tmp-$$"
V=HEAD
list="$O/list"
list_exist="$O/list_exist"
# Delete everything created here on exit
trap "rm -rf $O" 0
mkdir $O
mkdir $O/WORKINGCOPY
# Dump
git diff $V --name-only -z $1 > $list
# Create links to changed files inside temp folder
# (changes made to these links will be made to originals)
for i in `cat $list | xargs -0`; do
PPATH=`dirname $i`
mkdir -p $O/WORKINGCOPY/$PPATH
mkdir -p $O/HEAD/$PPATH
ln $(pwd)/$i $(pwd)/$O/WORKINGCOPY/$i
git show HEAD:$i > $O/HEAD/$i
done
# Copy HEAD versions of changed files to temp folder
# cat $list | xargs -0 git archive --prefix=HEAD/ $V | tar xf - -C $O
# Execute winmerge which must be on the system path
WinMergeU.exe //r //u //wr //dl WORKINGCOPY //dr HEAD $O/WORKINGCOPY $O/HEAD

3a. WinMerge tree view

I also always like to see things as a tree in WinMerge (Menu view > Mode: Alt+V M) and also expanded (Menu view > Expand All Subfolders: Alt+V X). It'll store the configuration to show as tree, but unfortunately it needs to be expanded all the times when doing a compare (i.e.: no auto-expand).

4. Show things in a compact way

git config format.pretty "%h %ct %ad %Cgreen%aN%Creset %s"
git config log.date short

#Make git log show comments wrapped.
git config --global core.pager 'less -r'

5. The commands used to get the contents of a pull request (create local branch, merge, get dev, merge with dev):

git checkout -b PullFromBranch-dev development
git pull https://github.com/pull_from_user/Pydev.git PullFromBranch
git checkout development
git merge PullFromBranch-dev --no-commit --no-ff

Then, to accept the merge do a commit or to reject it do:
git merge --abort
or
git merge --reset


6. When creating a feature in a branch:

git checkout -b FeatureBranch-dev development
git checkout development
git pull FeatureBranch-dev --no-ff


7. Preview incoming changes:

Create a bash file with the contents below (usually just hardcoding the ${current-branch} to the development branch). The command below will create 2 branches from the current branch, update one of those, diff it, compare with external tool and revert changes again.

echo Saving local changes just in case... git stash apply may be done later!
git stash
git checkout -b preview-branch
git checkout -b preview-branch2
git pull origin ${current_branch}
git checkout preview-branch
git merge --no-ff --no-commit preview-branch2
gitdd
git reset --hard
git checkout ${current_branch}
git branch -D preview-branch
git branch -D preview-branch2


8. Common commands

git status
git commit -a -m "Message"
git push origin master
git checkout
git shortlog -4 -w
git log -n 6
git log -n 3 --format=full
git commit --amend (change last commit message)
git show (see what happened on a commit)

And some of the commands I had to discover how to use in the msysgit bash are:

Alt+Space+E+K: mark contents for copy
Insert: paste contents
Alt+Backspace: erase until whitespace


Doing a merge:

Steps: create a new branch based on the current development, pull the merge request into that branch, then checkout the development branch, merge it there without commiting (to do a proper review) and then accept or reject the merge.

git checkout -b branch_to_do_merge_dev development
git pull https://github.com/user/Pydev.git jonahkichwacoders:branch_to_do_merge
git checkout development
git merge branch_to_do_merge_dev --no-commit --no-ff

Then, to accept the merge do a commit to reject it do:
git merge --abort
or
git merge --reset

4 comments:

Joel Bender said...

In 2. Fix history behavior there should be a backslash in front of the lowercase e, so it should be "\e[B": history-search-forward for example.

Joel Bender said...

For the 2. Fix history behavior part there should be a backslash in front of the lowercase 'e' like "\e[B": history-search-forward, other than that it works great! Thank you.

Fabio Zadrozny said...

Thanks... not sure how I got blogger to eat those as it was a copy from a local file -- which is correct :)

Anonymous said...

Copying and pasting becomes a lot easier if you install console2 and run msysgit bash from it.

http://sourceforge.net/projects/console/