Using .sl/store/git for transparent git interop?
adamh-oai opened this issue · comments
Like a lot of orgs we have all sorts of tools that expect you're working in a git repo (for pre-commit, deploy etc), which is a blocker for sapling adoption. I've played around some with hooks and scripts to transparently sync a git repo from sapling though it's all sort of slow and fragile.
I noticed .sl/store/git has an existing git repo that (?) mirrors the sapling contents. Is there any existing support for this I'm missing? Any suggestions for a good way to implement it?
Some specific git operations I run into:
- What Is HEAD?
- Is the working directory dirty?
- List modified files, run a linter on them
I've ended up at a solution with these two hooks:
[hooks]
txnclose = sl-git
update = sl-git
And sl-git looks like:
# point git HEAD to sapling HEAD
case $HG_HOOKTYPE in
"txnclose")
git update-ref HEAD `sl whereami`
;;
"update")
git update-ref HEAD $HG_PARENT1
;;
esac
# update the index without changing the working directory
git read-tree HEAD
This seems to keep git in sync with sapling in all the cases I tried, but I'm a little uneasy there might be cases I'm not aware of.
Now I'm wondering about pre-commit hooks (eg formatters), and how to make them work across all the paths that update a commit (amend, rebase, etc)
The .sl/store/git
is an implementation detail that we plan to change. While you can ln -s .sl/store/git .git
and get something working, it's not an officially supported setup and will likely break in the future.
See #182 for more discussions. We don't want to support .git/
file format compatibility, but are happy to accept patches that provide a command-line git
shim even if it's imperfect. If your use-case is automation (ex. the GitLens extension), they might just need a subset of git
features and a shim
could be a feasible solution.
@ahupp @adamh-oai just out of curiosity...are you using Sapling with a large repo? When I use your approach on a large repo it's quite slow to run git status after changing a commit in sapling as it has to refresh the index...
Not sure what you count as "large", its 33k files. The first git status
does take a bit but this isn't on my critical path.
Yah fair enough. Mine is > 10 times that, so it's more noticeable. I really like your solution -- was previously doing this with a separate worktree from .sl/git/store and then would rsync on demand + various other cmds to get the repo in the correct state. The problem with that is similar I think to what you experienced -- it can be finicky.
We have a lot of scripts that use git status/git diff to determine changed files, and so this is kind of on the critical path for me. But it's not necessarily a deal breaker as it's only a one-time thing after a ref change.