git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 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).