unisonweb / unison

A friendly programming language from the future
https://unison-lang.org
Other
5.82k stars 272 forks source link

push/pull to/from codebase file path #3837

Open ceedubs opened 1 year ago

ceedubs commented 1 year ago

Problem Description

Right now if you have two separate local codebases, it's a huge pain to get code from one of them into the other.

The easiest way is to push a namespace to Share and then pull it into the other codebase. But this solution is a bummer for a number of reasons.

Current Workaround

You can currently achieve the desired outcome, but it's a hassle.

  1. Google "git orphan repo" and stare at the results in confusion for a few minutes.
  2. Google "git bare repo" because that's actually what you meant.
  3. Create a new local git bare repo: git init --bare /tmp/temp_repo.git
  4. Search the Unison docs for the syntax to push using the git protocol.
  5. Google "git file protocol how many slashes"
  6. Push to the local bare repo from codebase 1: .> push git(file:///tmp/temp_repo.git).someNamespace .someNamespace
  7. Pull from the local bare repo in codebase 2: .> pull git(file:///tmp/temp_repo.git).someNamespace .someNamespace
  8. (bonus points) delete the temporary bare repo

Proposed Solution

Add support for a local file protocol to ucm. Something like:

.> push file(/home/me/code/unisonCodebase1).someNamespace .someNamespace

.> pull file(/home/me/code/unisonCodebase2).someNamespace .someNamespace

If the implementation of this command wants to create a bare repo behind the scenes that's fine by me.

Controversial Decisions

I'm assuming that the path should be to the parent directory that contains the .unison directory, because that's how other codebase paths generally work in UCM right now. Some users might expect to point directly to the SQLite file or the .unison directory?

ceedubs commented 1 year ago

Implementing this could provide one option to work around #3314 .

aryairani commented 1 year ago

@ceedubs Does it help that you don't have to use file://? you Should be able to

$ git init --bare /tmp/temp_repo
.> push git(/tmp/temp_repo).someNamespace .someNamespace
.> pull git(/tmp/temp_repo).someNamespace .someNamespace
ceedubs commented 1 year ago

@aryairani Slightly. Thanks for the tip. But I still think that my proposal would improve the ergonomics a lot. Manually creating a bare repo isn't very user-friendly (or discoverable).

aryairani commented 1 year ago

I was gonna suggest that you don't need a bare repo either, but I guess you do:

  Synced 6856 entities.
  I couldn't push to the repository at /tmp/foo ; the error was:
  remote: error: refusing to update checked out branch: refs/heads/trunk        
    remote: error: By default, updating the current branch in a non-bare repository        
    remote: is denied, because it will make the index and work tree inconsistent        
    remote: with what you pushed, and will require 'git reset --hard' to match        
    remote: the work tree to HEAD.        
    remote: 
    remote: You can set the 'receive.denyCurrentBranch' configuration variable        
    remote: to 'ignore' or 'warn' in the remote repository to allow pushing into        
    remote: its current branch; however, this is not recommended unless you        
    remote: arranged to update its work tree to match what you pushed in some        
    remote: other way.        
    remote: 
    remote: To squelch this message and still keep the default behaviour, set        
    remote: 'receive.denyCurrentBranch' configuration variable to 'refuse'.     
aryairani commented 1 year ago

@ceedubs Could you say more about the context — I'm assuming it's due to some other bugs or DX issues that you are even in this situation?

ceedubs commented 1 year ago

@aryairani I don't remember the original context, but here some scenarios that @rlmark and I came up with:

aryairani commented 5 months ago

@ChrisPenner Naming the command, aside, how much work do you think it would take to add a command (either an interactive command or a ucm shell command) that used sync22 to copy a project or branch to or from another codebase provided by a path argument?

(It doesn't necessarily have to use sync22, but why wouldn't we if it's already done.)

ChrisPenner commented 5 months ago

@aryairani Assuming that Sync22 hasn't bitrot (I don't know if we have many tests for it at this point 😓 ), shouldn't be hard IMO