Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rebase --squash feature #1135

Open
seregamorph opened this issue Jan 28, 2022 · 1 comment
Open

rebase --squash feature #1135

seregamorph opened this issue Jan 28, 2022 · 1 comment

Comments

@seregamorph
Copy link

seregamorph commented Jan 28, 2022

Squashing branch (let it be feature) commits into a single commit and rebasing them on top of target branch (let it be master) is one of the most common operations. If there is a single commit, it's trivial, if two - trivial as well (e.g. amend to parent commit first). But in many cases the feature branch can be pretty long and contain merges from target branch as well - standard situation for long PRs and active target branch. So at some point author may want to squash all changes.

TLDR:
Introduce a standard concise command:

git checkout feature
git fetch origin master
git rebase --squash origin/master

Why this could be convenient: in case of possible merge commits they will be solved only once, not a nightmare rebasing all commits.

With current available options I do it this way

git checkout feature
git fetch origin master
git merge origin/master --no-edit && git reset --soft origin/master
git commit -m "FEA-123 - new feature"

It's pretty straightforward, but this flow has pitfalls when you try to explain it to someone else. The most critical case is possible merge conflict:

# fails because of the conflict
git merge origin/master --no-edit && git reset --soft origin/master
# resolve conflict, commit
git reset --soft origin/master
# danger here: it could be possible that author did not notice that origin/master was updated (e.g.
# it was implicit background action by GIT UI client)
git commit -m "FEA-123 - new feature and revert some commits from origin/master"

To avoid the case with updated master I always execute this pair:

git merge origin/master --no-edit && git reset --soft origin/master

There is another way to do it

git checkout feature
git fetch origin master
git branch old-feature
git reset --hard origin/master
git merge old-feature --squash --no-edit
# resolve possible conflict, commit

it's already better, but still not perfect - we introduce temporary branch (or store commit hash somehow).

One more way

git checkout feature
git fetch origin master
git merge-base HEAD origin/master
git reset --soft 00_hash_from_merge_base_00 && git commit -m "FEA-123 - new feature"
git rebase origin/master

Nice for geeks.

I understand, that these scenarios can be automated via shell scripts and even custom git commands and even shared via repo.
But I still believe it could be a nice feature.

I'm very sorry, if it's a duplicate, or the feature is already here, but I could not find and proof for such idea.

@LemmingAvalanche
Copy link

At first I thought that this isn’t needed for git-rebase(1). Rebase is about replaying commits. If you just want to squash commits you can internally use something equivalent of git-commit-tree(1) with the tree of the tip commit and make the parent the base commit. (Or so I’ve answered on StackOverflow.)

But then I thought: why does it matter how git-rebase(1) is implemented (conceptually)? Should you need to know about that in order to guess that it would be “inappropriate” (I can’t seem to find the right word) and then move onto using git-commit-tree (which is kind of like “plumbing” command now I guess? As opposed to before git-commit(1) came along).

People love to squash ranges of commits (perhaps to a fault?). I often open an interactive rebase and just type fixup for a whole range. So yeah, a --squash option should be helpful for many. One streamlined option instead of worrying about the todo editor.

But this is spoken from a position of not knowing anything about the concrete implementation of this subcommand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants