viwosh
viwosh

Reputation: 21

sync between git repo and non-git directory

I would like to find an efficient way of syncing files between a git repo and a target directory. The target directory in this case is the build location for an embedded linux distribution managed by ptxdist.

I am frequently building various versions of the distro so I set my various git repos to the corresponding commit, do an rsync to the build tree, and build the distro. The trouble with this approach is that rsync leaves files from one commit which may not exist in another commit and could cause confusion for the code.

I could make the distro a git repository and git pull into it but I don't need to track what I happen to be building.

The best candidate seems to be using git-archive to create tar files of the git repos, delete the target directories, then extract the tar files to the target directories. However, this seems inefficient if just a few files have changed out of everything that goes into the distro.

What I would like is a way to do something like an rsync --delete, or perhaps unison -prefer, with files in a git repository instead of the git working directory since I have untracked files I want to keep around.

UPDATE

Here is a bash script which I've used which does what was needed,

#!/usr/bin/env bash

# Does one way sync between commit and target directory where the target
# directory is not a git archive.
# USAGE: git-archive-commit <source directory> <target directory> [<treeish>] [-- <paths>...]
set -e
sourceDir="$(readlink -f $1)"
targetDir="$(readlink -f $2)"

shift; shift
checkoutArgs="$@"
gitSetup="--work-tree=$targetDir --git-dir=$sourceDir/.git"

function gitStash {
        pushd . > /dev/null 2>&1
        cd $targetDir
        git $gitSetup stash -q
        git $gitSetup stash drop -q > /dev/null 2>&1
        popd > /dev/null 2>&1
}

if [ $# -gt 0 ]; then   
        if [ $1 != "--" ]; then
                if [ $# = 1 ]; then
                        gitStash
                fi
                git $gitSetup checkout $checkoutArgs
                shift
        else
                git $gitSetup checkout $checkoutArgs
        fi
else
        gitStash
        git $gitSetup checkout
fi
git $gitSetup clean -df "$@"

Upvotes: 2

Views: 527

Answers (1)

VonC
VonC

Reputation: 1323963

If you "could make the distro a git repository and git pull into", that means:

  • git is (or can be) available on the server
  • the server can contact the client (while the reverse isn't obvious)

You could:

  • make a bare repo on the server /path/to/myrepo.git
  • set in it a post-update hook: /path/to/myrepo.git/hooks/post-update
  • git pull

The post-update script can, after each pull, trigger a:

git --work-tree=/path/to/target/directory --git-dir=/path/to/myrepo.git checkout HEAD

That would ignore the untracked files, but would update (add/modify/remove) the tracked file after each git pull.

Upvotes: 1

Related Questions