Skip to content

Pull with rebase as an explicit action #7

Description

@sinhaparth5

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions