Use your favorite editor/IDE with a local git work tree, even when you need to run things on a remote host, by sending changes back and forth with almost no time/effort.
- From a local interactive shell, run
remocon
within any subdir of your git work tree. - It opens a remote shell with an identical copy of the work tree on the preconfigured host.
- Enjoy playing with the same commit and all the tracked staged/unstaged changes under the same relative working directory, but on a remote host.
You probably already have Homebrew. Then, just run:
brew install netj/tap/remocon
Download the remocon
script and place it as an executable file on a directory on $PATH
.
remocon-completion.bash includes programmatic completion support for bash (and perhaps other shells). bash-completion 2 or later required. Homebrew formula takes care of installation on macOS. On other OS, install it manually to the right place, such as:
install -m a=r remocon-completion.bash /usr/local/etc/bash_completion.d/
:set makeprg=remocon
- Now, βB (or
:make
) mirrors all your local edits remotely within a second.
-
Add to External Tools a Program
remocon
with Working directory set to$ProjectFileDir$
. -
Assign a shortcut to it, say ^βS, from Keymap in Preferences.
-
Now, making all your changes appear on the remote host requires the same effort as saving any file locally.
# Use the `set` command interactively:
$ remocon set
π‘ Enter a remote host and path prefix to use, e.g.:
[email protected]:tmp/repos to put a clone of local git work tree 'foo' under 'tmp/repos/foo', or
example.org or [email protected] to put all remote clones on the home dir.
>>> [email protected]:some/path
π‘ [[email protected]:some/path] βοΈ setting ~/.remocon.conf
# Or pass the remote host and optional path prefix as argument:
$ remocon set example.org
π‘ [example.org] βοΈ setting ~/.remocon.conf
# Or edit the configuration file directly:
$ vim ~/.remocon.conf
[email protected]:some/path
remote=example.org
# Use the `put` command:
$ remocon put
π‘ [example.org] π° putting a replica of local git work tree on remote
...
# Or it's the default behavior when not in a full terminal:
$ remocon # from a non-tty, e.g., in MacVim or IntelliJ
# Use the `run` command:
$ remocon run
π‘ [example.org] π° putting a replica of local git work tree on remote
...
π‘ [example.org] β‘οΈ running command: bash -il
...
# You can open a different shell than `bash` if wanted:
$ remocon run zsh -l
# In fact, you can run any commands with the latest changes in local work tree:
$ remocon run make test
$ remocon run pytest src/
$ remocon run mvn test
$ remocon run jupyter notebook
# Remote commands are run under the identical relative subdir to where you run remocon locally, so launching a server that is workdir-sensitive can be hassle-free:
$ cd server
$ remocon run docker-compose up -d
...
$ cd -
# You can also launch a REPL for Python
$ remocon run python
...
>>> 1+1
2
# Or even an editor to edit/view remote files:
$ remocon run vim
For example, maybe your commands generated important data remotely. Or you made precious changes to the code remotely while testing/debugging interactively.
# To get everything under the workdir:
$ remocon get
π‘ [example.org] π getting remote files under 1 paths: .
...
# You can specify a list of file/directory names to get back from remote:
$ remocon get Untitled.ipynb Experiment.ipynb
$ remocon get test/report.xml
$ remocon get src/server/easy_to_debug_remotely.py
$ remocon get src/main/java/
# Use the `prg` (p/ut, r/un, g/et) round-trip "programming" command:
$ remocon prg test/report.xml test/log.txt -- make test
π‘ [example.org] π° putting a replica of local git work tree on remote
...
π‘ [example.org] β‘οΈ running command: make test
...
π‘ [example.org] π getting remote files under 2 paths: test/report.xml test/log.txt
...
Is there a way to run the command in a new TMUX window, so I can inspect/debug after it finishes/aborts?
Of course.
Use the rec
(recording) command:
$ remocon rec pytest test/
π‘ [example.org] π° putting a replica of local git work tree on remote
π‘ [example.org] β¨ recording a new TMUX window with: pytest test/
π‘ β οΈ [example.org] attaching to the new TMUX window (TIP: append ` |:` to command-line to prevent this)
...
[detached (from session ...)] or [exited]
When your command takes a long time to run or for whatever reason you may feel it's awkward having to detach every time you run this command to come back to the local shell.
You probably already have another terminal attached to the remote TMUX session monitoring the activity and just want to launch the command from the local shell in the current terminal.
Here's a neat little trick for such setup: append the |:
to the command-line and it won't attach but just create a new TMUX window for it:
$ remocon rec pytest test/ |:
π‘ [example.org] π° putting a replica of local git work tree on remote
π‘ [example.org] β¨ recording a new TMUX window with: pytest test/
Finally, here's a handy way to attach to the TMUX session that can be used from the other terminal:
$ remocon rec
π‘ [example.org] π° putting a replica of local git work tree on remote
π‘ [example.org] β¨ recording a new TMUX window for an interactive session
...
In fact, it's remocon
's default behavior when in a full terminal:
$ remocon # from a tty
remocon
frees you from having togit commit
andgit push
every little change.
remocon
supersedes your IDE's sluggish remote deployment function that typically relies on SFTP wasting time/effort requiring you to guess and upload a whole bunch of changed files whenever you checkout a pretty different git branch.
- TMUX, Bash, and Vim/Emacs in terminals are a beautiful thing, but using them exclusively may not be the most productive work environment for you, nor the healthiest.
- No matter how close your remote host is, there's always a few msec of latency added to every keystroke you make when working/editing remotely, which can create significant fatigue and numbness over long period of time while you may not even recognize.
- By limiting your exposure to such hazardous conditions to a minimum when they're absolutely needed, and keeping the rest of the time in an optimal local work environment, you can become a lot more productive.
- Not really.
remocon
is only going to be complementary. Your nice dotfiles on remote hosts will still remain an integral piece of the workflow.remocon
reduces the need for setting up an SSH session to a remote host (logging in, changing directories withcd
, messing withgit pull
andgit checkout
, etc.), just to run some quick test commands on an identical copy of the code you have locally.remocon
enables quick switching between hosts of a shared cluster, e.g., when the current host gets too crowded, crashes, or whatever else goes wrong with it, you no longer need to become a hostage/victim of such situation/accident. Just point.remocon.conf
to another host and with a bit of initial git clone time, any fresh host becomes yours without changing workflow too much or having to move too many things.
RemoCon is a commonly used word for remote controller in Japan/Korea (γͺγ’γ³γ³/리λͺ¨μ»¨), and possibly in other countries/languages.
remocon
originates from:
- countless variations of the one-liner:
git diff | ssh ... "cd ...; git apply"
, - then the more evolved/rigorous
git-tether-remote
function ingit-helper
bpm module, - then the gist: https://gist.github.com/netj/54c8849681c13f11a4ec50d04041e0f3.