2

I have enabled the expansion of $Id:$ via ident in the .gitattributes file. This allows me to quickly identify whether the file is outdated when someone else checked out my repository and installed it from there.

Now, I also sync the contents of my own Git repository to other (non-development, i.e. without Git) systems. The trouble is that the keyword expansion only happens on checkout, but my workflow is commit -> push -> sync, so the synced copies contain outdated Ids.

How can I easily force an update of the Ids after a local commit? (Bonus points for doing this automatically after any commit!)

A simple git checkout doesn't work (also not with --force), probably because the file contents haven't changed. Neither does git checkout-index --force. I only managed to accomplish this via either local modification (cumbersome, need to know the modified files):

$ echo "modified" >> file
$ git checkout file

or by temporarily checking out the previous commit:

$ git checkout HEAD^
$ git checkout HEAD@{1}
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • what filepattern do you apply this ident attribute to? and about how many files does that encompass? – Alexander Bird Nov 19 '12 at 16:20
  • 1
    Also, a tip (though this doesn't answer your question): you can do `git checkout HEAD@{1}` and it will checkout the previous value of HEAD (http://git-scm.com/book/en/Git-Tools-Revision-Selection#RefLog-Shortnames). It keeps track of branch values at .git/logs – Alexander Bird Nov 19 '12 at 16:25
  • 1
    I would recommend not using idents when checking out files. It is almost never the right solution, and causes more problems than it solves; instead, if you need to keep track of which revision corresponds to a checkout, I would use a separate file that tracks that and is not committed to git. For instance, if you have a `sync` script, have it write the current commit-id to a file, and read that file anywhere that you need to display this. – Brian Campbell Nov 19 '12 at 16:40
  • Though I don't see how it's relevant, my filepattern is `*`, and I have ~ 50 Bash scripts in 2 subdirectories. The scripts are somewhat related add-ons, but can be picked individually, that's why a central version file doesn't work well here; it'd have to be a separate one for each script. – Ingo Karkat Nov 19 '12 at 16:43

3 Answers3

1

here are some suggestions:

git checkout --force . or maybe git checkout --force file.txt

If one of those commands work, then you can create a script .git/hooks/post-commit and have that script be a one-liner which calls that command (or whatever command works) and then git will do that on every commit. I believe hook scripts automatically have the root of the working directy (where the .git folder is) set as the cwd for the script.

EDIT:

If you run touch file.txt; git checkout file.txt then git will do a full checkout including applying the ident attribute when I tested that. hopefully that can be used somehow

Alexander Bird
  • 38,679
  • 42
  • 124
  • 159
  • Unfortunately, `--force` doesn't help. But thanks for the details on the hooks; I will try that. – Ingo Karkat Nov 19 '12 at 16:48
  • From my understanding of your general requirements, I would try the Brian's suggestion in the comment of the question. However, I'm not sure I know what you mean by "syncing" repos. Do you mean that you do a `git pull`? or that you have some other system to copy/rsync the files to the other non-git instances? Sorry for not understanding fully; though maybe that's not even important. – Alexander Bird Nov 19 '12 at 20:12
  • I sync the scripts via the Unison tool (xcopy / rsync would work, too). I am aware of the limitations of ident, and that it's generally recommended against, but it seemed to fit my use case very well. – Ingo Karkat Nov 20 '12 at 09:21
0

This can be done via a post-commit hook. I've automated the setup via a script, maintained as part of my git-extensions repository:

$ git-ident-update --help
Update the expansion of $Id$ to $Id:...$ via ident in the .gitattributes
after a commit.
To do this automatically in the future, invoke with --install.
Usage: git-ident-update [--install|--uninstall|--status|--set [<path>[ <path> ...]]] [-?|-h|--help]
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
0

I run touch and git checkout on recently updated files that have git Id in them using the following command:

find . -type f -mtime -1 -a -not -name '*~' | \
   xargs grep -l '$Id:' | \
   xargs --replace --verbose sh -c '{ touch {} ; git checkout {}; }'
Nicholas Sushkin
  • 13,050
  • 3
  • 30
  • 20