This makes it so that almost every command will remove non-visible
heads. That shouldn't have much visible effect, except that the
`all_heads()` revset will become the same as
`non_obsolete_heads()`.
It will help us remove support for evolution by cleaning up existing
repos. Existing repos (like mine) will lose the unwanted heads (~8.5k
heads in my case), so they don't clutter the repo once evolution is
gone.
This is part of issue #32.
If you rewrite a change twice, from A to A' to A'', then undo the
operation that created A', you'll end up with a repo where A'' refers
to commit (A') that's not reachable from any head in the view. We
currently crash when that happens. This change fixes the
crash. Undoing the A' operation now instead produces a state where A
and A'' are divergent. That at least makes some sense.
This may not seem important since I'm working on removing support for
evolution (#32), but I wanted to get it fixed in order to help with
the transition off of evolution. Specifically, I want to be able to
start removing old heads more freely.
This closes#28.
In the recent switch away from `git2::Remote::fetch()`, I passed
`git2::AutotagOption::All`, which caused cloning of e.g. the `clap`
repo to fail like this:
```
Error: Fetch failed: Error { code: -1, klass: 4, message: "target OID for the reference doesn't exist on the repository" }
```
This commit changes from `All` to `Unspecified`, which respects the
remote's configuration.
The default branch relies on checking the value of `HEAD`. The `empty_git_commit` function updates the ref `refs/heads/main`, but since `HEAD` was never updated to point to that ref, the default branch can't be determined. The fix is to explicitly set `HEAD`.
Personally, this test failed reliably for me on macOS. I don't know why this behavior would be non-deterministic on other platforms.
It seems it wasn't Windows that behaved differently when it comes
getting the remote's default branch; the test failed on Ubuntu
too.
The documentation for `Remote::default_branch()` says that it can be
called even after the connection has been closed, but let's see if
calling it while the connection is open helps anyway. To do that, we
have to replicate what `Remote::fetch()` does.
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`.