* RCS keyword expansion
@ 2007-10-11 14:47 Peter Karlsson
2007-10-11 15:02 ` Johannes Sixt
` (2 more replies)
0 siblings, 3 replies; 27+ messages in thread
From: Peter Karlsson @ 2007-10-11 14:47 UTC (permalink / raw)
To: git
Hi!
I've looked and looked, but cannot figure out how to do RCS/CVS style
keyword expansion with Git. The FAQ on the Wiki is quite cryptic on the
subject, and my googling skills fail short.
I mainly want to have $Date$ expand in RCS/CVS manner, i.e to when the
file was last changed. Possibly even have an $Id$ that gives me
something useful (name and commit hash, perhaps?). Is it possible to do
this? Can it be done through git-cvsserver?
I currently have my personal website in CVS and am using $Date$ to
include a datestamp on the pages. I am considering converting the
repository to Git, but only after I can get $Date$ expansion to work.
I am considering having the website host believe it still is a cvs
repository by using git-cvsserver, thus my question about expanding
$Date$ through it.
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: RCS keyword expansion 2007-10-11 14:47 RCS keyword expansion Peter Karlsson @ 2007-10-11 15:02 ` Johannes Sixt 2007-10-11 15:09 ` Randal L. Schwartz 2007-10-11 19:16 ` Lars Hjemli 2 siblings, 0 replies; 27+ messages in thread From: Johannes Sixt @ 2007-10-11 15:02 UTC (permalink / raw) To: Peter Karlsson; +Cc: git Peter Karlsson schrieb: > I've looked and looked, but cannot figure out how to do RCS/CVS style > keyword expansion with Git. The FAQ on the Wiki is quite cryptic on the > subject, and my googling skills fail short. Cryptic? Q: Does git have keyword expansion? A: No. To me this is crystal clear. :-) -- Hannes ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 14:47 RCS keyword expansion Peter Karlsson 2007-10-11 15:02 ` Johannes Sixt @ 2007-10-11 15:09 ` Randal L. Schwartz 2007-10-11 15:59 ` Oliver Kullmann 2007-10-11 17:55 ` Peter Karlsson 2007-10-11 19:16 ` Lars Hjemli 2 siblings, 2 replies; 27+ messages in thread From: Randal L. Schwartz @ 2007-10-11 15:09 UTC (permalink / raw) To: Peter Karlsson; +Cc: git >>>>> "Peter" == Peter Karlsson <peter@softwolves.pp.se> writes: Peter> I mainly want to have $Date$ expand in RCS/CVS manner, i.e to when the Peter> file was last changed. Possibly even have an $Id$ that gives me Peter> something useful (name and commit hash, perhaps?). Is it possible to do Peter> this? Can it be done through git-cvsserver? That's not a job for a source code manager to do. It's a job for your build/install tool. See how "git --version" gets created in the core distro, and follow that example. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/> Perl/Unix/security consulting, Technical writing, Comedy, etc. etc. See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training! ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 15:09 ` Randal L. Schwartz @ 2007-10-11 15:59 ` Oliver Kullmann 2007-10-11 18:09 ` Alex Riesen 2007-10-11 20:47 ` Johannes Schindelin 2007-10-11 17:55 ` Peter Karlsson 1 sibling, 2 replies; 27+ messages in thread From: Oliver Kullmann @ 2007-10-11 15:59 UTC (permalink / raw) To: git On Thu, Oct 11, 2007 at 08:09:22AM -0700, Randal L. Schwartz wrote: > >>>>> "Peter" == Peter Karlsson <peter@softwolves.pp.se> writes: > > Peter> I mainly want to have $Date$ expand in RCS/CVS manner, i.e to when the > Peter> file was last changed. Possibly even have an $Id$ that gives me > Peter> something useful (name and commit hash, perhaps?). Is it possible to do > Peter> this? Can it be done through git-cvsserver? > > That's not a job for a source code manager to do. It's a job for your > build/install tool. See how "git --version" gets created in the core distro, > and follow that example. > This looks like a misunderstanding of what $Date$ is used for: It has not much to do with a version number (such things are decisions by the developers), but it is an identification stamp, typically used to identify exactly which piece of code is involved in a given executable. Our group also needs a replacement for the keyword-expansion mechanism (we are using a nice little system, which allows for each executable produced to query it about the source-code-files involved in it, which is especially useful for testing and development, where many versions of many files float around (and perhaps some shouldn't)). The principle solution seems quite clear to me: Adapt the pre-commit hook, so that files are scanned for the keyword, and apply the keyword expansion then before the actual commit. Better than just the date, it would be greatest to be able to put also the SHA1-ID of the commit into the file, alas this is a bit complicated, since it's a pre-commit hook; However it seems necessary to have in the repository really the actual file content, not "modulo some modification", due to the distributed character of Git repositories (everybody should have the same file-timestamp), and so a post-commit hook shouldn't be used. So well, using the previous SHA1-ID should be a reasonable approximation. Oliver ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 15:59 ` Oliver Kullmann @ 2007-10-11 18:09 ` Alex Riesen 2007-10-11 20:47 ` Johannes Schindelin 1 sibling, 0 replies; 27+ messages in thread From: Alex Riesen @ 2007-10-11 18:09 UTC (permalink / raw) To: Oliver Kullmann; +Cc: git Oliver Kullmann, Thu, Oct 11, 2007 17:59:56 +0200: > Better than just the date, it would be greatest to be able to put also > the SHA1-ID of the commit into the file, alas this is a bit complicated, actually, it is quite simple: just (re)generate a file which you can compile and link to your executable. That is how gits version work: $ git version git version 1.5.3.4.229.ga321c1 this ga321c1 is the commit (no one knows what the "g" stands for, but the rest is plain value of HEAD at the moment of compilation). Put the generated string in your image in a greppable/identable form and you are set: the commit identifies uniquely the whole build tree (assuming your build tree _can_ be identified. It not given for most commercial projects I am familiar with). ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 15:59 ` Oliver Kullmann 2007-10-11 18:09 ` Alex Riesen @ 2007-10-11 20:47 ` Johannes Schindelin 2007-10-11 21:35 ` Sam Vilain 2007-10-12 5:26 ` Peter Karlsson 1 sibling, 2 replies; 27+ messages in thread From: Johannes Schindelin @ 2007-10-11 20:47 UTC (permalink / raw) To: Oliver Kullmann; +Cc: git Hi, On Thu, 11 Oct 2007, Oliver Kullmann wrote: > On Thu, Oct 11, 2007 at 08:09:22AM -0700, Randal L. Schwartz wrote: > > >>>>> "Peter" == Peter Karlsson <peter@softwolves.pp.se> writes: > > > > Peter> I mainly want to have $Date$ expand in RCS/CVS manner, i.e to when the > > Peter> file was last changed. Possibly even have an $Id$ that gives me > > Peter> something useful (name and commit hash, perhaps?). Is it possible to do > > Peter> this? Can it be done through git-cvsserver? > > > > That's not a job for a source code manager to do. It's a job for your > > build/install tool. See how "git --version" gets created in the core distro, > > and follow that example. > > > > This looks like a misunderstanding of what $Date$ is used for: It has > not much to do with a version number (such things are decisions by the > developers), but it is an identification stamp, typically used to > identify exactly which piece of code is involved in a given executable. It does not matter if it is a date or a version number. The problem is this: for efficiency, git does not change files which have not changes between the last version checked out (whatever that is) and the current version. This seems counterintuitive to people coming from SVN/CVS: they expect _every_ file to be touched when checking out. So there is not much we will do to accomodate in git; touching files which have not changed at all (even if containing a $Id$ or a $Date$) is not the way we want it... As Randal already suggested: if you need something like this, you better have a build procedure which replaced $Date$ _at a given time_ (make install) with the current date. Ciao, Dscho ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 20:47 ` Johannes Schindelin @ 2007-10-11 21:35 ` Sam Vilain 2007-10-12 5:26 ` Peter Karlsson 1 sibling, 0 replies; 27+ messages in thread From: Sam Vilain @ 2007-10-11 21:35 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Oliver Kullmann, git Johannes Schindelin wrote: > The problem is this: for efficiency, git does not change files which have > not changes between the last version checked out (whatever that is) and > the current version. > > This seems counterintuitive to people coming from SVN/CVS: they expect > _every_ file to be touched when checking out. Well, that's not entirely true. SVN for one doesn't change the keywords on files that haven't changed. You can't have a keyword that expands to the current head revision, for instance. SVN's answer to the problem of how this works with merging is largely arbitrary; if you are merging changes in, the $Id$ becomes expanded to the merge that affected that path, not the change that introduced this version of the file. Sam. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 20:47 ` Johannes Schindelin 2007-10-11 21:35 ` Sam Vilain @ 2007-10-12 5:26 ` Peter Karlsson 2007-10-12 10:02 ` Johannes Schindelin 2007-10-12 19:08 ` Salikh Zakirov 1 sibling, 2 replies; 27+ messages in thread From: Peter Karlsson @ 2007-10-12 5:26 UTC (permalink / raw) Cc: git Johannes Schindelin: > The problem is this: for efficiency, git does not change files which have > not changes between the last version checked out (whatever that is) and > the current version. > > This seems counterintuitive to people coming from SVN/CVS: they expect > _every_ file to be touched when checking out. No? That would just be strange. Only the files that are actually changed should be updated, no others. A $Date$ or $Id$ will show the last time/commit that specific file was changed, not the latest global state (I guess the fact that most modern VCSs have global state makes this a bit more difficult to achieve, in RCS/CVS/PVCS and others the change history is local to a file and thus it is trivial to find the large change for that particular file). > As Randal already suggested: if you need something like this, you better > have a build procedure which replaced $Date$ _at a given time_ (make > install) with the current date. But that's not what I want. Then my build procedure would need to do a "git status", or whatever you use to get the last commit information about a file, on each file that is changed and is to be installed. It would be a lot easier if that was done already on checkout through some kind of hook. -- \\// Peter - http://www.softwolves.pp.se/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 5:26 ` Peter Karlsson @ 2007-10-12 10:02 ` Johannes Schindelin 2007-10-12 10:50 ` Peter Karlsson 2007-10-12 19:08 ` Salikh Zakirov 1 sibling, 1 reply; 27+ messages in thread From: Johannes Schindelin @ 2007-10-12 10:02 UTC (permalink / raw) To: Peter Karlsson; +Cc: git Hi Peter, please do not play games with the To: header. We have a policy here (which is supposed to be good netiquette) that we keep people in the Cc: list that we respond to. On Fri, 12 Oct 2007, Peter Karlsson wrote: > Johannes Schindelin: > > > The problem is this: for efficiency, git does not change files which > > have not changes between the last version checked out (whatever that > > is) and the current version. > > > > This seems counterintuitive to people coming from SVN/CVS: they expect > > _every_ file to be touched when checking out. > > No? That would just be strange. Only the files that are actually changed > should be updated, no others. A $Date$ or $Id$ will show the last > time/commit that specific file was changed, not the latest global state > (I guess the fact that most modern VCSs have global state makes this a > bit more difficult to achieve, in RCS/CVS/PVCS and others the change > history is local to a file and thus it is trivial to find the large > change for that particular file). But don't you see? When switching branches, this totally breaks down. No, really, IMHO it is enough to show either the commit name or the blob name of the file. After all, you are not interested in the date that this file was last committed, but in the _contents_. So why not go for the contents? With CVS/SVN you only have the chance to do that by date or version number. With git, we have a more powerful way: we do it by a hash of the contents. > > As Randal already suggested: if you need something like this, you > > better have a build procedure which replaced $Date$ _at a given time_ > > (make install) with the current date. > > But that's not what I want. Then my build procedure would need to do a > "git status", or whatever you use to get the last commit information > about a file, on each file that is changed and is to be installed. It > would be a lot easier if that was done already on checkout through some > kind of hook. If it's not what you want, I suggest rethinking what you want ;-) Otherwise it is scripting time for you. It's easy enough with git. Ciao, Dscho ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 10:02 ` Johannes Schindelin @ 2007-10-12 10:50 ` Peter Karlsson 2007-10-12 11:05 ` Johannes Sixt ` (3 more replies) 0 siblings, 4 replies; 27+ messages in thread From: Peter Karlsson @ 2007-10-12 10:50 UTC (permalink / raw) To: git; +Cc: Johannes Schindelin Hi! > please do not play games with the To: header. We have a policy here > (which is supposed to be good netiquette) that we keep people in the Cc: > list that we respond to. Sorry, didn't mean to do anything. I try to avoid Cc'ing people that are on the mailing list, and apparently strange things happened that kept the mailing list only as Cc. I'll try to remember setting To: properly. Back on-topic: > But don't you see? When switching branches, this totally breaks down. Why would it? If the file is the same on both branches, nothing would happen (it is still the same version), and if the file is different, it gets changed anyway, and a new keyword expansion would take place. > No, really, IMHO it is enough to show either the commit name or the > blob name of the file. After all, you are not interested in the date > that this file was last committed, but in the _contents_. Yes, but I want it on the lowest addressable unit size, i.e on the file level (I could possibly want to have the last commit for a set of files when I have something that get generated from several sources, but that is rare for a regular website, unless since javascripts and stylesheets etc. are delivered separately). Already today when you do "git log" on a file, you get the log filtered for only changes to that file. So the mechanisms seem already to be there, I just need to figure out how to apply them to what I want. > So why not go for the contents? With CVS/SVN you only have the > chance to do that by date or version number. With git, we have a more > powerful way: we do it by a hash of the contents. Yes, but the hash if of "everything". I'm not interested in "everything" in this context, and I don't want to have a separate git repository for each file... > If it's not what you want, I suggest rethinking what you want ;-) > Otherwise it is scripting time for you. It's easy enough with git. That's what I'm trying to figure out. I assume it would be possible to do with some kind of hook that is run on checkout. But I can't figure out how to do that. -- \\// Peter - http://www.softwolves.pp.se/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 10:50 ` Peter Karlsson @ 2007-10-12 11:05 ` Johannes Sixt 2007-10-12 11:21 ` Lars Hjemli ` (2 subsequent siblings) 3 siblings, 0 replies; 27+ messages in thread From: Johannes Sixt @ 2007-10-12 11:05 UTC (permalink / raw) To: Peter Karlsson; +Cc: git, Johannes Schindelin Peter Karlsson schrieb: >> If it's not what you want, I suggest rethinking what you want ;-) >> Otherwise it is scripting time for you. It's easy enough with git. > > That's what I'm trying to figure out. I assume it would be possible to > do with some kind of hook that is run on checkout. But I can't figure > out how to do that. Read about the 'filter' attribute (clean and smudge filters), e.g. here: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html This is the place to tie a script to checkouts. How the scripts derive the information that they put in the checked-out files, is a different matter. -- Hannes ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 10:50 ` Peter Karlsson 2007-10-12 11:05 ` Johannes Sixt @ 2007-10-12 11:21 ` Lars Hjemli 2007-10-12 11:34 ` Johannes Schindelin 2007-10-12 12:57 ` Jan Hudec 3 siblings, 0 replies; 27+ messages in thread From: Lars Hjemli @ 2007-10-12 11:21 UTC (permalink / raw) To: Peter Karlsson; +Cc: git, Johannes Schindelin On 10/12/07, Peter Karlsson <peter@softwolves.pp.se> wrote: > Johannes said: > > So why not go for the contents? With CVS/SVN you only have the > > chance to do that by date or version number. With git, we have a more > > powerful way: we do it by a hash of the contents. > > Yes, but the hash if of "everything". I'm not interested in > "everything" in this context, and I don't want to have a separate git > repository for each file... Try this: $ echo 'File revision $Id$' > index.html $ echo "*.html ident" > .gitattributes $ git add index.html .gitattributes $ git commit >From now on, the '$Id' in index.html gets expanded to the SHA1 of the content of index.html (not the commit SHA1) each time you checkout (and removed when you commit) If you still want 'last modified date', the closest thing in git is 'commit date' which you can also get for free: $ echo 'Last commit: $Format:%cd$' > index.html $ echo "*.html export-subst" > .gitattributes $ git add index.html .gitattributes $ git commit $ git archive --prefix=test/ HEAD | tar -x $ cat test/index.html For all supported keywords, take a look at the 'git-log --pretty=format' option -- larsh ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 10:50 ` Peter Karlsson 2007-10-12 11:05 ` Johannes Sixt 2007-10-12 11:21 ` Lars Hjemli @ 2007-10-12 11:34 ` Johannes Schindelin 2007-10-15 14:03 ` Peter Karlsson 2007-10-12 12:57 ` Jan Hudec 3 siblings, 1 reply; 27+ messages in thread From: Johannes Schindelin @ 2007-10-12 11:34 UTC (permalink / raw) To: Peter Karlsson; +Cc: git Hi, On Fri, 12 Oct 2007, Peter Karlsson wrote: > > But don't you see? When switching branches, this totally breaks down. > > Why would it? If the file is the same on both branches, nothing would > happen (it is still the same version), and if the file is different, it > gets changed anyway, and a new keyword expansion would take place. Finding out which commit last changed that file is slow. That's why it breaks down. It is possible, yes. But then I think that you really do not want this. You are just to used to CVS/SVN to see that there is a much better way in git. > > No, really, IMHO it is enough to show either the commit name or the > > blob name of the file. After all, you are not interested in the date > > that this file was last committed, but in the _contents_. > > Yes, but I want it on the lowest addressable unit size, i.e on the file > level (I could possibly want to have the last commit for a set of files > when I have something that get generated from several sources, but that > is rare for a regular website, unless since javascripts and stylesheets > etc. are delivered separately). The lowest addressable unit size is the file level, alright. And $Id$ contains the blob name. IOW it contains a key to retrieve the contents of exactly this version of the file. Ciao, Dscho ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 11:34 ` Johannes Schindelin @ 2007-10-15 14:03 ` Peter Karlsson 2007-10-15 14:28 ` Johannes Schindelin 0 siblings, 1 reply; 27+ messages in thread From: Peter Karlsson @ 2007-10-15 14:03 UTC (permalink / raw) To: git; +Cc: Johannes Schindelin Hi! > Finding out which commit last changed that file is slow. That's why > it breaks down. That might be, but it only needs to be done when a file is updated. > You are just to used to CVS/SVN to see that there is a much better > way in git. I can see that favouring the argument that having a $Id$ that gives me the global state id when the file was last updated is a bad idea. Fair enough. Give me a local state tham (which you did, hash id for the file contents). My problem now is the file date. That could possibly be fixed by having it updated before I check in the file. So, to summarize, if I've understood the responses here correctly, what I really want is: on commit: - replace "$Date$" (or whatever) with the current time. - store the contents. on checkout: - update the file. - replace "$Id$" (ditto) with a magic identifier for the file state. - update git's state so that it doesn't see the "$Id$" expansion as a change in the file contents. Now the question is: Where can I find documentation on how to do this (i.e what should I search for--"hooks"?)? And, if this goes into the ".git" directory, can I still have it replicated when I clone a repository? I noticed that my ".git/ignore" file wasn't replicated and that I had to replace it with a local ".gitignore" to get it under version control. -- \\// Peter - http://www.softwolves.pp.se/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-15 14:03 ` Peter Karlsson @ 2007-10-15 14:28 ` Johannes Schindelin 0 siblings, 0 replies; 27+ messages in thread From: Johannes Schindelin @ 2007-10-15 14:28 UTC (permalink / raw) To: Peter Karlsson; +Cc: git Hi, On Mon, 15 Oct 2007, Peter Karlsson wrote: > I wrote: > > > Finding out which commit last changed that file is slow. That's why > > it breaks down. > > That might be, but it only needs to be done when a file is updated. Almost. It also needs to be updated when switching branches. For every file. Since the commit blamed for the current version could be different for every file. > > You are just to used to CVS/SVN to see that there is a much better way > > in git. > > I can see that favouring the argument that having a $Id$ that gives me > the global state id when the file was last updated is a bad idea. Fair > enough. Give me a local state tham (which you did, hash id for the file > contents). > > My problem now is the file date. That could possibly be fixed by having > it updated before I check in the file. > > > So, to summarize, if I've understood the responses here correctly, what > I really want is: > > on commit: > - replace "$Date$" (or whatever) with the current time. I think that would be more "on edit". > - store the contents. > > on checkout: > - update the file. > - replace "$Id$" (ditto) with a magic identifier for the file state. > - update git's state so that it doesn't see the "$Id$" expansion > as a change in the file contents. > > Now the question is: Where can I find documentation on how to do this > (i.e what should I search for--"hooks"?)? For the $Id$ thing: Documentation/gitattributes.txt. For the $Date$ thing: Documentation/hooks.txt, and Documentation/git-rev-list.txt. You'll need to roll your own thing there, since Git oldtimers feel that what you want to do is the wrong thing (see Randal's comment on generating it as part of the build process). What you want to do might be frowned upon by many on the list, but it is certainly doable. See ExampleScripts on the wiki for inspiration. > And, if this goes into the ".git" directory, can I still have it > replicated when I clone a repository? I noticed that my ".git/ignore" > file wasn't replicated and that I had to replace it with a local > ".gitignore" to get it under version control. No, there is not way to have it replicated into the .git directory. The common way would be to either have it installed as templates, so that every user of yours gets them automatically, or to check them in under different names, and make every user install them by hand. The rationale: every cloner is free to choose what hooks she wants to run. So checking in such hooks is always understood as suggestion what hooks to install. Ciao, Dscho ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 10:50 ` Peter Karlsson ` (2 preceding siblings ...) 2007-10-12 11:34 ` Johannes Schindelin @ 2007-10-12 12:57 ` Jan Hudec 3 siblings, 0 replies; 27+ messages in thread From: Jan Hudec @ 2007-10-12 12:57 UTC (permalink / raw) To: Peter Karlsson; +Cc: git, Johannes Schindelin [-- Attachment #1: Type: text/plain, Size: 3068 bytes --] On Fri, Oct 12, 2007 at 11:50:51 +0100, Peter Karlsson wrote: > > But don't you see? When switching branches, this totally breaks down. > > Why would it? If the file is the same on both branches, nothing would > happen (it is still the same version), and if the file is different, it > gets changed anyway, and a new keyword expansion would take place. It does not -- the blob ID is the same. And you can indeed get $Id$ expanded to that (see gitattributes(5)). However, that's the ONLY thing that is the same. The date of last modification or ID of commit that last touched that file might not. Why? Because git tracks content, not history. The trees and blobs (files) are identified by SHA1 hashes of their content. Only commit objects add the notion of history. Thus if two commits contain file with the same text, it's the same file. Even if the file is the same in those commit purely by accident. > > No, really, IMHO it is enough to show either the commit name or the > > blob name of the file. After all, you are not interested in the date > > that this file was last committed, but in the _contents_. > > Yes, but I want it on the lowest addressable unit size, i.e on the file > level (I could possibly want to have the last commit for a set of files > when I have something that get generated from several sources, but that > is rare for a regular website, unless since javascripts and stylesheets > etc. are delivered separately). > > Already today when you do "git log" on a file, you get the log filtered > for only changes to that file. So the mechanisms seem already to be > there, I just need to figure out how to apply them to what I want. Yes. But you need the (current) commit for that. Now if a file foo is the same on branches A and B, switching between them will not touch that file, but git log foo may well give you completely different results. That's why there's no date or commit that last touched a file. > > So why not go for the contents? With CVS/SVN you only have the > > chance to do that by date or version number. With git, we have a more > > powerful way: we do it by a hash of the contents. > > Yes, but the hash if of "everything". I'm not interested in > "everything" in this context, and I don't want to have a separate git > repository for each file... > > > If it's not what you want, I suggest rethinking what you want ;-) > > Otherwise it is scripting time for you. It's easy enough with git. > > That's what I'm trying to figure out. I assume it would be possible to > do with some kind of hook that is run on checkout. But I can't figure > out how to do that. If you read the (already mentioned) gitattributes(5) manpage, you'll find description of smudge and clean filters. They will be applied to each file written out to the tree and read back respectively. But be sure to understand why you can't -- for principial, not techical reasons -- have the date or commit ID expanded correctly in all cases. -- Jan 'Bulb' Hudec <bulb@ucw.cz> [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 5:26 ` Peter Karlsson 2007-10-12 10:02 ` Johannes Schindelin @ 2007-10-12 19:08 ` Salikh Zakirov 2007-10-12 22:42 ` Johannes Schindelin 1 sibling, 1 reply; 27+ messages in thread From: Salikh Zakirov @ 2007-10-12 19:08 UTC (permalink / raw) To: git Peter Karlsson wrote: > But that's not what I want. Then my build procedure would need to do a > "git status", or whatever you use to get the last commit information > about a file, on each file that is changed and is to be installed. It > would be a lot easier if that was done already on checkout through some > kind of hook. For what it's worth, I've made a small exercise on git scripting (which I'm total newbie in), and tried to use filter mechanism (smudge/clean) for solving the problem Peter stated. Fundamental problems of this approach were discussed in full on the mailing list, however, as I understand Peter's situation, they do not apply, as the web site workspace is 'checkout-only', and no actual work (commits) are made there. Thus, it will not cause any merge problems etc. Anyway, smudge/clean does not give the immediate solution to the problem because of smaller technical shortcomings: * smudge filter is not passed a name of file being checked out, so it is not possible to exactly find the commit identifier. However, this is alleviated by the fact that 'smudge' is only being run for the changed files, so the last commit *is* the needed one. * smudge filter is not passed a commit identifier. This is a bit more serious, as this information is nowhere to get from otherwise. I tried to use 'HEAD' value, but apparently it is not yet updated at the moment 'smudge' is being run, so the files end up with the date of the "previous" commit rather than the commit being checked out. "Previous" means the commit that was checked out before. The problem gets worse if different branch is checkout out, as the files get the timestamp of a previous branch. AFAIR, lack of information in smudge filter was intentional, to discourage this particular use of smudge/clean mechanism. However, I think this can be reconsidered given the Peter's use case: "checkout-only" workspace for immediate publishing to webserver. Alternatively, anyone interested in this use case could implement additional smudge arguments as a site-local patch. And then, there are small annoyances, which seems to be inevitable: * if you change 'clean' filter and check out earlier revision, it will be reported as having modifications (due to changed 'clean' definition). Below is what I ended up with: .gitattributes: * filter=date .git/config: [filter "date"] smudge = .git/smudge clean = .git/clean .git/clean: #!/usr/bin/perl -p s#\$Date[^\$]*\$#\$Date\$#; .git/smudge: #!/usr/bin/perl use POSIX qw(strftime); $branch = `git-symbolic-ref HEAD`; chomp($branch); $rev = `git-rev-list -n 1 $branch`; chomp($rev); open REV, "git show --pretty=raw $rev|"; $time = time; # default to current time while (<REV>) { if (/^committer.* (\d+) [\-+]\d*$/) { $time = $1; } } close REV; $date = strftime "%Y-%m-%d %H:%M:%S", localtime($time); while (<>) { s#\$Date[^\$]*\$#\$Date: $date\$#; print; } ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 19:08 ` Salikh Zakirov @ 2007-10-12 22:42 ` Johannes Schindelin 2007-10-12 23:52 ` Zakirov Salikh 0 siblings, 1 reply; 27+ messages in thread From: Johannes Schindelin @ 2007-10-12 22:42 UTC (permalink / raw) To: Salikh Zakirov; +Cc: git Hi, On Sat, 13 Oct 2007, Salikh Zakirov wrote: > * smudge filter is not passed a name of file being checked out, > so it is not possible to exactly find the commit identifier. > However, this is alleviated by the fact that 'smudge' is only being run > for the changed files, so the last commit *is* the needed one. No. When changing branches, this is not the commit you think it is. But maybe you humour me and tell me in which context such a smudge filter is of use. I have yet to encounter an argument that convinces me. Ciao, Dscho ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 22:42 ` Johannes Schindelin @ 2007-10-12 23:52 ` Zakirov Salikh 0 siblings, 0 replies; 27+ messages in thread From: Zakirov Salikh @ 2007-10-12 23:52 UTC (permalink / raw) To: Johannes Schindelin; +Cc: git, Peter Karlsson On 13/10/2007, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > > * smudge filter is not passed a name of file being checked out, > > so it is not possible to exactly find the commit identifier. > > However, this is alleviated by the fact that 'smudge' is only being run > > for the changed files, so the last commit *is* the needed one. > > No. > When changing branches, this is not the commit you think it is. Exactly. When switching branches, or merging or fast-forwarding several commits, the last commit may not be correct. The last commit is only correct for the files being updated by the fast-forward to exactly one commit. Which seem to be pretty natural for the use case of checkout-only web-published workspace. > But maybe you humour me and tell me in which context such a smudge filter > is of use. I have yet to encounter an argument that convinces me. Your comment prompted me to think about a narrower case of fast-forwaring to one revision. In that case, 'smudge' script can have commit identifier in FETCH_HEAD, so the example script from previous message with a little modification: $rev = `git-rev-parse FETCH_HEAD` gives *exact* solution to the originally stated problem, though for the specific case when the web server directory is a checkout-only working directory, which pulls changes automatically from master server (as opposed to, e.g., pushing changes to web server). Even if the server pulls several revisions at once, it is likely that they are done in a close succession (otherwise automated update would have picked them separately), and important part in web page timestamp is usually date. Too bad I do not really have a web server and do not need to maintain timestamps in web pages ... :) git scriptability always amazed me. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 15:09 ` Randal L. Schwartz 2007-10-11 15:59 ` Oliver Kullmann @ 2007-10-11 17:55 ` Peter Karlsson 2007-10-11 19:21 ` Alex Riesen 2007-10-11 21:20 ` Sam Vilain 1 sibling, 2 replies; 27+ messages in thread From: Peter Karlsson @ 2007-10-11 17:55 UTC (permalink / raw) Cc: git Randal L. Schwartz: > That's not a job for a source code manager to do. It's a job for your > build/install tool. Since there is no build step involved (my web site is just a CVS checkout at the moment), it's a job for the checkout step. I'd really want to avoid having a separate copy of the web site just so that I can do a "make install". That would sort of negate the savings in disk space I hope seeing by moving from CVS to Git. -- \\// Peter - http://www.softwolves.pp.se/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 17:55 ` Peter Karlsson @ 2007-10-11 19:21 ` Alex Riesen 2007-10-12 5:27 ` Peter Karlsson 2007-10-11 21:20 ` Sam Vilain 1 sibling, 1 reply; 27+ messages in thread From: Alex Riesen @ 2007-10-11 19:21 UTC (permalink / raw) To: Peter Karlsson; +Cc: git Peter Karlsson, Thu, Oct 11, 2007 19:55:05 +0200: > >That's not a job for a source code manager to do. It's a job for your > >build/install tool. > > Since there is no build step involved (my web site is just a CVS checkout > at the moment), it's a job for the checkout step. I'd really want to avoid > having a separate copy of the web site just so that I can do a "make > install". That's confusing. If your web site is just a checkout, what is the "make install" for? If it is a repo, you have the version information anyway, and at all times. And if this extra step is indeed present, why can't the "make install" just save the HEAD somewhere for later reference? > That would sort of negate the savings in disk space I hope seeing > by moving from CVS to Git. You'll find you have plenty of savings for anything. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 19:21 ` Alex Riesen @ 2007-10-12 5:27 ` Peter Karlsson 2007-10-12 17:05 ` Barry Fishman 0 siblings, 1 reply; 27+ messages in thread From: Peter Karlsson @ 2007-10-12 5:27 UTC (permalink / raw) Cc: git Alex Riesen: > That's confusing. If your web site is just a checkout, what is the "make > install" for? Exactly. That's what I wondering. > If it is a repo, you have the version information anyway, and at all > times. Yes, but not embedded in the page in a format that is visible to the visitor. For CVS I use something like this: <p class="date">$Date$</p> to embed the last update time into the page. -- \\// Peter - http://www.softwolves.pp.se/ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 5:27 ` Peter Karlsson @ 2007-10-12 17:05 ` Barry Fishman 2007-10-12 17:44 ` Linus Torvalds 2007-10-12 17:51 ` Florian Weimer 0 siblings, 2 replies; 27+ messages in thread From: Barry Fishman @ 2007-10-12 17:05 UTC (permalink / raw) To: git Peter Karlsson <peter@softwolves.pp.se> writes: > Yes, but not embedded in the page in a format that is visible to the > visitor. For CVS I use something like this: > > <p class="date">$Date$</p> > > to embed the last update time into the page. > I guess everyone moving from CVS/SVN to Git faces rethinking of what the RCS markers really mean in the context of their project. In my case the identifier was just a away of seeing when the file was last changed, and who did it. I decided this fit better as an editor function, rather than a checkin function. I changed my editor (Emacs) to convert RCS Ids to timestamps when I opened a file for reading. This would fix old files. When i wrote out files I would update the timestamp before writing them (via emacs's timestamp package). I didn't have to think about it as my RCS Id stamped files slowly evolve into my editor stamped ones. I'm sure I could do something similar in VIM, or with a script encapsulating another editor. This actually worked out better for me. Now the timestamps were updated even when I hadn't yet checked in the file. Since I test things before checking them in, I did not have my file changed after testing by the checkin process. I could find the the commit assocated with the file fairly quickly using "git log" and finding the commit for the file just after its timestamp. -- Barry Fishman ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 17:05 ` Barry Fishman @ 2007-10-12 17:44 ` Linus Torvalds 2007-10-12 17:51 ` Florian Weimer 1 sibling, 0 replies; 27+ messages in thread From: Linus Torvalds @ 2007-10-12 17:44 UTC (permalink / raw) To: Barry Fishman; +Cc: git On Fri, 12 Oct 2007, Barry Fishman wrote: > > I changed my editor (Emacs) to convert RCS Ids to timestamps when I > opened a file for reading. This would fix old files. When i wrote out > files I would update the timestamp before writing them (via emacs's > timestamp package). I didn't have to think about it as my RCS Id > stamped files slowly evolve into my editor stamped ones. I'm sure I > could do something similar in VIM, or with a script encapsulating > another editor. I think it might also be potentially interesting to make this just be a pre-commit hook - although your point that doing it in the editor is to some degree even nicer, because it also means that it shows up in diffs even *before* you commit. But if you want to explore the pre-commit hook approach, what it would basically boild down to is that at that point you have a list of all files that have changed, and then you could run some script on them to change them even further. I'm sure you'd find some problems with the approach, and I think it absolutely sucks for merging (ie trivially you'll have all the merge problems people *always* have with RCS Id's, and now you need to teach the auto-merger to hide them from you), but it's probably better than trying to do it at some "core level" (which screws up things like switching branches etc). Linus ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-12 17:05 ` Barry Fishman 2007-10-12 17:44 ` Linus Torvalds @ 2007-10-12 17:51 ` Florian Weimer 1 sibling, 0 replies; 27+ messages in thread From: Florian Weimer @ 2007-10-12 17:51 UTC (permalink / raw) To: git * Barry Fishman: > I changed my editor (Emacs) to convert RCS Ids to timestamps when I > opened a file for reading. This would fix old files. When i wrote out > files I would update the timestamp before writing them (via emacs's > timestamp package). I didn't have to think about it as my RCS Id > stamped files slowly evolve into my editor stamped ones. I'm sure I > could do something similar in VIM, or with a script encapsulating > another editor. The downside is that this causes totally unncessary conflicts when merging. Maybe a custom merge handler could deal with that, though. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 17:55 ` Peter Karlsson 2007-10-11 19:21 ` Alex Riesen @ 2007-10-11 21:20 ` Sam Vilain 1 sibling, 0 replies; 27+ messages in thread From: Sam Vilain @ 2007-10-11 21:20 UTC (permalink / raw) To: Peter Karlsson; +Cc: git Peter Karlsson wrote: > Randal L. Schwartz: > >> That's not a job for a source code manager to do. It's a job for your >> build/install tool. > > Since there is no build step involved (my web site is just a CVS checkout at > the moment), it's a job for the checkout step. I'd really want to avoid > having a separate copy of the web site just so that I can do a "make > install". That would sort of negate the savings in disk space I hope seeing > by moving from CVS to Git. The problem is that asking for the "last commit that changed a file" is one of those features which comes out of the wash with proper merge support. There is often no clear answer to that question. Here's an example. Say two people apply a patch on their own branches, which are subsequently merged. The file was the same on both branches; the commits may have exactly the same date, but different committers. Now, consider what happens as you are switching branches. Instead of just being able to check the file identity in the tree, the system has to somehow know that the (derived) ancestry of the file is different, and now the content has to change. That makes something that was extremely fast, slow. It's the sort of thing that's possible to arrange to work using hooks (with whatever arbitrary decisions you choose to make for the areas where it would be ambiguous), but no-one bothered because people realised that it probably means you're trying to encapsulate the information in the wrong place. Sam. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: RCS keyword expansion 2007-10-11 14:47 RCS keyword expansion Peter Karlsson 2007-10-11 15:02 ` Johannes Sixt 2007-10-11 15:09 ` Randal L. Schwartz @ 2007-10-11 19:16 ` Lars Hjemli 2 siblings, 0 replies; 27+ messages in thread From: Lars Hjemli @ 2007-10-11 19:16 UTC (permalink / raw) To: Peter Karlsson; +Cc: git On 10/11/07, Peter Karlsson <peter@softwolves.pp.se> wrote: > I've looked and looked, but cannot figure out how to do RCS/CVS style > keyword expansion with Git. If you look at 'man gitattributes' you'll find a description of the 'ident' attribute which is expanded to the SHA1 of the containing file during checkout. There is also a description of the 'export-subst' attribute which can be used to expand keywords when generating tar/zip files with 'git-archive'. It supports commit SHA1 and date, among others. Btw: using git-archive means that you don't need a local repository on the webserver, you only need a proper git installation. Essentially, you can update your webserver 'checkout' with something like this: $ git archive --remote=<url> --prefix=somepath/ master | tar -x -- larsh ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2007-10-15 14:29 UTC | newest] Thread overview: 27+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-10-11 14:47 RCS keyword expansion Peter Karlsson 2007-10-11 15:02 ` Johannes Sixt 2007-10-11 15:09 ` Randal L. Schwartz 2007-10-11 15:59 ` Oliver Kullmann 2007-10-11 18:09 ` Alex Riesen 2007-10-11 20:47 ` Johannes Schindelin 2007-10-11 21:35 ` Sam Vilain 2007-10-12 5:26 ` Peter Karlsson 2007-10-12 10:02 ` Johannes Schindelin 2007-10-12 10:50 ` Peter Karlsson 2007-10-12 11:05 ` Johannes Sixt 2007-10-12 11:21 ` Lars Hjemli 2007-10-12 11:34 ` Johannes Schindelin 2007-10-15 14:03 ` Peter Karlsson 2007-10-15 14:28 ` Johannes Schindelin 2007-10-12 12:57 ` Jan Hudec 2007-10-12 19:08 ` Salikh Zakirov 2007-10-12 22:42 ` Johannes Schindelin 2007-10-12 23:52 ` Zakirov Salikh 2007-10-11 17:55 ` Peter Karlsson 2007-10-11 19:21 ` Alex Riesen 2007-10-12 5:27 ` Peter Karlsson 2007-10-12 17:05 ` Barry Fishman 2007-10-12 17:44 ` Linus Torvalds 2007-10-12 17:51 ` Florian Weimer 2007-10-11 21:20 ` Sam Vilain 2007-10-11 19:16 ` Lars Hjemli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).