* Implementing $Date$ substitution - problem with git status
@ 2009-08-09 19:37 Peter Krefting
2009-08-09 20:52 ` Johannes Sixt
2009-08-13 6:47 ` Implementing $Date$ substitution - solution using pre-commit Peter Krefting
0 siblings, 2 replies; 8+ messages in thread
From: Peter Krefting @ 2009-08-09 19:37 UTC (permalink / raw)
To: Git List
Hi!
I finally got around to moving my web site repository over from CVS to Git,
and to not have to redo everything about how it is set up, I set up a filter
that fakes CVS' handling of "$Date$" keywords. Since I cannot access any
information about the file from the "smudge" filter, I set up a "clean"
filter that edits the $Date$ token on "git add":
#!/usr/bin/perl -wTp -i.bak
if (/\$Date:?[^\$]*\$/)
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year + 1900,
$mon + 1, $mday, $hour, $min, $sec);
s/\$Date:?[^\$]*\$/\$Date: ${now} \$/;
}
In .gitattributes I have lines like:
*.html filter=date crlf=true ident
and filter.date.clean is set to point to the script above in .git/config.
This works fine, except that I have some problems with files that I cannot
get to be "clean" in git status. "git diff" shows only a difference in the
"$Date$" token, which is different each time I run "git diff" (the "+" line
shows the current time):
diff --git a/.htaccess b/.htaccess
index 2dfbc32..d8ac343 100644
--- a/.htaccess
+++ b/.htaccess
@@ -2,7 +2,7 @@
# -----------------------------------------------------
# $Id$
-# $Date: 2009-08-09 19:52:30 $
+# $Date: 2009-08-09 20:31:56 $
[...]
Strangely, the $Id$ line above (which is handled by me adding the "ident"
attribute to all text files), does not exhibit the same problem.
Doing "git reset --hard" or "git checkout master filename" does not help,
the file is still believed to be modified by git.
Does anyone know if there is a way to get this to work, or am I screwed for
trying to do things I'm not supposed to? :-)
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Implementing $Date$ substitution - problem with git status
2009-08-09 19:37 Implementing $Date$ substitution - problem with git status Peter Krefting
@ 2009-08-09 20:52 ` Johannes Sixt
2009-08-10 4:41 ` Peter Krefting
2009-08-12 6:54 ` Peter Krefting
2009-08-13 6:47 ` Implementing $Date$ substitution - solution using pre-commit Peter Krefting
1 sibling, 2 replies; 8+ messages in thread
From: Johannes Sixt @ 2009-08-09 20:52 UTC (permalink / raw)
To: Peter Krefting; +Cc: Git List
On Sonntag, 9. August 2009, Peter Krefting wrote:
> I finally got around to moving my web site repository over from CVS to Git,
> and to not have to redo everything about how it is set up, I set up a
> filter that fakes CVS' handling of "$Date$" keywords. Since I cannot access
> any information about the file from the "smudge" filter, I set up a "clean"
> filter that edits the $Date$ token on "git add":
>
> #!/usr/bin/perl -wTp -i.bak
> if (/\$Date:?[^\$]*\$/)
> {
> my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
> localtime(); my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year +
> 1900, $mon + 1, $mday, $hour, $min, $sec);
> s/\$Date:?[^\$]*\$/\$Date: ${now} \$/;
> }
>
> In .gitattributes I have lines like:
>
> *.html filter=date crlf=true ident
>
> and filter.date.clean is set to point to the script above in .git/config.
>
> This works fine, except that I have some problems with files that I cannot
> get to be "clean" in git status. "git diff" shows only a difference in the
> "$Date$" token, which is different each time I run "git diff" (the "+" line
> shows the current time):
>
> diff --git a/.htaccess b/.htaccess
> index 2dfbc32..d8ac343 100644
> --- a/.htaccess
> +++ b/.htaccess
> @@ -2,7 +2,7 @@
> # -----------------------------------------------------
>
> # $Id$
> -# $Date: 2009-08-09 19:52:30 $
> +# $Date: 2009-08-09 20:31:56 $
> [...]
The clean filter is applied before 'git diff' generates the diff. Since you
have unstaged changes (I take [...] to mean this), you see a new date on
every invocation.
After 'git add .htaccess' subsequent 'git diff' should not show any changes.
> Strangely, the $Id$ line above (which is handled by me adding the "ident"
> attribute to all text files), does not exhibit the same problem.
>
> Doing "git reset --hard" or "git checkout master filename" does not help,
> the file is still believed to be modified by git.
Now, that's an entirely different problem, and I think that there is a bug. I
have observed this as well with my own clean filter sometimes, but not
always. I haven't found a recipe that reliably exhibits the problem.
-- Hannes
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Implementing $Date$ substitution - problem with git status
2009-08-09 20:52 ` Johannes Sixt
@ 2009-08-10 4:41 ` Peter Krefting
2009-08-12 6:54 ` Peter Krefting
1 sibling, 0 replies; 8+ messages in thread
From: Peter Krefting @ 2009-08-10 4:41 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Git List
Johannes Sixt:
> The clean filter is applied before 'git diff' generates the diff. Since you
> have unstaged changes (I take [...] to mean this), you see a new date on
> every invocation.
Sorry for being unclear; no, the $Date$ line is the only change that shows
up. I removed the surrounding context because I didn't want to publish them.
On another machine, there is another file that exhibits the same problem.
> After 'git add .htaccess' subsequent 'git diff' should not show any changes.
But then I need to check it in again, and I'd like to avoid that, if possible.
Is it possible to have a filter run on "commit" instead of "add"? (Or is
"commit" just moving changes from the index to the repository, making that
impossible?)
>> Doing "git reset --hard" or "git checkout master filename" does not
>> help, the file is still believed to be modified by git.
>
> Now, that's an entirely different problem, and I think that there is a
> bug. I have observed this as well with my own clean filter sometimes, but
> not always. I haven't found a recipe that reliably exhibits the problem.
It seems to be triggered by using my date script and doing
git add file
git commit file
git reset --hard file
the last command gives me a local copy with the keyword expanded, but marked
dirty.
Is it possible to have "git add" expand the keyword (both the Git-internal
"ident", i.e "$Id$", and my "$Date$")? Would duplicating the "clean" filter
as a "smudge" one accomplish that?
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Implementing $Date$ substitution - problem with git status
2009-08-09 20:52 ` Johannes Sixt
2009-08-10 4:41 ` Peter Krefting
@ 2009-08-12 6:54 ` Peter Krefting
2009-08-12 8:36 ` Problems with filters and git status - reproduction steps Peter Krefting
1 sibling, 1 reply; 8+ messages in thread
From: Peter Krefting @ 2009-08-12 6:54 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Git List
Johannes Sixt:
>> Doing "git reset --hard" or "git checkout master filename" does not
>> help, the file is still believed to be modified by git.
> Now, that's an entirely different problem, and I think that there is a
> bug. I have observed this as well with my own clean filter sometimes, but
> not always. I haven't found a recipe that reliably exhibits the problem.
After som examination, it seems to be caused by the way I imported the CVS
history: I kept all the $ keywords expanded in history (so that if I check
out an old version from Git, it looks like it did in CVS). This means that
still in the latest revision of several files, I have "$Id$" lines checked
in in CVS format.
However, as I have set the "ident" attribute, Git wants to expand it itself
and check in files with "$Id$". When I do a reset, it seems it records the
entry as clean against a version stored with just "$Id$", but the record in
history has an expanded "$Id$", and the entry is thus never deemed clean.
I can probably work around this by removing the "$Id$" attributes, or by
removing the "ident" rule.
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Problems with filters and git status - reproduction steps
2009-08-12 6:54 ` Peter Krefting
@ 2009-08-12 8:36 ` Peter Krefting
2009-08-12 8:55 ` Michael J Gruber
0 siblings, 1 reply; 8+ messages in thread
From: Peter Krefting @ 2009-08-12 8:36 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Git List
Peter Krefting:
> However, as I have set the "ident" attribute, Git wants to expand it itself
> and check in files with "$Id$". When I do a reset, it seems it records the
> entry as clean against a version stored with just "$Id$", but the record in
> history has an expanded "$Id$", and the entry is thus never deemed clean.
Actually, that is not the case. It seems to be the filter that causes the
problems, all by itself. I cannot seem to reproduce this *reliably*. I tried
setting up a minimal repository and a reproduction recipe, but I get
different behaviour when I perform the steps manually, and when I run it
from a shell script.
Here is the reproduction recipe:
#!/bin/bash
# Reproduction recipe for $Date$ dirty issue
ORIGINREPO=git://git.debian.org/users/peterk/gitfilterproblem.git
DESTINATIONREPO=gitfilterproblem-testrepo
# Set up repository
echo -- Cloning
git clone ${ORIGINREPO} ${DESTINATIONREPO}
cd ${DESTINATIONREPO}
# Status should be clean
echo -- After cloning, status should be clean
git status
# Set up filter
echo -- Set up filter, status should be clean
./reposetup.sh
git status
# Create tracking branch
echo -- Create tracking branch for changed file, status should be clean
git branch --track changed-text-files origin/changed-text-files
git status
# Merge the branch
echo -- Merge the changes from the branch, now status gets unclean
git merge changed-text-files
echo
git status
git diff
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problems with filters and git status - reproduction steps
2009-08-12 8:36 ` Problems with filters and git status - reproduction steps Peter Krefting
@ 2009-08-12 8:55 ` Michael J Gruber
2009-08-12 9:25 ` Peter Krefting
0 siblings, 1 reply; 8+ messages in thread
From: Michael J Gruber @ 2009-08-12 8:55 UTC (permalink / raw)
To: Peter Krefting; +Cc: Johannes Sixt, Git List
Peter Krefting venit, vidit, dixit 12.08.2009 10:36:
> ORIGINREPO=git://git.debian.org/users/peterk/gitfilterproblem.git
> DESTINATIONREPO=gitfilterproblem-testrepo
>
> # Set up repository
> echo -- Cloning
> git clone ${ORIGINREPO} ${DESTINATIONREPO}
> cd ${DESTINATIONREPO}
>
> # Status should be clean
> echo -- After cloning, status should be clean
> git status
>
> # Set up filter
> echo -- Set up filter, status should be clean
> ./reposetup.sh
> git status
I get "Changed but not updated" already here!
Also, what's your git version? There have been some fix-ups recently
regarding the interaction between filters/textconv and assumptions of
the code about dirtiness of the worktree.
>
> # Create tracking branch
> echo -- Create tracking branch for changed file, status should be clean
> git branch --track changed-text-files origin/changed-text-files
> git status
>
> # Merge the branch
> echo -- Merge the changes from the branch, now status gets unclean
> git merge changed-text-files
> echo
> git status
> git diff
Do you really want the date in the checked-in version of the file? I
would assume otherwise. Then your clean filter should really be the
smudge filter, and you would need a clean filter to go with it (remove
the date and restore the keyword).
Michael
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Problems with filters and git status - reproduction steps
2009-08-12 8:55 ` Michael J Gruber
@ 2009-08-12 9:25 ` Peter Krefting
0 siblings, 0 replies; 8+ messages in thread
From: Peter Krefting @ 2009-08-12 9:25 UTC (permalink / raw)
To: Michael J Gruber; +Cc: Johannes Sixt, Git List
Michael J Gruber:
> I get "Changed but not updated" already here!
With git 1.5.6.5, I do get that. With git 1.6.4, I seem to only get it after
the last step.
I have 1.5.6.5 on the server with the master repo, and am running 1.6.4 on
the client (although when I ran the recipe through a shell script, I got the
unclean status earlier, which made me think it ran an earlier version I have
installed in another directory).
> Do you really want the date in the checked-in version of the file?
Yes. This way, the checked out copy that makes my web server can do its job
without requiring any of the filters being installed. And the files in
history are marked as necessary.
> I would assume otherwise. Then your clean filter should really be the
> smudge filter, and you would need a clean filter to go with it (remove the
> date and restore the keyword).
The problem with that approach is that the "smudge" filter does not have
access to the file name, and so can not look up the last change date of the
file it is re-writing. And I want the last time the file was *changed*, not
the time it was checked out.
Also, I imported my entire CVS history with keywords expanded to allow for
this (and "checked out" the Git-generated tree over my CVS check-out to not
have Git update all the time-stamps).
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Implementing $Date$ substitution - solution using pre-commit
2009-08-09 19:37 Implementing $Date$ substitution - problem with git status Peter Krefting
2009-08-09 20:52 ` Johannes Sixt
@ 2009-08-13 6:47 ` Peter Krefting
1 sibling, 0 replies; 8+ messages in thread
From: Peter Krefting @ 2009-08-13 6:47 UTC (permalink / raw)
To: Git List
Hi!
So, my filter-based approach at doing RCS-like $Date$ expansion didn't work
out. Since I wanted to have the Date expand on check-in, not on check-out,
and be expanded in history, I had made it into a "clean" filter. But due to
how Git internally checks if files are clean, that did not work properly.
The solution to this was instead to make the Date expansion into a
pre-commit hook. Using .gitattributes, I set "datereplace=true" on all the
files I want to have "$Date$" expand in, and then install the following
file as .git/hooks/pre-commit:
===8< pre-commit >8===
#!/bin/bash -e
# Find base commit
if git-rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Set up Date substitution
export NOW=$(date +"%Y-%m-%d %H:%M:%S")
for file in $(git diff-index --cached --diff-filter=AM --name-only $against); do
if git check-attr datereplace -- "$file" | grep 'datereplace: true' > /dev/null; then
perl -w -i.bak -e 'my $now = $ENV{"NOW"};
$now =~ s/[^-:0-9 ]//g;
while (<>)
{
if (/\$Date:?[^\$]*\$/)
{
s/\$Date:?[^\$]*\$/\$Date: ${now} \$/;
}
print
}' "$file"
git update-index --add "$file"
fi
done
exit 0
===8< pre-commit >8===
This has the added bonus over a filter that it all files committed at the
same time will have the same date stamp, whereas the filter would expand on
the time "git add" is executed.
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-08-13 6:47 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-09 19:37 Implementing $Date$ substitution - problem with git status Peter Krefting
2009-08-09 20:52 ` Johannes Sixt
2009-08-10 4:41 ` Peter Krefting
2009-08-12 6:54 ` Peter Krefting
2009-08-12 8:36 ` Problems with filters and git status - reproduction steps Peter Krefting
2009-08-12 8:55 ` Michael J Gruber
2009-08-12 9:25 ` Peter Krefting
2009-08-13 6:47 ` Implementing $Date$ substitution - solution using pre-commit Peter Krefting
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox