4

Original Title: How to make git ignore my file regardless of branching?

I have the following post-checkout file which works as expected:

#!/usr/bin/ruby

cmd = ENV["HOME"] + "/dev/pitbull/cpp/bin/gen_version.rb --write"
`#{cmd}`

The gen_version.rb script figures out a timestamp, the last master tag, and the HEAD git hash and writes to a VERSION.hpp file which is also in git.

I then use use git update-index --assume-unchanged VERSION.hpp to make git ignore my change.

Now, this works great if I stay on my development branch. But when I try a get checkout master, I'm screwed:

git checkout master
error: Your local changes to the following files would be overwritten by checkout:
    cpp/inc/core/util/VERSION.hpp
Please, commit your changes or stash them before you can switch branches.
Aborting

What is the right git setup so that I can update VERSION.hpp when I check out but have git ignore any changes to this file, regardless of my branch?

EDIT I changed the topic as the final solution actually addresses a broader topic which may be more useful to more users of SO. So you can read this topic two ways: with the original title and the answer below, or with the broader problem above, again with the entire solution below.

kfmfe04
  • 14,936
  • 14
  • 74
  • 140
  • If i understand you right you wanz to overwrite the changes to this file on checkout. Try git checkout -f – Lesstat Nov 17 '12 at 06:48
  • @Lesstat sounds reasonable, but when I tried it, I got: error: Entry 'cpp/inc/core/util/VERSION.hpp' not uptodate. Cannot merge. – kfmfe04 Nov 17 '12 at 06:52
  • 1
    Mhm have you considered ignoring the file all together with a .gitignore file? – Lesstat Nov 17 '12 at 06:57
  • @Lesstat yes, I tried that, too, but I still get the same error from git checkout master above... – kfmfe04 Nov 17 '12 at 07:11
  • 1
    +1 @Lesstat actually, I tried removing it from git altogether and then put it into .gitignore - I think this might work. Will update later if it does. TY. – kfmfe04 Nov 17 '12 at 07:15
  • 1
    Yes, .gitignore only ignores files that aren't already in the index. Your last comment is the correct way to do this if you don't want the file checked-in. – MattJenko Nov 17 '12 at 11:52
  • +1 @MattJenko ty for the confirmation – kfmfe04 Nov 17 '12 at 15:23

1 Answers1

3

To address my original problem: How to make git ignore my file regardless of branching?

  1. git rm cpp/inc/core/util/VERSION.hpp
  2. add cpp/inc/core/util/VERSION.hpp to .gitignore

To address: How to embed an updated git-hash into Version.hpp?

Part of the issue is a chicken-egg problem where you cannot know your hash until all files are checked in, but you cannot check in your updated VERSION.hpp until you know your git-hash. So my solution was to leave VERSION.hpp out of repository and in the .gitignore file.

Keep in mind that the purpose of embedding VERSION.hpp into the executable: if a nasty bug shows up in production, with the git-hash in the binary, we will know what code to checkout of git so that we can debug the code properly.

Here are the steps I took in addition to the two steps above:

  1. Write a short ruby script which does two things, depending on whether the local area is dirty or not (if git diff --shortstat shows more than 0 lines, you have a dirty area). git rev-list HEAD | sed -n '1p' | cut -c1-10 will give you the first 10 characters as the git-hash. If your local area is dirty, this is the LAST HEAD's git-hash (I embed the string LAST inside VERSION.hpp). If this is clean, it is your true current git-hash.
  2. The ruby script will check the result in 1. vs the actual VERSION.hpp file. If the result has changed, then write the new result into VERSION.hpp.
  3. Modify my .bashrc, adding two small aliases - cmakerel and cmakedbg for calling cmake in my local and release directories, but before I do I cmake and make in the alias, I call the ruby script in 1. to update my VERSION.hpp if necessary.

If I call cmakerel and cmakedbg after git checkout and if I don't modify the code before the build (which I shouldn't be doing for an actual release anyways), I will have the VERSION.hpp I need with all the proper information embedded.

NOTE An alternative solution to modifying .bashrc with the aliases is to use git's post-checkout hook (in theory). However, I couldn't get this to work and I had spent too much time on this issue already, but you may have better luck.

kfmfe04
  • 14,936
  • 14
  • 74
  • 140