To put the prefix ?<revision-number> to codes by Git/SVN
How can you put the prefix ?v=VersionNumber
to each file at your repository efficiently with Git/SVN?
I found out that SO uses the practise to give version numbers to each specific file in its repo.
They use SVN. I would like to know how you can do the same with Git.
A few examples.
#1
<link rel="stylesheet" href="/content/all.css?v=3959">
#2
<script src="./js/question.js?v=3955" type="text/javascript"></script>
Solution 1:
"at your repository"? at your repository directly?
That would be call "keyword expansion" and that is not recommended (as discussed in this SO question)
Putting meta-data (revision number) into data stored into a repository can lead to merge issues.
What you see in SO pages are the result of a deployment process which takes the meta-data from SVN (the revision) and puts it into the generated HTML pages.
GitFaq does not recommend it either.
The equivalent to a SVN revision number integrated into files deployed on a server would be using git describe, in order to get some sort of a "commit count" to be displayed during deployment step.
But recording it directly in the repository would mean keyword expansion, and keyword unexpansion.
To illustrate that, let's check out what Linus said at the time of the original discussion on this topic (April 2007):
Adding expansion is not just "harder". It's basically impossible to do with any kind of performance.
Think "git checkout newbranch
".
And think what we do about files (and whole subdirectories!) that haven't even changed. And finally, think about how important that optimization is in an SCM like git that supports branches.[the] fundamental problems that keyword expansion has (ie switching branches is basically impossible to do without checking out every_single_file with the "keyword" attribute set. There are others).
Now, unexpansion is trivial to do (it really is the same as the "CRLF->LF" translation: that's technically really just an "unexpansion" too). And it should work.
The way this does unexpansion also breaks "git diff" in that it basically always makes diff ignore the keywords. In other words, when you do
git diff A..B
and send the diff to somebody else, they'll never see any keywords at all!
Now, that obviously fulfills my requirement that the diff be empty if A and B are the same, so you should expect me to be happy.
But I'm not happy, because if the other person also is using git, HE CANNOT EVEN APPLY THE DIFF!
Even if he's at "A", and thus gets a diff that is supposed to apply exactly, he'll get rejects if there were other changes around the unexpanded keyword (which he will have expanded in his working tree, of course!)See? Keywords simply cannot work. They're broken. Either you can ignore them (and not show them in diffs), in which case the diff is broken, or you can not ignore them (and show them in diffs) in which case the diff is also broken, just differently.
The only sane and workable case is to not have them at all. Any keyword expansion will always result in problems. You simply cannot do it right.
Solution 2:
If this version number is generated by some server script: PHP, Perl, ASP.NET, Ruby on Rails (VonC explained why keyword expansion is a bad idea, i.e. why making Git and not web server update such information is a bad idea), then it is simply matter of running git describe in this script.
Another solution is to make deployment (build) system, which copies files from version control system to web server, embed this data. For example gitweb, git web interface for Git written in Perl, has
our $version = "++GIT_VERSION++";
replaced by build system (make gitweb/gitweb.cgi
) by result of running GIT-VERSION-GEN
. This means for example that running gitweb shows in "generator" meta header for example:
<meta name="generator" content="gitweb/1.6.4.rc0.22.gfc1cf.dirty git/1.6.3.2.317.g2dd3f"/>
Solution 3:
Maybe you were looking for this:
How do I enable ident string for Git repos?
at least setting an $Id$ is possible and using filters will allow you some more options.
Example (not best one) from this answer
echo '*.txt ident' >> .gitattributes
echo '$Id$' > test.txt
git commit -a -m "test"
rm test.txt
git checkout -- test.txt
cat test.txt
See the manual for git-attributes.
Solution 4:
Ignoring the word "efficiently" in your question, you should look up "filter driver". A simple smudge to insert the revision and a clean to remove it should do what you (think you) want.