12

How do people deal with different shebangs between local and remote?

For example, my local python is /usr/bin/python, whereas my web host is a purpose-built python at ~/local/bin/python. A lead developer may have ruby at /usr/bin/ruby, whereas mine is /usr/local/bin/ruby.

I manually edit the shebang, but then git marks it as a change. Ideally, I would like git to ignore the first line of the file, or perhaps to ignore a regex match of lines within the file.

It seems to me this must be a very common problem, but I cannot find any mention of it.

I use git, but I would not call myself an expert by any stretch.

Nick Coleman
  • 465
  • 3
  • 10
  • 6
    Isn't that what `#!/usr/bin/env python` is for? – coreyward Feb 19 '11 at 05:58
  • @coreyward: See [this question](http://unix.stackexchange.com/q/29608/10454) and [my answer](http://unix.stackexchange.com/a/29620/10454) for a discussion of the advantages and drawbacks of the `#!/usr/bin/env` hack. – Keith Thompson Apr 28 '13 at 18:21

3 Answers3

18

Change it to

#!/usr/bin/env python

or

#!/usr/bin/env ruby

Then it should work on all your systems, provided you have python and ruby in your PATH environment variable.

Mikel
  • 24,855
  • 8
  • 65
  • 66
  • The PATH is the issue. I have a custom-built python in ~/local/bin/python on my web-host. I can't change the PATH for the web server as I don't have root. It is kind of annoying to have to change the shebang every time I do a pull or a push. – Nick Coleman Feb 20 '11 at 02:35
  • [continued...] I guess my real question was "can git be made atomic at the line level" and the answer is "no, it is atomic at the file level". – Nick Coleman Feb 20 '11 at 02:45
  • You probably don't need root. How are you running the script? Command line? Via a web page? Via Cron? – Mikel Feb 20 '11 at 02:53
  • It's via a web page. I also have shell access and can run it command line to test it. – Nick Coleman Feb 20 '11 at 08:12
  • Apache? PHP? Ruby? General answer: call `env PATH=$PATH:/home/user/local/bin scriptname` rather than just `scriptname`. – Mikel Feb 20 '11 at 08:21
  • @Mikel, but on many systems you can't pass more than a single argument on the shebang line, the whole rest of the line will be passed to env as `$1`. – dubiousjim Apr 19 '12 at 15:52
  • You're right. There's some hacks suggested in http://stackoverflow.com/questions/3306518/cannot-pass-an-argument-to-python-with-usr-bin-env-python that could work in the general case. And if running from Apache, two things to try are [SetHandler](http://httpd.apache.org/docs/2.0/mod/core.html#sethandler) and [mod_env](http://httpd.apache.org/docs/2.2/mod/mod_env.html). – Mikel Apr 19 '12 at 21:16
5

The solution to your problem is git’s smudge/clean filter rule. This allows you to set up filters that will modify files on checkout and undo those changes on checkin. Here’s a nice graphic:

enter image description here

First set up a the filters that can do the change in both directions, by adding something like the following to you .git/config. The smudge filter transforms the file in the repo to the working copy, the clean filter undoes that change. It is important that running smudge -> clean yields exactly the original file. The filters given here will replace the first line with #!~/local/bin/python in the working copy if it is #!/usr/bin/env python in the repo

[filter "pyshebang"]
    smudge = sed '1s?^#!/usr/bin/env python$?#!~/local/bin/python?'
    clean = sed '1s?^#!~/local/bin/python$?#!/usr/bin/env python?'

Now activate this filter by adding a line like this to .git/info/attributes (create that file if it doesn’t exist):

*.py filter=pyshebang

If your python files don’t end in .py, just configure the filter on the correct files / a whole folder / all the files. If you set up the filter correctly it will only change files with a python shebang anyways.

I would recommend to read up on smudge filters, to understand the details of what’s going.

Chronial
  • 66,706
  • 14
  • 93
  • 99
  • URL for the smudge filter documentation has changed: https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion – ericx Jul 22 '22 at 11:27
0

This belongs in the comments but I don't have enough reputation yet... You could just remove the hash bang and always run it with python when you run it from the command line... maybe...

Daniel Kuntz
  • 405
  • 4
  • 11