-
Notifications
You must be signed in to change notification settings - Fork 59
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
[Feature] Allow absorbing existing commits #44
Comments
if the commit you want to absorb is HEAD, then you can now, if you want to absorb a range of commits that doesn't end at HEAD, life gets a bit more complicated. eg suppose you have a sequence of commits like this:
now, suppose you want to absorb 3333333 and 4444444 (into 1111111 and 2222222), but not 5555555. if 4444444 and 5555555 commute, then you can reorder them to the top (eg with an interactive rebase), reset --soft, and absorb, so that's still pretty easy. but if they don't commute, you would have to remove 5555555 altogether to run the absorb on 3333333 and 4444444 (eg with an interactive rebase all of this is possible with the existing algorithm - there's nothing fundamentally novel here - but it's mechanically complicated. and in addition, rewording commits is probably going to be an annoying amount of code. so i don't think i'm interested in implementing this myself, and if someone were to submit a pr for it, it would have to be pretty high quality (to compensate for how much new code it would be adding). if this is a problem you have often, the reset --soft approach is probably the most practical way forward. (you might also have an easier time writing a script around interactive rebases than you would trying to implement this feature directly in git absorb.) |
Thank you for sharing this detailed reply! Your explanation makes it clear why you (or anyone) would be reluctant to add this complexity to On reflection I realized I didn't share my use case for why I would want such a feature: Sometimes I find myself making several changes and realizing afterwards that I should commit them separately. I then select some of those changed files, commit those, and repeat, ending up with a stack of tiny commits at the end that need to be I wrote this feature request because I didn't see flags on I wish I could be the person to put up a PR but my desire to learn Rust keeps getting overshadowed by real-world necessities. If you'd like I will close this ticket as to not clutter up your issue list. |
oh that's interesting... i think i'm open to that. it would be a pretty modest change ("find the first commit that any hunk in this commit does not commute with"), and it seems useful to have some plumbing flags that let you pull the algorithm out for scripting. let's leave this issue open |
@arkban commented on May 31, 2021 1:44 AM:
Don't you mean the latest commit? If the latest commit before X is called Y, then X will not commute with any ancestors of Y either. In case this feature does not appear in git-absorb soon, I hope @tummychow will not mind me mentioning git-deps, a project I wrote which takes a very different approach to roughly the same problem (it uses git blame instead of testing commutativity, as mentioned in #8). It has a very simple example script called Having said that, my intention of mentioning it here is not to "steal" users from git-absorb, which is an excellent project, and certainly has advantages over the blame-based heuristic which git-deps uses. I think both tools have benefits in different situations, and it's always good to have a choice :-) |
Good catch, you are correct, I meant "latest"; I wrote some of this response while being peppered with questions about Sailor Moon lore by my daughter who was supposed to be asleep ;) |
I realized I also wanted this feature because sometimes I type |
In this kind of scenario git autosquash will solve your issue |
You can do this with
You will then get your commit replaced with a bunch of fixup commits in the history, you can then |
Yeah, after doing this a lot I wrote myself a [alias]
# better `fixup` based on 'git-absorb' https://github.com/tummychow/git-absorb/
# Changes made by this mini script:
# - Stages all changes (because I always forget to do that)
# - sets the `--base` to the HEAD of the followed branch (so it does not fix older commits)
# - automatically invokes interactive rebase
# - Keeps empty commits to ensure a smooth squash (at least tries too...)
# - Rebases away any empty commits left by the autosquash
# See:
# - https://stackoverflow.com/a/50122618/11889
fixup = "!f() { \
trap 'echo >&2 ERROR: Operation failed; return' ERR; \
command -v git-absorb >/dev/null 2>&1 || { echo >&2 'git-absorb needs to be installed!'; exit 1; }; \
UPSTREAM=$( git branch $( git branch --show-current ) --list --format '%(upstream)' ); \
git add -A; \
git-absorb --verbose --force --base $UPSTREAM; \
git rebase --interactive --autosquash --allow-empty --keep-empty $UPSTREAM; \
git rebase --empty=drop --no-keep-empty --no-allow-empty; \
}; f" I'm posting it here in case someone else wants to crib from this, and I think at this point the feature "exists" and this issue can be considered resolved. |
It would be nice to allow "absorbing" existing commits, i.e. I already committed a minor change, I'd like to have
git-absorb
identify which previous commit it should be absorbed into.Example, assume I have already committed my small fixes into the last commit:
I'd like to do something like:
And then have the log look like:
So I can then use
--autosquash
:Might something like that be possible?
The text was updated successfully, but these errors were encountered: