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).