Say I've made a number of unrelated changes to uncoupled files in my git repo. I want to review and commit each of the files separately.
I run magit-status
, and get a list of changed files. But the only magit diff commands I can find (d
and D
) diff entire revisons, not individual files.
I want the output of git diff <filename>
, but in the magit diff buffer. How can I get magit to diff only one file?
Magit enables you to "review and commit each of the files separately" directly from the magit-status
buffer, without the need for any separate diff buffers.
You just expand the file(s) you're interested in (with TAB, which shows you the diff for the file at point); then you can stage the bits of it that you want to commit (either the whole file, or individual hunks, or even a marked region) with s to stage (or u to unstage). Repeat for all the changes involved in that commit and, once everything necessary has been staged, press c to begin the commit.
You might prefer the visibility cycling behaviour you get by using C-TAB (repeatedly) instead of the simple toggle you get by default with TAB.
If you really do want to view the diff for a file in a separate buffer, you can do that from the file's buffer by calling magit-diff-buffer-file
directly, or using the "diff" option (d) in magit-file-popup
. e.g.:
(global-set-key (kbd "C-c m d") 'magit-diff-buffer-file)
(global-set-key (kbd "C-c m f") 'magit-file-popup)
Also note @assem's comment below:
You might also be interested in
magit-ediff
which is bound to e by default, and opens an ediff session for the diff/file at point.
Some other alternatives available in Emacs by default (i.e. not Magit) are:
vc-diff
vc-ediff
for the ediff equivalentediff-revision
to create an ediff session with more optionsI bind vc-ediff
to C-xvC-= so that the two variants have similar key bindings.
I recommend watching the video by the creator of magit. It's 20 min and it shows you the work-flow as it was intended.
Also, a small tip: you can use 1 2 3 to change the diff verbosity of the current heading.
Another small tip: if you're not happy with the size of the hunks,
you can stage arbitrary regions by - that's right - marking a
region and pressing s. It's magic.
I didn't know about this option for a while, I was actually
dropping back to console and doing git add -p
the old fashioned way.
There are definitely advantages to not going against the grain when using tools, as is exemplified by the other answers.
On the other hand, sometimes you just want to tell your editor what to do, and have people on the internet answer your questions instead of telling you want to do something else.
magit provides a menu interface for doing things to the current file through M-x magit-file-popup
. The keys you need to press from here are "du". This may well be too many key presses for you, if this is the case you can call magit-diff
directly like so:
(defun magit-diff-given-file (&optional file)
(interactive)
(unless file
(setf file buffer-file-name))
(magit-diff-working-tree "HEAD" nil (list (file-relative-name file (magit-toplevel file)))))
You might like to define your own function and keybinding for this.
magit-diff
has advantages over vc-diff
because if allows you to jump to the location of the diff.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With