4

I prefer to have small and focused commits but don't always code that way. I've got a code section to the effect of

if abc:
    def
etc

I edited def and etc, and the hunk in magit shows both as removed and then the edited parts as inserted.

@@ -1,3 +1,3 @@
 if abc:
-    def
-etc
+    ghi
+etc...

I want to make one commit with just the def edit, but as it is it removes def and inserts the new version after etc when I select those lines manually.

How can I create one commit that results in code

if abc:
    ghi
etc...

instead of

if abc:
etc...
    ghi

Would committing the remove of def and ammending with the add of ghi be the only way to do it?

  • 1
    Fun question!! To clarify, you want (1) commit def->ghi first? (2) commit etc->etc... in a second commit? (3) But the problem is the sections are swapped because of the order the commits are applied? – Melioratus Aug 28 '18 at 15:57
  • After reading your question again, I think I have a better idea what you're asking. – Melioratus Aug 28 '18 at 23:16
4

It's possible in Magit, though how to do so isn't obvious or straightforward. Call magit-ediff-dwim (e) on the unstaged hunk. This will bring up three windows. One of them (B, at least for me) is labeled as the index. Switch to the index window and change the content to match what you want to stage. For example, change it to

if abc:
    ghi
etc

to stage just the "def" -> "ghi" change.

Then switch back to the ediff control panel buffer and quit the ediff session with q, confirming the update the index when you are asked.

After you commit those staged changes, your unstaged changes will be

 if abc:
     ghi
-etc
+etc...

which you can stage and commit as usual.


Note that there's been some previous discussion related to this on the Magit issue tracker (gh-2165, gh-2173, gh-2718). There's also an open feature request to add support for editing diffs (gh-2938), which would provide an alternative way to achieve what you're after.

  • I have some weird bugs when I try this. First only the ediff control panel buffer appears, the rest of the screen is black. I managed to solve this by opening the Ediff manual (E) but that closed the control panel buffer. It looks like it works and staged my desired commit but emacs crashed immediately. Even stranger repeating the process doesn't cause the same bugs, but the ediff control panel is in a different frame. Do I have to retype everything I want to stage in the index? – Gooby Aug 30 '18 at 13:19
  • re: ediff issues, sorry, I can't say more than the unhelpful "works on my end". If you can provide steps to reproduce it and it seems specific to Magit's call of ediff, please open a report on Magit's issue tracker. re: retyping, you can manually copy the text over from the working tree's buffer (ediff panel C). AFIAK ediff's handy "copy hunk from X to Y" won't work because, like Git and Magit, ediff can't split the hunk any further. – Kyle Meyer Aug 30 '18 at 22:12
  • Considering as soon as I managed to stage something through it it appears to have gone away, I doubt I can reproduce it. Regardless of the issues I ran into Ediff did exactly what I wanted, so thanks! – Gooby Aug 31 '18 at 13:14

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.