jesseduffield / lazygit

simple terminal UI for git commands
MIT License
52.34k stars 1.83k forks source link

Easily convert changes to a single commit #2249

Open jesseduffield opened 1 year ago

jesseduffield commented 1 year ago

Is your feature request related to a problem? Please describe. Often I come across a PR which has maybe 3 or 4 commits but has a bunch of merge commits merging master into the branch. So it's a bit of a mess and it would be much better if it was just a single commit (because the PR isn't actually doing much).

I know github has a feature where you can squash before merge, and that's basically what I want here, except I only want the squashing part, because there may be more commits to come on the PR and it may make sense logically to have those remain as separate commits.

Describe the solution you'd like Upon pressing a certain key, the following happens:

Describe alternatives you've considered This could just be a custom command, and I want to start it off as just a custom command, but I'd like this to live inside lazygit because it's such a common thing I come across and it's typically on other people's PRs where the person isn't very well versed with git (so it's easy to say 'download lazygit and press this key')

Additional context Here's what the command could look like:

MERGE_BASE=$(git merge-base {{.Branch}} HEAD)
git diff --binary {{.Branch}}...HEAD > /tmp/mypatch
git stash save "Lazygit: Stash before applying patch"
git reset --hard "$MERGE_BASE"
git apply --index /tmp/mypatch
git commit -m {{.CommitMessage}}
git stash apply stash@{0}
mark2185 commented 1 year ago

Just to clarify, would this be the equivalent of:

jesseduffield commented 1 year ago

@mark2185 if the commits are all at the top then yes, though this case is more for when there's a bunch of merge commits inbetween. In those cases I'm not sure you actually can get what you want via a rebase (though if you can that would be good to know)

mark2185 commented 1 year ago

Ah yes, my curse of not really reading carefully. Rebases and merge commits aren't the best of buddies, you got that right.

I like the idea of...

...better than creating temporary files. More info.

jesseduffield commented 1 year ago

Interesting, testing that approach locally it works. I'm not averse to using temp patch files, but the branching approach makes sense. We'd just need to ensure that the temp branch doesn't already exist (perhaps by appending a random uniqueness hash to the end of it)

mark2185 commented 1 year ago

I'm pretty sure hashes are overkill and that nobody will name their branch lazygit/just-a-temporary-branch-for-squashing, but the moment I click "Comment", someone will create a branch named exactly that.

Jokes aside, is this just a menu entry that allows the user to "clean up" the current branch, or are we finally getting a merge with options menu? :)

(I know this isn't really a merge with options type of option, but we gotta put it somewhere)

jesseduffield commented 1 year ago

Yeah you're probably right about the temp name thing: I was concerned that a step could fail in a prior attempt meaning the temp branch wouldn't have been deleted.

Merge with options would be good, but I don't really consider this operation as a whole to be a merge operation, even though it contains a merge. It does feel a bit too bespoke to be given its own keybinding though so I would like to find a sensible menu for it to live in (perhaps a new one that we can extend over time)

mark2185 commented 1 year ago

We could always open up a misc menu that can hold all kinds of things.