Private files in public repo
Scenario
You are working in a project, collaborating with other people but there are some files within that project that you don't want to share, but still want to version.
Concrete example in our application would be you are using a specific IDE,
namely PyCharm, which stores the configuration in a .idea/
directory.
Commit private files
First:
- Make sure you start with an empty change e.g. execute
jj new
- Start PyCharm. If you don't use PyCharm just create a
.idea/
directory with some (empty) file inside for this tutorial.
jj desc -m "local: keep track of .idea (PyCharm config)"
jj
The new change is just on the top of our history, as expected. We would like to move the to the side so that we can work on the code without worrying about that change.
jj new @- @
jj
# CHANGE_ID is the id of the ".idea" change (mwzllxkn in my case)
jj rebase --revisions CHANGE_ID --destination "root()"
jj
Hmm, that's not exactly what we wanted. We lost our merge change. We could of course just create it again but let's instead learn to undo operations.
jj op log
# OPERATION_ID is the id of the operation before the rebase (d042 in my case)
jj op restore OPERATION_ID
jj undo
allows you to undo some operation, by default the last one.
Unfortunately in my opinion this does not work as well as jj op restore
because sometimes a command like jj log
appears in the operation log so you
would be undoing that operation, which is not harmful but also doesn't help.
You could use jj op log
to identify the operation you want to undo and then
call jj undo IDENTIFIER
to do so.
# CHANGE_ID is the id of the ".idea" change (mwzllxkn in my case)
jj rebase --source CHANGE_ID --destination "root()"
jj
The difference between the two rebase commands was that one used the
-r/--revisions
options and the other -s/--source
. The second option rebases
the entire descendant tree, which is what we wanted. There is a third option
-b/--branch
. Check the help to find out what it does.
jj rebase --help
Continue developing
Now of course we have this merge change in our history that we do not want to share with other developers. How do we continue working then?
jj new
- Add a new feature to the app e.g. TODO
- Modify an IDE setting (or manually add a file to the
.idea/
folder)
jj split .idea
An editor will open. Describe the changes you made e.g. "local: fix IDE settings".
jj
jj st
jj diff
jj desc -m "feat: add todocli entry point"
jj new
Implement another feature.
jj desc -m "feat: add "--version" flag"
jj new
Now put everything into its right place. Look at the current status:
jj
# rebase IDE change after previous local IDE change
jj rebase -r so -A m
# rebase my two features on top of where I want them
jj rebase -r r -r w -A l
jj
Integrate upstream changes
Assume upstream 'main' has advanced and you want to incorporate those changes into your local merge commit. You could just re-create it. But you can also do the following:
jj rebase -s MERGE_CHANGE_ID -d "all:MERGE_CHANGE_ID-" -d UPSTREAM_CHANGE_ID
jj simplify-parents -s MERGE_CHANGE_ID
Another variant, maybe simpler:
jj rebase -s MERGE_CHANGE_ID -d UPSTREAM_CHANGE_ID -d LOCAL_CHANGE_ID