19

I would like to write my own notes/tests/code in org and then use org-bable-tangle to produce source files. However, all of these files are subject to version control and hence subject to change from outside my org environment.

I would like to be able to have a number of src blocks and then tangle to a bunch of different files, each of which would be commit to version control. But at the same time, be able to "untangle" each of these files back into my org file after pulling any changes from version control.

Is there any straightforward way of doing this? I am now considering playing with insert-file-contents

RJTK
  • 293
  • 2
  • 5
  • Could you provide a little example of what you are asking to do? It sounds like you have code blocks in one or more org files and you want the file or files generated from the tangle of these blocks to disassemble into the original blocks with changes in the org files. – David D. Oct 05 '18 at 12:44
  • 2
    Essentially the workflow would be like this: (1) write some literate code in org. (2) tangle that code to one or more files. (3) git commit those files. (4) have lunch (5) git pull my colleague's changes. (6) "inverse-tangle" those changes back into code blocks in my org file. (7) goto (1). – RJTK Oct 05 '18 at 15:12

2 Answers2

16

Yes, it's org-babel-detangle.

org-babel-detangle is an interactive compiled Lisp function in ob-tangle.el.

(org-babel-detangle &optional SOURCE-CODE-FILE)

Propagate changes in source file back original to Org file. This requires that code blocks were tangled with link comments which enable the original code blocks to be found.

You need to set the comments header argument to link to make it work, for example,

#+begin_src ruby :tangle hello.rb :comments link
  puts 'hello'
#+end_src

then use M-x org-babel-tangle to export the code block, a new file named hello.rb will be created, it should have similar contents like the following

~ $ cat hello.rb
# [[file:~/foo.org][No heading:1]]
puts 'hello'
# No heading:1 ends here
~ $

Finally, open hello.rb in Emacs, change hello to hello world, and run M-x org-babel-detangle in hello.rb's buffer. The org file will be updated

#+begin_src ruby :tangle hello.rb :comments link
  puts 'hello world'
#+end_src
xuchunyang
  • 14,302
  • 1
  • 18
  • 39
  • Could you be more precise (or give an example) on how to use this org-babel-detangle function. I tried with your ruby code to use M x org-babel-detangle after tangling to hello.rb and modifying lightly the code but I have an error "org-babel-detangle: Wrong type argument: stringp, nil". – Lgen Oct 08 '18 at 20:10
  • 1
    @Lgen I've updated my answer. And don't forget to read `org-babel-detangle`'s docstring to understand the purpose and the usage. – xuchunyang Oct 09 '18 at 01:12
  • Thanks for this clarification. I had not understood the assumption that the source code had to be edited within emacs to allow reverse tangling (I was using another text editor to modify the source code). It works as expected now. – Lgen Oct 09 '18 at 07:28
  • This is nice feature, but isn't quite what I was hoping to find. I can't really commit the #[[...]] comments since they don't mean anything except to myself. Is it possible to annotate a source block to detangle from an entire file without requiring the link comment? Essentially just `insert-file-contents` ? – RJTK Oct 09 '18 at 14:47
8

There is also org-tanglesync, which has a much simpler method of syncing than org-babel-detangle

Essentially if a block is tangled to an external file, then every time that block is edited the external file is checked also, and if a diff is detected, the user is prompted to either reject or pull the external changes into the org src block.

This also has functions to automatically process all tangled blocks in a buffer. I hope it helps.

Mehmet Tekman
  • 183
  • 1
  • 6
  • FYI for anyone who's planning to try this out, this doesn't to support tangling multiple source blocks to a single file: https://gitlab.com/mtekman/org-tanglesync.el/-/issues/13 – gsgx Sep 12 '22 at 01:22