> Does JJ really prefer for me to think backwards? It wants me to start with the new and describe command, but with git I first make the changes and name the changeset at the end of the workflow.
A good way to think of it is that jj new is an empty git staging area. There's still a `jj commit` command that allows you to desc then jj new.
> I also often end up with in a dirty repo state with multiple changes belonging to separate features or abstractions. I usually just pick the changes I want to group into a commit and clean up the state.
jj split allows you do to this pretty well.
> Since it's git compatible, it feels like it must work to add files and keep files uncommitted, but just by reading this tutorial I'm unsure.
In jj you always have a commit - it's just sometimes empty, sometimes full, has a stable changeid regardless. jj treats the commit as a calculated value based on the contents of your folder etc, rather than the unit of change.
I'm using jj exactly this way, but `jj commit -i` is still somewhat backwards compared to `git commit -i`: jj displays the commit timestamp by default instead of the author timestamp like git. In addition, in jj the author timestamp of a commit is set to the time you started and not ended a commit/change. This results in unexpected timestamps when working with git-using people or tools. Also, it's rather weird if you use a previously empty commit for your work which was created months earlier by a previous `jj commit`, resulting in a timestamp neither correlating to when you started nor ended your work.
I guess the idea of jj's authors is that jj's commits are far more squishy and can always be changed, so a fixed finished timestamp makes less sense. I still prefer git's behaviour, marking work as finished and then keep the author (but not commit) timestamps on amends.
I use this jj alias to get git's timestamp behaviour:
[aliases]
c = ["util", "exec", "--", "bash", "-c", """
set -euo pipefail
change_id=$(jj log -r @ --no-graph -T 'change_id')
desc=$(jj log -r $change_id --no-graph -T 'description')
commit_author=$(jj log -r $change_id --no-graph -T 'author.email()')
configured_author=$(jj config get user.email)
jj commit -i "$@"
if [ -z "$desc" ] && [ z"$commit_author" = z"$configured_author" ]; then
echo "Adjusting author date"
jj metaedit --update-author-timestamp --quiet $change_id
fi
"""]
[templates]
# display author timestamp instead of commit timestamp in log
'commit_timestamp(commit)' = 'commit.author().timestamp()'I often will use `jj new -B@` (which I made an alias for) followed by `jj squash -i` to split changes. I had no idea about `jj split`, so I need look into that!
> A good way to think of it is that jj new is an empty git staging area. There's still a `jj commit` command that allows you to desc then jj new.
This always made me feel uncomfy using `jj`. Something that I didn't realise for a while is that `jj` automatically cleans up/garbage collects empty commits. I don't write as much code as I used to, but I still have to interact with, debug and test our product a _lot_ in order to support other engineers, so my workflow was effectively:
```Running `jj new master@origin` felt odd because I was creating a commit, but... when I realised that those commits don't last, things felt better. When I then realised that if I made a change or two while investigating, that these were basically stashed for free, it actually improved my workflow. I don't often have to go back to them, but knowing that they're there has been nice!