Question

I have a hook that takes the changed files and copies them to a directory it works for standard commits but the auto-commit of a merge breaks it as the last two commits doesn't contain any changed files

Here is my current code

generateChangeSet() {
    if [ ! -d $WORKDIR ];then
        mkdir $WORKDIR
    fi

    CHANGESET=$(git log -1 --name-status $oldrev $newrev | grep -v -e "^Merge" -e "^commit" -e "^Author" -e "^Date" -e "^ " -e "^$")
    if [ -z $CHANGESET ]; then
      echo Could not detect any files in the change set, aborting push
      exit $RETVAL
    fi

    # Get a list of deleted files
    DELFILES=$WORKDIR/deletedFiles.sh
    if [ -f $DELFILES ];then
        rm -rf $DELFILES
    fi

    for dFile in $(echo $CHANGESET | grep "^D" | awk '{print $2}'); do
        echo deleted file $dFile
        echo rm -f $dFile >> $DELFILES
    done
    if [ -f $DELFILES ];then
        sed -i '1s/^/#!\/bin\/bash\n/' $DELFILES
        chmod +x $DELFILES
        echo find . -depth -type d -empty >> $DELFILES
        echo rm deletedFiles.sh >> $DELFILES
    fi

    echo "Generating diff between $newrev and $oldrev"
    git archive HEAD $(echo $CHANGESET | grep -v "^D" | awk '{print $2}') | (cd $WORKDIR && tar xf -)
}

Any ideas on how get the script to get the latest changed files at all times?

Thanks

Was it helpful?

Solution

I'd start by being concerned that the target ($WORKDIR?) might not be in sync with the delta being computed here in the first place. Why are deletions being exported through a shell script? Why not git checkout directly into a fresh target (set GIT_WORK_TREE to do this), e.g.:

what_to_replace=/some/where/tree
tmp_replacement=/some/where/tree.new

rm -rf $tmp_replacement
mkdir $tmp_replacement || fatal "can't create $tmp_replacement"

GIT_WORK_TREE=$tmp_replacement git checkout master -- . ||
    fatal "can't create updated master branch tree"
mv $what_to_replace ${what_to_replace}.old &&
    mv $tmp_replacement $what_to_replace ||
    fatal "can't swap in $tmp_replacement"
rm -rf ${what_to_replace}.old ||
    warn "can't clean up ${what_to_replace}.old"

(which probably needs some sort of locking added, and some more fleshing out). But if you're determined to go on with the existing code (there could be some reason(s) to do so), this part is just silly:

CHANGESET=$(git log -1 --name-status $oldrev $newrev | grep -v -e "^Merge" -e "^commit" -e "^Author" -e "^Date" -e "^ " -e "^$")

Instead, use git diff-tree --name-status $oldrev $newrev to diff the trees associated with the given commits. The rest should be easy. This all assumes that $oldrev accurately reflects the state of whatever's being updated, of course.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top