git-remote-ipfs
git-remote-ipfs copied to clipboard
Push
Now that clone/fetch is working, push is the next step.
For now, I just plan to add commits to a remote, and print the new root hash of that repo. Updating IPNS entries will come later.
I'm also not sure if I can update the local path of the remote that was used after a push. Might need a 'git remote rm ipfs $oldHash && git remote add ipfs $newHash' dance until ipns is added... (dislike..)
For the mechanics: When running git push
with an ipfs origin, git asks the helper for a list of remote refs (just like with fetch, but with the for-push argument, not sure what that is about)
>list for-push
<3f7ba9486ffcaa277b28598c7bfc061bffcfb10e HEAD
<3f7ba9486ffcaa277b28598c7bfc061bffcfb10e refs/heads/master
Next, git will send one ore more push <src>:<dst>
commands.
>push refs/heads/master:refs/heads/master
At that point I already know the hash of that remote ref (I just received it myself). I think the idea is, to walk down the history of the local repo (GIT_DIR
) and find that remote ref. Everything up from that point, are the commits we need to push.
Open questions:
- [x] Can I just add those commit objects (and the trees and blobs that it depends on, of course) into the remote
.git/object/ab/cdefs..
or do I need to update some index? Refs at least, I guess. - [x] Should I pack them?
- [ ] Look into refspec as they define how to update which reference (branches)
- [x] updating remote paths?
- [ ] Have a special case like
ipfs://new
to publish new repos? - [ ] deleting remote branches
- [ ] force updating
cc @chriscool your insight would be more than welcome here. The 'dumb' remote protocol is only described for fetch/pull in the git book.
For now, I just plan to add commits to a remote, and print the new root hash of that repo. Updating IPNS entries will come later.
Sounds great to me.
I'm also not sure if I can update the local path of the remote that was used after a push. Might need a 'git remote rm ipfs $oldHash && git remote add ipfs $newHash' dance until ipns is added... (dislike..)
git remote set-url
?
I think the idea is, to walk down the history of the local repo (GIT_DIR) and find that remote ref. Everything up from that point, are the commits we need to push.
I believe so.
see also http://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols
- [ ] Can I just add those commit objects (and the trees and blobs that it depends on, of course) into the remote .git/object/ab/cdefs.. or do I need to update some index? Refs at least, I guess.
- [ ] Should I pack them?
maybe we want to use git-receive-pack
- Receive what is pushed into the repository
@cryptix maybe https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt could help.
Maybe https://github.com/git/git/blob/master/Documentation/technical/send-pack-pipeline.txt could help too.
Hey!
Thanks for the input but send/receive-pack is modeled around a remote process running on a remote copy. Plus: it's not cleanly separated from the ssh transport. Making it hard to reuse.
Luckily, @davidar pointed me to git-remote-dropbox, which works exactly like I wanted it. Dumb protocol, no 2nd repo clone required.
I added a simple test that clones, adds a commit, pushes, clones the result and checks if the files are there. More complex usage tests are needed though. I'm sure that deleting a remote ref currently doesn't work, for instance.
[15:22] luzifer ~/g/g/s/b/l/dirclean (master) [128]> git push ipfs://_/repo.git master
time="2015-09-14T15:22:50+02:00" level=info msg="for-push: should be able to push to non existant.. TODO #2" module=git-remote-ipfs
time="2015-09-14T15:22:50+02:00" level=error msg="walk root failednot a key" module=git-remote-ipfs
time="2015-09-14T15:22:50+02:00" level=fatal msg="speakGit failed:walk(/ipfs/_/repo.git/refs) failed: not a key" module=git-remote-ipfs
I'd like to have something to push to IPFS without having the repo previously hosted in IPFS…
Usability weirdness: since you can only update the remote location manually with git remote set-url
git prints the old remote url after a push...:
time="2015-10-29T11:49:17+01:00" level=info msg="remote updated - new address:ipfs:///ipfs/QmRxB2V4qRtexYysXgPdME1nD3KVmhS1AA9b7rSYW6tDEC" module=git-remote-ipfs
To ipfs://ipfs/QmYFpZJs82hLTyEpwkzVpaXGUabVVwiT8yrd6TK81XnoGB/unpackedTest
3f7ba94..d90c7ca master -> master
[cryptix@svahnry ~/testRepo:master] git remote -v
origin ipfs:///ipfs/QmRxB2V4qRtexYysXgPdME1nD3KVmhS1AA9b7rSYW6tDEC (fetch)
origin ipfs:///ipfs/QmRxB2V4qRtexYysXgPdME1nD3KVmhS1AA9b7rSYW6tDEC (push)
Not sure how to highlight this better. (I'll fix colors of the logging but that's only maaaarginally helpful.)