This change makes it so `jj abandon` uses `DescendantRebaser` for
rebasing descendants of the abandoned commits. That makes it not
depend on evolution for it.
Descendants of abandoned commits should be rebased onto their parents,
or the rewritten parents if they had been rewritten. This patch
teaches `DescendantRebaser` to do that. It updates `jj rebase -r` to
use the functionality. I plan to also use it in `jj abandon`
(naturally, given the name), and for rebasing descendants of deleted
refs imported from `jj git refresh/fetch/push`.
The fact that `DescendantRebaser` visits some commits that don't need
to be rebased is mostly an implementation detail. I can't think of a
reason that callers would care about these commits.
The command's help text says "Abandon a revision", which I think is a
good indication that the command's name should be `abandon`. This
patch renames the command and other user-facing occurrences of the
word. The remaining occurrences should be removed when I remove
support for evolution.
This makes conflicted branches pointing to the working copy get
updated when the working copy changes, just like they are when it
changes for other reason (such as `jj describe`).
This patch moves the function for updating branches after rewrite from
`commands.rs` into `rewrite.rs`.
It also changes the function to update branches even if they were
conflicted or become conflicted. I think that seems better than
leaving branches on old commits. For example, let's say you have start
with this:
```
C main
|
B origin@main
|
A
```
You now pull from origin, which has updated the main branch from B to
B'. We apply that change to both the remote branch and the local
branch, which results in a conflict in the local branch:
```
C main?
|
B B' main? origin@main
|/
A
```
If you now rewrite C to C', the conflicted main branch will still
point to C, which is just weird. This patch changes that so the
conflicted side of main gets repointed to C'.
I also refactored the code to reuse our existing
`MutableRepo::merge_single_ref()`, which improves the behavior in
several cases, such as the conflict-resolution case in the last test
case.
I don't know why I hadn't already updated these. Maybe I thought it
wasn't necessary. That's probably true right now, but I want to make
`jj git fetch` and `jj git refresh` automatically rebase commits when
branches were updated on a remote or in the underlying Git repo. We
want to make sure that the working copy also gets updated then.
As the updates test case shows, when rebasing forward, we missed
commits that fork off from the section between the source and the
destination.
As part of the fix, I also restructured the code a bit to prepare for
support for rebasing descendants of multiple rewritten commits.
I forgot to remove the `fetch_head` from a variable name when I
recently realized that Git's `FETCH_HEAD` is not what we want to check
out after fetching.
It turns out that `FETCH_HEAD` is not the remote's `HEAD` (it's
actually not even a normal symbolic ref; it contains many lines of
commits and names). We're supposed to ask the remote for its default
branch instead. That's what this patch does.
The table describes the simplified Git workflow of always using `git
commit -a`. With that workflow, you don't need to `git add` or `git
rm` to stage changes.
It's annoying to have to add `--branch main` every time I push to
GitHub.
Maybe we should make it push only the current branch by default, but
we don't even have a concept of a current branch yet...
Before this change, you could end up with an index segment with 10
commits, then a child segment with 9 commits, then another child with
8 commits, and so on. That's not what I had intended. This changes
makes it so we squash if a segment has more than half as many commits
as its parent instead.
I'm not sure what the interface should be, but until public heads are
automatically removed when they disappear from a remote, this will at
least be useful as a workaround.
For example:
```
main: 4f2efc5bb873 cli: make `jj branches` say how much remote branches are ahead/behind
@origin (behind by 2 commits): 5023d8d360 Merge pull request #26 from martinvonz/git-comparison
```
It turns out that `--help` provides a longer version of the help text
than `-h` does. I only discovered that because I was wondering what
the difference between `clap::App::about()` and
`clap::App::long_about()` was. There's clap-rs/clap#1015 for tracking
it in clap, but let's clarify it ourselves for now by changing the
help text for `-h/--help`.
We have had support for ignores via `.gitignore` files since
3b326a942c, and we haven't had the problem with the temporary
`.git/` directory created by libgit2 since 88f7f4732b.
With this commit, you can run `jj concepts branches` to get help about
the "branches" concept. We don't have much help for other commands and
their arguments yet, but I'm starting with concept guides so we can
point to them as we add help for commands and their arguments.
I initially tried to make the command to get help be `jj help
--concept branches`. That would require replacing clap's
implementation of the help command with our own. clap-rs/clap#1350
prevented me from doing that. But I'm pretty happy with having it
under `jj concepts` anyway. It's probably more discoverable that way.
I tried to mimic clap's styling with yellow headings.
Clap uses present tense by default (e.g. "Prints help information"). I
considered switching our message to that style, but I found it harder
to describe some flags that way.
Git doesn't want `.git` entries in its trees, so at least when using
the Git backend, we need to ignore such paths. Let's just ignore
`.git` paths regardless of backend to keep it simple.
Closes#24.
When I added the function for rebasing descendants, I forgot to call
the existing `rebase()` function and instead simply created a new
commit with the new parents but the old contents.
I think it makes sense to have a version of rebase that rebases the
descendants of the rebased commit onto the parents of the rebased
commit. Let's make `jj rebase -r` do just that. Let's also add `jj
rebase -s` (matching Mercurial's `hg rebase -s`) for rebasing a commit
and its descendants onto another commit.
Since both flavors of the command now explicitly rebase the
descendants (just to different destinations), I also made the command
not evolve orphans afterwards. That would have made sense regardless
of this commit.
This should be useful in lots of places. For example, `jj rebase -r`
currently rebases all descendants, because that's what the auto-evolve
feature does. I think it would be nice to instead copy from
Mercurial's `-s` flag for also rebasing descendants. Then `jj rebase
-r` can be made to pull a commit out of a stack, rebasing descendants
onto the rebased commit's parents. I also intend to use this
functionality for rebasing descendants when remote branches have been
rewritten.