openshift-eng/doozer

doozer won't overwrite dotfiles on rebase

Closed this issue · 3 comments

When doing a rebase, dotfiles like .dockerignore in the source will be copied over to the dist-git repo, but only if they haven't before.

My test case is:

doozer  --latest-parent-version -i  ose-multus-admission-controller  images:rebase  --version v4.0.0 --release 0.139.1 -m "testing"

In the history of this repo, the .dockerignore was added, and then later modified. The modifications were never automatically synced, leading to quite a lot of difficulty in tracking down why stuff was missing from the build.

I think we need to tread lightly here as we don't necessarily want to copy everything from the source; certainly not .., and certainly not .git. Not sure about .gitignore and presumably not .oit.

I ran into this and have been looking through the code and still don't quite understand why it happens. rsync copies everything. I don't understand how it's copying something but only if it's not overwriting the destination (there are rsync options for that but I don't see them being used?)

Issue is here:

        # Clean up any files not special to the distgit repo
        for ent in os.listdir("."):

            # Do not delete anything that is hidden
            # protects .oit, .gitignore, others
            if ent.startswith("."):
                continue

            # Skip special files that aren't hidden
            if ent in ["additional-tags"]:
                continue

            # Otherwise, clean up the entry
            if os.path.isfile(ent) or os.path.islink(ent):
                os.remove(ent)
            else:
                shutil.rmtree(ent)

Particularly this:

if ent.startswith("."):
     continue

And then we'd need to add --include ".*" to the rsync command I think. NOte that we delete basically everything in the distgit dir first... so it's less of an update and more of a copy. Though you are right that it should copy that file when updated...
Oh.... wait. It might be because git doesn't preserve file modification times. It's just whenever you cloned it. So yeah.... here be dragons.

ahhhh yes... that would explain it. we delete everything except the dotfiles, and since they were just cloned, they're pretty much guaranteed to have a later timestamp, so rsync won't update them. that's great because otherwise it would overwrite .git which would be bad. however not so great because we do want most dotfiles to be updated.

seems like it would be best to give an explicit whitelist of what we want to preserve and delete everything else. so:

        # Clean up any files not special to the distgit repo
        for ent in os.listdir("."):
            if ent in ["additional-tags", ".git", ".oit", ".gitignore"]:
                continue

            # Otherwise, clean up the entry
            if os.path.isfile(ent) or os.path.islink(ent):
                os.remove(ent)
            else:
                shutil.rmtree(ent)

why do we want to preserve additional-tags? won't rebase rewrite it anyway?

I did as above with 03adba5

Feel free to tweak differently but I'll count this as done for now...