reddit / emacs

How to modify a previous commit with Magit? I can't stage my additions!

alessandrobertulli · 2022-07-21 12:26
Hi all, sorry for the newbie quetion, I thought I got this but clearly I was wrong. So basically I want to modify a previous commit in my repo (by adding some modifications I already have in my workspace). Following a suggestion from Magit's author (here [https://emacs.stackexchange.com/a/22565/29817](https://emacs.stackexchange.com/a/22565/29817)), Magit seems to have a command that should work pretty well for me: \`magit-rebase-edit-commit\`, bound by default to \`r m\`. Point is, when I do that, I see the buffer you see in the picture. If I need to add some lines to this commit, what should I do, since there's no "Unstaged files" section? https://preview.redd.it/4owtx6p9zwc91.png?width=674&format=png&auto=webp&s=149f2a30930da94d5265d08340d435dab1904d6d
wolfjb · 2022-07-21 13:08
Maybe the reword option under commit? (c then w)
Walheimat · 2022-07-21 13:28
The rebase probably autostashes. You would see unstaged changes if you made them at this point. So you could try popping your stash. Or you create a commit of your changes, rebase, move that commit below the one to extend, make it a fixup, optionally make the other one a reword.
alessandrobertulli · 2022-07-21 13:51
You're right, it autostashes indeed. But the question remains: if I want to apply part of my workspace to that commit, do I then need to * stash the modification I want to add * call magit-rebase-edit-commit * pop the stash, commit and continue/finish the rebase?
alessandrobertulli · 2022-07-21 13:53
It works, but I need to actually modify the file with some modifications I already have in my workspace. Thanks for pointing that out though, I'll edit my question.
dj_goku · 2022-07-21 14:30
You should be able to c m or commit amend while staging your changes. Another option is to interactive rebase and un-stage a commit and add/modify/delete and commit again.
alessandrobertulli · 2022-07-21 14:50
**BTW**, looks like `magit-commit-instant-fixup`, buond to `c F`, is what I was looking for. However, after trying it, I think I understand why Tarsius kept the normal rebase workflow as generic as possible, and why the "edit a commit" option works this way. So I think the hypothesis I laid out in the previous answer is indeed the idiomatic one, thanks u/Walheimat for the suggestion!
Walheimat · 2022-07-21 14:51
That should work. I usually do what I described, create a new fixup commit and reorder with `r i` (interactive rebase).
alessandrobertulli · 2022-07-21 14:53
Indeed, stage -> commit (instant fixup) was the answer I was looking for, thank! (see [this answer thread](https://www.reddit.com/r/emacs/comments/w4ff84/comment/ih22edm/?utm_source=share&utm_medium=web2x&context=3))
ieure · 2022-07-21 15:18
`c a` will add the staged changes to the changes to the most recent commit. `c F` will let you pick a commit further back to add them to.
by_wicker · 2022-07-21 18:22
No, the `fixup` (`c f`) and `instant fixup` is completely idiomatic and generic and what you are asking for. Editing a commit is different - it's when you want to perhaps split a commit into many commits or something, or move some of the commit to another commit. I'm puzzled what's not working for you though. I use fixups all the time - stage what you want to add to the commit, and then `c F` and select the target commit in history.
alessandrobertulli · 2022-07-21 20:26
Yes, now is clearer, thank you. I just thought that "modify a commit" was referring to fixup, but since I didn't know "fixup" was the correct term, I was looking at the wrong option. 🙂 Btw, if I wanted to split a commit in half, what should I do?
by_wicker · 2022-07-21 21:20
I think there are a number of ways to skin the cat - I haven't typically used `r m` (rebase - modify a commit) but I may start, as I think that does the same thing as an interactive rebase `r i` and selecting `e` on a commit for `edit`, but with fewer steps. Whichever way you get there you then find yourself in a rebase with that commit at the top of the history. I'd reset to the next commit with `x` to uncommit the offending changes, then do whatever I wanted, e.g. `fixup` parts of it into other commits, or split it into two or more new commits, or whatever, and when that's all done continue the rebase with `r r`. e.g. I have commits: - A - B - C - D And I realize I put something in `B` that should have been in `D`. - I do `r m` with the cursor on `B` in history or status - I move to the next commit, `C`, in history or status, and reset to it with `x`; now I have the contents of `B` uncommitted. - I would take the offending edits, stage them, do `c f` to put them in as a fixup to `D` (I think instant fixups won't work, nesting rebases...?) - then do `c c` to re-commit the remainder of B. History in the commit message buffer via `m-p` will let me reselect the former `B` commit message - now my edit is done and I do `r r` to complete the rebase - If I made fixup commits I may have to do another quick `r i` to collapse them Hit me up if I've got this wrong - I'm explaining this mostly from memory. (Edit: and I did - I said `c m` when I meant `r m`) (for all rebasing, I find it really nice to have `--autostash` and `--autosquash` set on by default)
SigmaScape · 2022-07-21 21:31
1 - do your changes 2 - stage them 3 - c F to commit+apply on a commit 4 - the list of commit of the branch will pop, move your cursor to the line representing the commit to edit 5 - Cc Cc to apply this edit on the commit directly
alessandrobertulli · 2022-07-21 21:34
Thanks, right now I can't follow you with my PC but you're giving me a lot to further investigate. Thanks a lot, I'll let you know if I have any comment. 😄
7890yuiop · 2022-07-21 23:52
> `magit-rebase-edit-commit`, bound by default to `r m`. Point is, when I do that, I see the buffer you see in the picture. Yes, it does a rebase and stops to let you edit that commit. Now you need to edit it. Make your changes. Stage them. Then amend the current HEAD commit with `c a`. Then `r r` to continue the rebase (completing it, barring any conflicts with the later commits).