Git Merge — Ignore Merge Conflicts for Specific Directory

How do you have Git ignore merge conflicts for a directory?
How do you force git to always accept files from a specific branch?

Look no further.

I have all of my project files in a git repo, including my libraries. Some libraries must compile and build binaries dependent on the OS, in my example pyCrypto.

That means I have a development branch for local development on my Mac, and a production branch that has the correct pyCrypto binaries for the production server.

However, every time I try to merge changes from my development branch, I’d get conflicts (naturally) since the binaries are different between the two packages.

I’ve solved my problem by forcing git to NOT merge the Crypto folder at all

I set up a git merge driver that does nothing at all, and set all files in the Crypto folder to use this driver.

All of this info comes from a stack question here http://stackoverflow.com/questions/928646/how-do-i-tell-git-to-always-select-my-local-version-for-conflicted-merges-on-a-sp/930495#930495

Step 1: create a special merge rule in your repositories .git/config file

[merge "keepmine"]
        name = dont_merge_selected_files
        driver = echo %O %A %B

Step 2: navigate to the folder you want never merged from outside branches, and create a .gitattributes file where you specify all files to use the merge driver “keepmine” defined in step 1

* merge=keepmine

commit your changes, and try merging! The conflicts in the folder with .gitattributes will not register and leave the original files intact. If you want the other way around, where your branch is always overwritten by a merge, take a look at the stack post above.

It says to set up a merge driver as

keepMine.sh %O %A %B

and in your keepMine.sh

cp -f $3 $2.
return 0

where 0 is the exit code of “resolved”.

This saves my world.

GitHub — fatal: ‘/data/repositories…’ does not appear to be a git repository

I just found out that my specific problem with GitHub doesn’t have to do with MY settings at all — I need to ask GitHub to fix an error in their systems.

http://support.github.com/discussions/repos/3426-fatal-datarepositories-does-not-appear-to-be-a-git-repository

Hopefully this helps somebody else getting the same problem.

Make sure you can ssh git@github.com

ssh git@github.com
ERROR: Hi yuchant! You've successfully authenticated, but GitHub does not provide shell access
Connection to github.com closed.

If you are having issues with permissions, read the answer to this stack question: http://stackoverflow.com/questions/922210/unable-to-git-push-master-to-github for tons of debugging ideas.

For me, it turns out it wasn’t my fault : )

Mac OSX — Installing a fresh Django environment with Homebrew, Git, and Virutualenv

How to install an isolated Django environment with Homebrew, Git, Virtualenv on OSX 10.6.5

I needed to start a local development environment, and every time I make a major switch whether it be a new server or a new OS, I try to make improvements based on what I’ve learned since the previous switch.

This time, I decided I need completely isolated virtualenvs, and I needed my code rewritten to use relative paths so that I can actually run my django app in my local environment without any changes.

Anyways…

First, install homebrew

I need the package manager Homebrew to do easy installs of various things like wget, Git, that are missing.

ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"

Next, install Xcode

You can find Xcode on the CD that ships with your mac.

Just open the CD, go to the Optional Installs folder, and click on the Xcode package.

This post has more detail if you require it http://www.mactricksandtips.com/2010/02/installing-xcode.html

Homebrew some Git

brew install git

Bam.

Use easy_install to grab virtualenv

easy_install virtualenv

Finally, time to set up our project!

First, we need to set up our project folder. I shall call it myproject. Very original.

mkdir myproject 
cd myproject

Now, it’s time to set up the virtual environment. I’m going ot use the –no-site-packages option to completely isolate this environment from the global python site-packages living in /Library/Python/X.X/site-packages

virtualenv venv --no-site-packages  # isolate from packages
cd venv  # cd into our newly created venv

virtualenv has set us up (the bomb) with a lib/ directory where python2.6 lives, and a bin/ directory where we have the activation scripts that force us to use this environment.

Since we want to install django into this virtualenv, run the bash script “bin/activate”

source bin/activate

Now we can install django. It’s now as easy as typing …

easy_install django

We can install most packages this way..

PS: I’d like to note that I had trouble installing PIL due to a bug. As of Nov 20, 2010, easy_install PIL will install to the correct directory but will not work. All you need to do is symlink the funky egg file to the same directory under the name PIL.

easy_install PIL
ln -s PIL............ PIL

Now we’re ready to start the django project.

cd ~/myproject
source venv/bin/activate # MAKE SURE you have activated your virtualenv, or else your python can't find the django you just installed.
django-admin.py startproject main

Congrats! Your isolated django install is ready on OSX

Bash / bash-alias / SSH — Automatically screen -x after logging in

I found myself setting up bash aliases that auto log me into my servers without having to type in a port number or password, but always found myself typing screen -x after I log in. I wanted a way to automatically queue a command after the SSH was established.

Sometimes, in spotty areas of connections, I have to do it *a lot*.

Passing in screen -x after the ssh returns an error that a terminal must be connected…

The solution is to use the -t flag

-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g., when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.

ssh me@me.com -p 3298 -t "screen -x" 

Django / mod_python — IOError: Client read error (Timeout?)

I’ve been getting these emails from my  django setup with this exception: IOError: Client read error (Timeout?)

I just found out I can consistently trigger it if I cancel an upload before it’s finished.

 

I used to think it was a server setting cutting off connections early or something, not to worry now!

 

TextMate / Sublime Text 2 Sudden Light Font Fix

Suddenly, my fonts got REALLY thin and I couldn’t figure out why. I started to wonder if it was ever any different or if I was imagining things.

That said, the fonts looked really thin and so did all others.

I’m glad I found this post: http://hints.macworld.com/article.php?story=20090828224632809

that details how OSX can sometimes detect your external display as a CRT and disables font smoothing.

Type this in the terminal to force the mac to always use 2: LCD font smoothing.

defaults -currentHost write -globalDomain AppleFontSmoothing -int 2

The number 2 here corresponds to Medium - Best for Flat Panel. You may also use 1 for light smoothing, and 3 for strong smoothing, as per the original OS X font smoothing options.

Python — Shopify Dynamic Discount Code Creation With Urllib2

The Shopify API has no support for discount code creation or mass discount code uploads by other means. Still, I needed a way to create 1 discount code for every order that comes in.

I was surprised to solve this rather painlessly in a short time since I’ve never used anything with urllib2 or parsing. I will document the final result instead of my trials and errors.

I like that this solution uses only basic functions. You don’t learn if it’s magic. I saw an example using mechanize that was only 20 odd lines of codes, but I don’t follow it / it’s not in python.

Next time I need to do this, I will look into python mechanize.

Here are the main steps involved in sending web requests to Shopify:

Authentication

First, we need to log in to Shopify programmatically — not through their API.

Use the urllib2 library to do so.

First, set up urllib2 to use the “opener” urllib2.HTTPCookieProcessor, which will handle cookie handling for your session.

import urllib, urllib2

opener = urllib2.build_opener( urllib2.HTTPCookieProcessor() )
urllib2.install_opener( opener )

# future requests will use the cookie processor that we install here

The next step is to log in to Shopify by setting up our urlencoded post parameters for this specific login form. All i needed to do was check out the login form and find the field names they are expecting: login, and password.

Let’s give it a shot:

params = { 'login': 'myusername', 'password': 'mypassword' }
encoded_params = urllib.urlencode( params )

_file = opener.open( 'https://myshop.myshopify.com/admin/auth/login', encoded_params )
response = _file.read()
_file.close()

# success!

Now, due to the Cookie handler, we can simply open new admin url pages and they will load without fuss.

_file = o.open('http://myshop.myshopify.com/admin/marketing')
_file.read()
_file.close()

#Works!

next step…

Posting to the discount code form…

First, navigate to the discount code page to see how their magic is happening. myshop.myshopify.com/admin/marketing is where you need to be.

I use google chrome, so you can open the developer tools, go to the resources tab, and click on the XHR subtab to see what AJAX requests are being performed when you create a discount code.

Here, I found all the information I needed to POST to replicate this behavior.

What exact headers if any that Shopify needs to see, what exact post parameters if any that shopify needs.

The important piece I see here is that there is an authentication token as a security measure Shopify takes.
We’ll need to hunt down this token and store it before we move on to making our POST.

Hunting down the authentication token

First, we need to load the /admin/marketing page to find this token. I used beautiful soup to parse the html and find the token.

        _file = opener.open( 'http://myshop.myshopify.com/admin/marketing' )
        html = _file.read()
        _file.close()

        soup = BeautifulSoup(html)
        auth_token = soup.find('input', type='hidden', attrs={'name': 'authenticity_token'})
        authentication_token = auth_token['value']
        # yay! our auth token found.

Setting up the request headers so Shopify doesn’t complain

With the auth token found, we need to modify our post headers or else Shopify will give you a 406 error. I didn’t bother to check which exact headers they check for, so I copied all of the headers I found in the screenshot above:

        post_headers = {
            'Accept': 'text/javascript, text/html, application/xml, text/xml, */*',
            'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7',
            'X-Prototype-Version': '1.7_rc2',
            'X-Requested-With': 'XMLHttpRequest',
        }

        # note, addheaders takes a list of tuples
        headers = [(x, y) for x, y in post_headers.iteritems()]
        opener.addheaders = headers

Setting up our actual POST

Our headers are ready, we have our authentication token, now lets set up our post data.

As in the screenshot, we know what fields Shopify is expecting. I just copied them all.

        form_data = {
            'utf8': '✓',
            'authenticity_token': authentication_token,
            'discount': 'helloDiscountCodeFromPython',
            'discount[value]': '10',
            'type':'fixed_amount',
            'discount[starts_at]': '',
            'discount[ends_at]': '',
            'discount[minimum_order_amount]': '0.00',
            'discount[usage_limit]': '1',
            'commit': 'Create Discount',
            'page': '1',
            '_': '',
        }

Let's make a discount code!

Finally, we're ready.

Here's the completed list of what we need:

  • Authentication. We're logged in.
  • The Authentication token.
  • The POST headers for AJAX / whatever Shopify is expecting
  • The POST itself

So let's give this a shot!

encoded_post_data = urllib.urlencode( form_data )
_file = opener.open( 'https://myshop.myshopify.com/admin/discounts', encoded_post_data)
response = _file.read()
_file.close()

# it works!

Fantastic! It works! I've taken this and built a class that will take options for the various discount code fields and check whether the response was successful or not (very crudely), etc.

Here's the whole process

I'll copy and paste the pieces here into one block

import urllib, urllib2

opener = urllib2.build_opener( urllib2.HTTPCookieProcessor() )
urllib2.install_opener( opener )
# future requests will use the cookie processor that we install here

# log in

params = { 'login': 'myusername', 'password': 'mypassword' }
encoded_params = urllib.urlencode( params )

_file = opener.open( 'https://myshop.myshopify.com/admin/auth/login', encoded_params )
response = _file.read()
_file.close()

# success!

# parse for auth token

_file = opener.open( 'http://myshop.myshopify.com/admin/marketing' )
html = _file.read()
_file.close()

soup = BeautifulSoup(html)
auth_token = soup.find('input', type='hidden', attrs={'name': 'authenticity_token'})
authentication_token = auth_token['value']

# auth token found.

# set up post headers

post_headers = {
    'Accept': 'text/javascript, text/html, application/xml, text/xml, */*',
    'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7',
    'X-Prototype-Version': '1.7_rc2',
    'X-Requested-With': 'XMLHttpRequest',
}

# note, addheaders takes a list of tuples
headers = [(x, y) for x, y in post_headers.iteritems()]
opener.addheaders = headers

# done adding headers to our opener (which means it will be used every time from now on)

# set up our post

form_data = {
    'utf8': '✓',
    'authenticity_token': authentication_token,
    'discount': 'helloDiscountCodeFromPython',
    'discount[value]': '10',
    'type':'fixed_amount',
    'discount[starts_at]': '',
    'discount[ends_at]': '',
    'discount[minimum_order_amount]': '0.00',
    'discount[usage_limit]': '1',
    'commit': 'Create Discount',
    'page': '1',
    '_': '',
}

encoded_post_data = urllib.urlencode( form_data )
_file = opener.open( 'https://myshop.myshopify.com/admin/discounts', encoded_post_data)
response = _file.read()
_file.close()

# discount code created!

WordPress.com Code Syntax Highlighting

I’ve had a lot of trouble finding syntax highlihgting for WordPress.com, as in hosted at wordpress.com.

There are plenty of nice plugins for wordpress.org, but not com.

I needed to write a post with a decent amount of code in it, so I looked harder this time and found Posting Source Code.

def myfunction(foo):
    print "this is Python!" 

#oh my god this is useful.

Git — Remove all .pyc

To remove all your .pyc files from your git repo…

First, git rm them
find . -name "*.pyc" -exec git rm -f {} \;

Then, add a .gitignore file in the root of your repo and enter a line:
*.pyc

to prevent them from being added automagically in the future without an -f