16

With Magit you can open the magit status buffer, press TAB to expand the diff (or RET to bring up a separate diff buffer), mark parts of a hunk and press s or u to stage/unstage the region. Really nice.

I'd like to know if it's possible to:

  • edit a file
  • select a region, hunk or several hunks right inside the file buffer
  • stage/unstage the selected region or the hunk around point
tarsius
  • 25,685
  • 4
  • 70
  • 109
Nsukami _
  • 6,521
  • 2
  • 23
  • 35
  • You seem a bit confused about hunk vs. region. I have edited you description of what magit does and your questions. I might not have guessed correctly what you intended to ask, though. – tarsius Jan 04 '15 at 23:37
  • @tarsius Maybe I'm confused, for me a region is what I've just selected inside the buffer, and the hunk is the selected region ready for being staged. Am I wrong? – Nsukami _ Jan 04 '15 at 23:57
  • 2
    "Region" is an Emacs term, it's the thing in between the point and mark, i.e. "the selection". "Hunk" is a Git term, it begins with e.g "@@ -1,1 +1,1" and ends right before the next such heading which begins a new hunk. Magit highlights the current section (which may be a hunk section) much in the same way Emacs generally highlights the region, so that might have contributed to your confusion. – tarsius Jan 05 '15 at 00:00
  • 1
    In a magit status or diff-only buffer you can stage the current hunk regardless of where inside the hunk you are simply by pressing s. But you can also stage just part of the hunk, by marking parts of it (the same way you would do that in a file-visiting buffer) and then stage just that. – tarsius Jan 05 '15 at 00:04
  • @tarsius exactly what I mean, my english is just not sharp enough. – Nsukami _ Jan 05 '15 at 00:04

2 Answers2

11

No, Magit does not support that. Future versions might though. Git-Gutter does support it now. The command is named git-gutter:stage-hunk.

tarsius
  • 25,685
  • 4
  • 70
  • 109
  • While this does stage a hunk, it doesn't stage a region. – ocodo Mar 12 '15 at 04:22
  • I find it's best to create a binding to stage a hunk, then another to jump to the next hunk, stage, and repeat. There's also a way to stage an entire buffer, but at that point you might as well be doing it from the command line. I find it's best to make commits at the block level with git-gutter + magit. Larger changes aren't suited for git-gutter. – yurisich Aug 31 '16 at 17:18
1

As mentioned earlier, git-gutter is an extension designed for showing you git information directly in your file, and operating from there, whilst magit focuses on operating on diffs.

This feature isn't planned for git gutter any time soon (https://github.com/syohex/emacs-git-gutter/issues/91)

However it's the sort of thing that emacs lisp should be very good at wiping up (go through the hunks in a region and stage them out a time). Trying this myself this was almost the case, the only problem was git-gutter kicks off a background process after you stage a hunk and doesn't wait for it to finish, so I had to add a little hacky magic to deal with this.

The following emacs lisp function should do what you want. You might want to bind it to some keys.

(defun my-git-stage-region ()
  (interactive)
  (let ((git-gutter:ask-p nil)
        (start (region-beginning))
        (end (region-end)))
    (save-excursion
      (goto-char start)
      (git-gutter:next-hunk 1)
      (while (< (point) end)
        (git-gutter:stage-hunk)
        ;; This is a hack to wait for git-gutter to finish
        ;; updating information (git-gutter kicks
        ;; of a process to update the diff information
        ;; and does not block)
        (while (get-buffer (git-gutter:diff-process-buffer (git-gutter:base-file)))
          (sit-for 0.05))
        (git-gutter:next-hunk 1)))))
Att Righ
  • 775
  • 4
  • 14
  • NOTE: This cannot split up hunks, hunks are either completely staged or not staged at all. However git-gutter tends to have relatively small hunks, which is precisely why I implemented this feature. – Att Righ Dec 12 '16 at 12:23