* 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: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 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 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
* 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 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 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 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-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: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 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: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-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-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
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).