问题
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.
回答1:
To address my original problem: How to make git ignore my file regardless of branching?
- git rm cpp/inc/core/util/VERSION.hpp
- 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:
- 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. - 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.
- 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.
来源:https://stackoverflow.com/questions/13428403/how-to-embed-an-updated-git-hash-into-version-hpp