Normally, when I wish to fix or clean up history I’ll do The Right Thing(clone
/etc
repo, edit, and force pull
the changes). However, occasionally I’ll
perform a quick in-place rebase
when the depth is very shallow or will be
non-destructive.
If — like me — you do this then you’ve probably been bitten by .etckeeper
breakage when simply re-ordering commits. If so, then the following addition to
your .git/hooks/pre-commit
will prevent the hook running while in a rebase
session.
if git branch | grep -q '^\* (no branch'; then
echo "Skipping pre-commit hook in rebase" >&2
exit 0
fi
Note: The unbalanced parenthesis in the match is on purpose, depending on
your git
version you could have a simple (no branch)
or the far more helpful
(no branch, rebasing <branch>)
branch name.
I’d be interested to know if other users have a better way to handle this.
-- James
While cloning and pulling between repos works, it is as you mentioned a bit cumbersome. What works much better is to create a lightweight worktree, e.g.
git worktree add /root/etc.worktree main.worktree
. Then/etc
and/root/etc.worktree
shares all commits and sort of works like instantly synchronised clones. The only limitation is that the same branch cannot be checked out in both worktrees (I usemain.worktree
as a shadow ofmain
).With that the update scenario will be like
cd /root/worktree
git checkout main.worktree # Probably default and not needed
git merge --ff main # Bring it up to date
git rebase --interactive HEAD~10 # Or whatever history modification you want to use
cd /etc
Finish with either
git merge main.worktree
orgit reset --hard main.worktree # NB! reset --hard is a command that might cause you to loose data if you are not careful.
I mainly use worktree to painlessly resolve new
*.rpmnew
files which are created if a package is updated and a config file update would overwrite some custom non-package modification, e.g say for instance you have changedGIT_COMMIT_OPTIONS
inetckeeper.conf
and a newer version of etckeeper has some other update to that config file. If it is the first time I resolve a update conflict I create a branchrpmnew/etckeeper.conf
from a commit right before I made theGIT_COMMIT_OPTIONS
modification (which might have been a while ago, so resetting back to that inside /etc would likely be a disaster. Inside a linked worktree there is no problem). Then I overwrite/root/etc.worktree/etckeeper/etckeeper.conf
with/etc/etckeeper/etckeeper.conf.rpmnew
and check in. Then the final step isgit checkout main.worktree && git merge rpmnew/etckeeper.conf
. This could potentially result in merge conflicts, but there are excellent tools like KDiff3 to use for that.The problem with the pre-commit hook still applies in this scenario, but I have just asked for a patch to be applied that will prevent the hook from running inside linked worktrees.