0

I have a remote bare repo on my server. I want the server to always have the current working tree as a real directory in the system.

I am using the post-receive git-hook with a command to build the working tree and to override the old tree:

git archive master | tar -x -C /dir/to/my/project/

However, this approach has a problem: It does not delete files that were deleted/moved in the repo.

I could simply erase the whole project directory but I want to keep all files that are ignored in my .gitignore.

I tried to write a script to delete all files that are not ignored but it takes minutes to process.

Is there a way to replicate the working tree without erasing ignored files?

Leander Hass
  • 162
  • 2
  • 3
  • 13
  • `git --work-tree=/dir/to/my/project/ checkout -f` Like in https://stackoverflow.com/a/33959217/7976758 – phd Feb 26 '22 at 21:03
  • I am getting the error "fatal: this operation must be run in a work tree". Is this because I have a bare repo? (Updated this fact in the question) – Leander Hass Feb 26 '22 at 21:12
  • The directory `/dir/to/my/project/` must exist. I checked checkout from a test bare repo with and without target dir; when the directory exists checkout works;; when the directory doesn't exist Git fails with message "fatal: this operation must be run in a work tree". – phd Feb 26 '22 at 22:11
  • I tested it again. Actually when the dir does not exist there is a message saying so. BUT now it works very well. Thank you very much. – Leander Hass Feb 27 '22 at 14:48

1 Answers1

1

You can either add worktrees with the convenience command (not really the best plan, but probably workable) or implement the parts you need yourself with core commands (guaranteed to always work the same).

The index is a manifest, a list of pathnames and pointers to repo content and cached filesystem metadata for the filesystem copy at that path.

GIT_WORK_TREE=/path/to/your/checkout GIT_INDEX_FILE=/path/to/your/manifest \
        git read-tree -um $commit:$dir

Where you put the work tree and index is entirely up to you, Git's core doesn't care, just tell it (as I've done here).

Docs for the $commit:$dir revision syntax

git read-tree is the core command underlying checkout, merge, hard resets, and anything of the kind.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • I tried the command like `GIT_WORK_TREE=/path/to/my/project GIT_INDEX_FILE=/path/to/my/project/.git/manifest \git read-tree -um commit:dir` and got the error `fatal: Not a valid object name commit:dir`. – Leander Hass Feb 27 '22 at 14:59
  • You have to use real commit id and (optional) directory path there. So from a post-receive it'd be the updated ref, like refs/heads/master or whatever, and if you want the whole commit just leave the directory selection empty, `$updatedref:` – jthill Feb 27 '22 at 15:06