Git back to where you used to be

I’m still not as versed in Git as I used to be. In various situations, I find myself looking at things and saying, well, I’ve backed up my own files, I know where I used to be. How do I just wipe everything clean and start over?

Obviously there’s always delete the dir and re-clone the files. With multi-gigabyte repos over a cell connection this isn’t the best option. Here’s a list of situations and their remedies as I’ve found them. All commands are run in the main directory of your project.

I’ve got changes, but I don’t want to commit them:

#just go ahead and delete everything you know about. 
git reset --hard

I’ve got changes and new files to add, but I just want to wipe everything out:

#hey git, there's all sorts of things in here to pay attention to
git add .
#just go ahead and delete everything you know about. 
git reset --hard

My commits have diverged, but I just wanna be where the origin is, not where I am:

#just go ahead and go back to where you were. 
git reset --hard @{upstream}

I’ve got commits staged, but I just want to wipe everything out:

#wipe out the last commit. Repeat as necessary
git reset --soft "HEAD^"

Multiple Email Addresses with a Default in Git

Someone pointed out to me that my commits to github were showing up using my work email address (and therefore my commits weren’t connected to the proper account). I do personal and professional work on the same laptop and I find myself wanting to commit one git repo via one email address and one repo to another.

The first idea I had was to set the global email address to the default and then set individual email addresses on a per-project basis. Git always uses the global email address if one’s set. Thanks, git. Anyway, I have a super-hacky workaround for this based partially on my PS1 code for my bash profile. The first thing you have to do is open your ~/.gitconfig file and remove the user.email line. This was originally set using git config --global user.email your@email.com, but we’ll be handling this more manually:

parse_git(){
	gb=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1/")
	if [[ -z $gb ]]
	then echo -e ""
	else
		ge=$(git config user.email)
		if [[ -z $ge ]]
		then 
			git config user.email "morgan@gallerus.com"
			echo -e "morgan@gallerus.com:"$gb'\n\r'
		else echo -e $ge":"$gb'\n\r'
		fi
	fi
}
PS1="\[\033[1;33m\]\$(parse_git)\[\033[0;0m\]\[\033[1;32m\]\w\[\033[0;0m\]\n>"

This first line takes the output from git branch and finds a line with a * in it indicating that branch is selected. If it finds one, it re-searches for the name specifically. If either of these is not found, an empty string is returned.

in bash, [[ -z ]] indicates empty. If we find that the output of the branch script is empty, we stop checking. Otherwise, we set the local email address to the default.

Finally, we output the various bits for use in our PS1 shell prompt, but you don’t have to do that if you don’t want to.

The final output looks something like this (only more colorful)

morgan@gallerus.com:feedback
~/Documents/Workspace/gallerus
>

which is now how I like to set up my bash environment.

ssh_askpass missing on osx

I recently installed tower on my system and tried to connect to a git repo I use. I don’t have my default password set in git (I like typing passwords), so when it tried to prompt me, I didn’t have a means of telling Tower what my password was. This is an oversight in OSX, but hey, we can fix that. This is the error I received
ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory
Permission denied, please try again.

And here’s the language to fix it. Place this code into a file at /usr/libexec/ssh-askpass and make it executable chmod +x /usr/libexec/ssh-askpass and you should be good to go. Tower will prompt you for passwords using a handy dialog.

#! /bin/sh

#
# An SSH_ASKPASS command for MacOS X
#
# Author: Joseph Mocker, Sun Microsystems

#
# To use this script:
# setenv SSH_ASKPASS "macos-askpass"
# setenv DISPLAY ":0"
#

TITLE=${MACOS_ASKPASS_TITLE:-"SSH"}

DIALOG="display dialog \"$@\" default answer \"\" with title \"$TITLE\""
DIALOG="$DIALOG with icon caution with hidden answer"

result=`osascript -e 'tell application "Finder"' -e "activate" -e "$DIALOG" -e 'end tell'`

if [ "$result" = "" ]; then
exit 1
else
echo "$result" | sed -e 's/^text returned://' -e 's/, button returned:.*$//'
exit 0
fi

Learning the Basics of Git – Fun!

I’ve been forced to switch from SVN to Git at work. The path has been difficult so far, but there’s a number of good svn to git guides out there, so I won’t really be posting about those. But, as a decent subversion user who’s been forced into git, I’d be remiss in not documenting the realizations I’ve had about the various workflow differences.

git clone url – this is used to pull files from a repo to your computer. This is the equivalent of hey, git, go and copy the main folder of this project to my computer and set it up for version control.

The following command have to be done in a project that’s under version control.

git branch – asks git to remind us which branch we’re on and which branches we have available, should we want to switch to them.

git branch mybranch – This tells git to create a new branch on your computer to which we can switch if we like.

git checkout mybranch – This tells the project to stop working with whatever branch it had and to use the new branch you’ve specified. If you’ve got uncommitted changes to files and you do this, git will prompt you of any conflicts.

git pull – This says, hey git, give me all of the most recent files from the server in the current branch on which I’m working.

git pull branch – This says, hey git, give me all of the most recent files from the server in the branch I’ve specified.

git add my.file – This tells git to start paying attention to the specified file. If you don’t do this, git will assume it’s not supposed to care.

git commit or git commit my.file(s) – Tells git that the state of things is something we want to hang on to. This doesn’t do anything on the server. It just tells git that the way things are now might be something we want to push to the server later. We also have to correlate a checkout with a message.

git push – This takes every commit you’ve made and pushes them up to the server.