p fetches and then fast-forwards. When the branch has diverged it stops and tells the user to go
run git themselves:
src/git/transfer.cpp:487-491
if ((analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) == 0) {
return Failure(branch + " and its upstream have diverged",
"gittop only fast-forwards; this needs a merge or a rebase",
"the fetch already landed, so `git rebase` or `git merge` will work now");
}
The refusal is the right default and the reasoning above it is right too — doing a merge or a rebase
implicitly behind a key called "pull" is how a tool loses work that was never committed anywhere
else. What is missing is the explicit version: a separate, clearly-named action that rebases the
current branch onto its upstream when the user asks for it by name.
This is the most common way the fast-forward-only rule is hit in practice. The message is accurate
but it ends with the user leaving gittop, which for a divergence caused by a rebase upstream is a
routine and expected event rather than an unusual one.
Proposed
- A distinct action — not a mode on
p. pull --rebase and pull differ in what they can destroy,
and a key that sometimes rebases depending on configuration is the ambiguity this codebase already
refuses elsewhere.
- Implement with
git_rebase_init / git_rebase_commit / git_rebase_finish. The rebase
machinery is already present in src/git/rebase.cpp, and Repository::Commit already knows to
refuse during a rebase because those commits have to go through git_rebase_commit to advance the
plan as well as the branch.
- Conflicts must land in the state the app already understands.
ReadOperation detects an
interrupted rebase and ui::OperationPane already offers continue and abort for one, so a rebase
that stops on a conflict should leave the repository exactly where those two expect it. That is
most of the value here: the failure mode is already designed for.
- Refuse to start with a dirty working tree, and say so, rather than discovering it partway through.
- The whole thing runs on the transfer worker with its own repository handle, per the existing rule
that one thread owns a Repository at a time.
Also worth having
git pull --ff-only is what p already is; a plain merge pull (git pull --no-rebase) is the
other half of what the refusal message suggests. If both are added they should be two named actions
for the same reason, not one action with a setting.
pfetches and then fast-forwards. When the branch has diverged it stops and tells the user to gorun git themselves:
src/git/transfer.cpp:487-491The refusal is the right default and the reasoning above it is right too — doing a merge or a rebase
implicitly behind a key called "pull" is how a tool loses work that was never committed anywhere
else. What is missing is the explicit version: a separate, clearly-named action that rebases the
current branch onto its upstream when the user asks for it by name.
This is the most common way the fast-forward-only rule is hit in practice. The message is accurate
but it ends with the user leaving gittop, which for a divergence caused by a rebase upstream is a
routine and expected event rather than an unusual one.
Proposed
p.pull --rebaseandpulldiffer in what they can destroy,and a key that sometimes rebases depending on configuration is the ambiguity this codebase already
refuses elsewhere.
git_rebase_init/git_rebase_commit/git_rebase_finish. The rebasemachinery is already present in
src/git/rebase.cpp, andRepository::Commitalready knows torefuse during a rebase because those commits have to go through
git_rebase_committo advance theplan as well as the branch.
ReadOperationdetects aninterrupted rebase and
ui::OperationPanealready offers continue and abort for one, so a rebasethat stops on a conflict should leave the repository exactly where those two expect it. That is
most of the value here: the failure mode is already designed for.
that one thread owns a
Repositoryat a time.Also worth having
git pull --ff-onlyis whatpalready is; a plain merge pull (git pull --no-rebase) is theother half of what the refusal message suggests. If both are added they should be two named actions
for the same reason, not one action with a setting.