Question

This is kind of a weird one, and I apologize in advance if it doesn't have much application outside of my specific circumstances. I am using git to manage my deployment packages by committing and tagging a set of generated files relating to the deployment and a submodule which points to the release code. I am attempting to do a git checkout of this deployment tag from a bare repo on each machine into a different, empty directory. The output I get indicates that it has deleted the files it should have created, and the work-tree directory remains empty afterward.

$ ls -al /var/www/test/
total 0

$ git --bare --work-tree=/var/www/test/ checkout my_tag
D   .gitmodules
D   generated.tgz
D   release
D   signatures.md5
HEAD is now at 8946ff5... Generated contents of deployment package.

$ ls -al /var/www/test/
total 0

I should state that both the commit referenced by my_tag and the tip of master have the same 4 files (though with different contents). Which makes it all the stranger that the following procedure gets me 75% of the way there:

$ git --bare --work-tree=/var/www/test/ checkout master
D   .gitmodules
Previous HEAD position was 8946ff5... Generated contents of deployment package.
Switched to branch 'master'

$ ls -al /var/www/test/
total 4
-rw-r--r-- 1 root root    0 Oct 17 17:00 generated.tgz
drwxr-xr-x 2 root root 4096 Oct 17 17:00 release
-rw-r--r-- 1 root root    0 Oct 17 17:00 signatures.md5

$ git --bare --work-tree=/var/www/test/ checkout my_tag
D   .gitmodules
(---- git's warning about detached HEAD state cut ----)
HEAD is now at 8946ff5... Generated contents of deployment package

$ ls -al /var/www/test/
total 4624
-rw-r--r-- 1 root root 2103765 Oct 17 17:02 generated.tgz
drwxr-xr-x 2 root root    4096 Oct 17 17:00 release
-rw-r--r-- 1 root root 2614883 Oct 17 17:02 signatures.md5

The thing is, "release" is a git submodule, and I can't init or update it without .gitmodules, so 75% of the way there still isn't good enough.

One solution to this problem would be to simply clone the repo anew every time I deploy, and maybe I'll go that way if nobody can suggest a better solution. But ideally I'd like to keep one bare repo on each machine and checkout from that to a new work-tree each time. Can anybody tell me what's going on here?

For reference, I'm using Git 1.8.2.1.

Était-ce utile?

La solution

The basic problem is that checkout is comparing the desired revision (my_tag, master) against what's in HEAD in the --bare repo. (And the --bare argument is doing nothing.) So with my_tag, it says you're already in detached HEAD mode and on the desired rev—i.e., it should not change HEAD—and looks into the target directory, /var/www/test/, and sees that the files have been removed and gives you the D status for each. It assumes they were there because of the index (see below).

When you switch to checkout master, it figures: OK, you're moving from this detached-HEAD to master, it updates HEAD and checks out the changed files. But .gitmodules is the same in my_tag and head, so that one remains Deleted.

If you use checkout -f, it will assume it should replace the missing files.

Git also has the bad habit :-) of using $GIT_DIR/index to record what it is doing with the checkout, as well as $GIT_DIR/HEAD. This leads to left-behind files when files are removed from the thing you're trying to deploy. If the target directory is emptied out before doing a checkout -f that should be OK though. (Alternatively, set GIT_INDEX_FILE in the environment, naming a file you keep along with each unique deployment. I have not experimented with this but it should work well.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top