Skip to content

Squash Git commits add-on: squashes too much #15731

@dylankiss

Description

@dylankiss

Describe the issue

The "Squash Git commits" add-on is trying to first rebase the local commits onto the origin remote, but the check to see whether it should is not using up-to-date information. This causes the plugin to squash the commit already on the remote with its last local commits. This in turn causes a merge conflict on the next rebase.

I already tried

  • I've read and searched the documentation.
  • I've searched for similar filed issues in this repository.

Steps to reproduce the behavior

Prerequisites:

  • Have the "Squash Git commits" add-on installed and activated, squashing all commits with a custom message.
  • Have a component set up using Git, linked to a remote repository with say branch main and push branch weblate (that are exactly the same at this point). Have it track a folder containing .po files and a .pot file. Disable the "Push on commit" setting.
  1. In your component, change a translation.
  2. In the "Repository maintenance", click "Commit".
  3. On the same screen, click "Push". You now have a commit on your remote weblate branch.
  4. Push this new commit onto your main branch outside of Weblate.
  5. Change another translation in your component.
  6. In the "Repository maintenance", click "Commit".
  7. On the same screen, click "Update". It should rebase your changes on the remote branch.

At this point, a merge conflict occurs and everything is locked.

What happens is, after step 4, Weblate is not aware yet that your main branch (that it's tracking) has the same commit as Weblate commited before. It's one commit behind. When you change a translation and commit again, the post_commit hook of the "Squash Git commits" add-on executes, which checks:

with repository.lock:
# Ensure repository is rebased on current remote prior to squash, otherwise
# we might be squashing upstream changes as well due to reset.
if component.repo_needs_merge():
try:
branch_updated = component.update_branch(
method="rebase", skip_push=True
)
except RepositoryError:
return

However, the repo_needs_merge() function just does a git log --format=format:%H ..origin/main --, which lists the commits on the remote that are not in the local repo. At this point it doesn't do a git fetch first, so it still has an old view of the origin/main branch that didn't contain its previous commit. So it does not rebase and squashes its new commit with the previous one (that is already on our remote).

When we try to do a real rebase afterwards, it gives a merge conflict.

Expected behavior

The check to rebase does a git fetch on the remote first before doing the git log command. Or another solution that makes sure it is up to date.

How do you run Weblate?

Docker container

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions