
A walk through the Magit interface - rohitpaulk
https://emacsair.me/2017/09/01/magit-walk-through/
======
iLemming
What truly makes Magit powerful (like many things in Emacs) that it is
extremely extensible.

Example:

When I'm ready to commit my changes:

I can spin-off a new branch:

\- If I have an Org-mode task that I'm currently clocked-in, it can check if
it contains a ticket number, then query the issue-tracking system and generate
a branch name based on the description.

All it takes is pressing two buttons: `b s`, and the rest is done
automatically

\- I commit my changes, it can use a template and fill out the details, I just
need to add a description. I can even make it so it compliant with git-commit
format enforcer like gommit. I can add fields like reported-by, cc, etc. with
a single keystroke;

\- If I suddenly find out that I forgot to add something, I don't have to
amend, I don't have to modify the commit, I can just stage my change and press
`c e` - "extend". It will quietly add it to my previous commit.

\- Using Forge I can create a PR. Once I push the PR, I can trigger a request
to issue-tracker that marks the ticket as in "code review"

There are bunch of things that other Git clients can't do* and even when they
do it, it's not so easy to extend them to work with different projects, issue-
tracking systems, etc.

* e.g. you can select a bunch of files in Dired and see git log pertaining changes only to those files [https://twitter.com/iLemming/status/1193025618742349824](https://twitter.com/iLemming/status/1193025618742349824)

~~~
amluto
> If I suddenly find out that I forgot to add something, I don't have to
> amend, I don't have to modify the commit, I can just stage my change and
> press `c e` - "extend". It will quietly add it to my previous commit.

Unless I’ve thoroughly misunderstood you, what you’re saying is that “c e” is
equivalent to “git commit --amend”. This sounds suspiciously like
“amend[ing]”.

Sure, git’s user interface is somewhere between mediocre and abysmal, but it’s
not really clear to me that “c e” is a vast improvement.

I say this as a former org-mode user and even one-time contributor. Eventually
I decided that the sheer number of magic incantations I had to remember to do
anything useful wasn’t worth it.

~~~
mgalgs
It's actually `git commit --amend --no-edit`, but yes, it's basically "just" a
shortcut. Count the keystrokes, though. If you spend much time working with
git it's a huge win.

Of course you could do something similar with shell aliases or reverse search,
but then there are other switches and flags that you need occasionally, etc.
And it's sooo much more convenient to have everything in one place right in
your editor. It's almost unfair how much faster I can get stuff done than
folks who don't use it ;)

Magit isn't hype, it's as good as everyone says it is. You just have to try
it.

~~~
williamdclt
If you spend much time with Git, you create aliases.

Not saying that Magit isn't worth it (never used it), but it's not a fair
comparison. I don't `git commit --amend --no-edit`: I `git amend` to edit the
last commit, `git amend HASH` to edit any commit, `git amend -i` to pick a
commit to edit in a searchable list with preview of their content.

~~~
mgalgs
> git amend HASH

That's 9 characters plus the effort of finding and copy/pasting the hash. With
magit it's two characters and you just focus on the hash in question.

> `git amend -i` to pick a commit to edit in a searchable list with preview of
> their content

That's cool! Still a lot more typing than with Magit, which also has a
searchable list with content previews ;)

I'm happy that you've found ways to optimize your workflow, but seriously,
Magit is still faster.

------
trey-jones
The granularity of staging and unstaging code, combined with the ease of doing
things within the text editor that you're already using anyway are really
great. I held off using Magit because I thought learning Emacs would be enough
by itself, but Magit is intuitive and easy and I really love it. Made my git
usage much more efficient within days of starting to use it.

~~~
tetris11
Same but one caveat that still bothers me about it is that it's not a
scriptable package.

I can't hook a function to automatically git pull changes when I open it
because the pull command only works when the buffer is up.

I'm sure there is some magic to set the current buffer, but for me this is not
trivial.

Ideally (magit-diff "myfile.py") should be all I need to do.

~~~
iLemming
> Same but one caveat that still bothers me about it is that it's not a
> scriptable package.

What are you talking about? It's written in Emacs-lisp, the possibilities are
virtually limited only by Emacs's capabilities. Explain what you're trying to
do, maybe post your problem to emacs.stackexchange, r/emacs. I'm sure people
would be able to help you.

------
downerending
Don't miss "Staging parts of a hunk", which is Magit's killer feature, IMO.
You can easily go through your current diff (from staged) and add/remove
single lines from the staged delta.

~~~
sigjuice
Staging (and committing?) parts of a hunk is cool and I have done this many
times myself. However, I am always uncomfortable with it because I am unsure
how to incorporate it within the overall workflow. I'd like each commit of
mine to at least compile and pass some tests.

~~~
RustyRussell
I agree: what I often want is _stash_ of selective parts, so I can test the
current stuff before commit.

~~~
celeritascelery
Magit supports this as well. In fact you can stash the index and working tree
separately. Even CLI got cant do that.

------
zaiste
I make short YouTube videos about Emacs. I've recently done some Magit and
Forge related ones [1]. I record what I learnt, so it's far from perfect.
Hopefully this helps someone.

[1]:
[https://www.youtube.com/watch?v=7ywEgcbaiys&list=PLhXZp00uXB...](https://www.youtube.com/watch?v=7ywEgcbaiys&list=PLhXZp00uXBk4np17N39WvB80zgxlZfVwj&index=18)

------
jacobsenscott
I love magit. If you deal with a lot of PRs the forge extension is also very
nice.

My only beef is the main interface can feel very slow sometimes.

I've learned to start using the functions directly from the M-x command line
when I can. Like rather than going to the main magit interface to stage a
file, just M-x stage-file. Time to stash? M-x magit-stash, etc. No need to
jump to the main magit UI much of the time.

~~~
flocial
It chokes when there are a large number of changes too because it's cycling
through all the individual diffs that are initially hidden. I honestly wish
there was a sparse mode to keep the initial magit status buffer as minimal as
"git status".

~~~
celeritascelery
You can also use `C-g` to interrupt the diffing algorithm if you just want to
get to the minimal git status buffer. In fact that is the recommended way to
deal with it.

------
Myrmornis
Magit is great, I’ve used it every day for 10 years or something. There’s just
one thing I haven’t got used to:

1\. Stage some stuff

2\. Start writing the commit message

3\. Stage something else

4\. Commit

The content staged at (3) doesn’t make it into the commit. This doesn’t fit my
mental model from the command line: I think of “commit” as transfer all the
staged content into a commit.

Initially magit didn’t do this, but I know it is intentional, and in fact the
magit author has explained to me that it accurately reflects the command line.
But I just seem totally unable to get used to it! I might even change it
locally.

~~~
iLemming
Seems you need to get comfortable with rebasing. Don't think about your
commits (especially if you haven't pushed them out) like something carved in
stone.

When I work, depending on what I'm doing I either commit often and don't think
much about it and then later rebase and group things into meaningful chunks of
work, or I just keep committing into a single commit and then at some point
break it apart into smaller commits.

Most often though I do try to keep commits nice and clean from the get-go, and
very often I want to add something into a commit that's a few hashes away from
the HEAD. In that case I would just rebase/modify with autostash option. It
will stash everything and get into rebase mode, I'll go into the stash, select
things I want to be included in the commit and press `a`, then I continue
rebasing, it will modify the commit, un-stash and get me to the point where I
was before.

~~~
Myrmornis
Thanks but sorry, you've missed the point of my post. If you have time, please
read it again. I'm pointing out that, if you think of C-c C-c in the commit
buffer as being "commit", then there's an uncomfortable conclusion: magit
doesn't put everything that is currently staged into the commit. Instead what
magit does is freeze the contents of the commit when you open the commit
message composition buffer, so anything staged subsequently doesn't make it
into the commit.

(In my original message I do say i've been using magit daily for 10 years; i'm
extremely familiar with all the rebasing operations you mention. i agree
they're very useful and i use them multiple times a day.)

~~~
iLemming
No, I think I get what you want the first time I read it. So I did a little
experiment (just to make sure I'm not wrong about it). I did everything in the
command line. I staged a file, then run git commit, when it opened the editor,
I switched to another terminal window and staged another file. Then I switched
back and finished committing. And surely enough, just as I expected - git did
not commit two files, but only one and the other stayed staged.

So the feature you're asking is not even supported by Git.

And the reason you want that feature, because Magit has spoiled you - when
almost everything is nonlinear (unlike with git cmd), you want to extend it
even further. Let's be pragmatic, don't complain that it is great that Tesla
has autopilot option but you actually wanted it to be an amphibious vehicle,
because you live next to a lake.

~~~
Myrmornis
Right, exactly. What you describe makes sense and is the reason why magit does
what it does.

Now, note that you ran `git commit`, with no arguments. Let's think about an
alternative narrative on the command line, involving `git commit -m
"$message"`

1\. Stage a file.

2\. Start drafting your commit message.

3\. Stage another file.

4\. Finish drafting your commit message.

5\. Issue git commit -m "$message"

This time, both files make it into the commit.

So basically, we are now thinking of the Magit commit composition buffer as a
place where you draft a work-in-progress commit message.

I think we can both agree that the idea of having a place where you can draft
your commit message, and meanwhile alter the contents of the staging area, is
not unreasonable. Perhaps as an alternative to the standard flow.

So my question to you (and those who might consider working on magit code) is:
what advantages does the other model have? (other than it mirroring `git
commit` with no arguments). Would one ever really want to mess about with the
contents of the staging buffer while you have a pending commit message that
you have not yet actually committed? Isn't it in fact more likely that what
you want to do, while that commit message is pending, is _alter_ the details
of what will be committed?

~~~
iLemming
Sorry, the "problem" you have is just too alien to me personally. I never had
any issues with that feature of Magit, never thought about it until now. Maybe
there are people just like you who'd say it's important to them - I can't
relate, once again: my apologies.

I'm sure this can be "fixed" by writing some non-trivial Emacs lisp by tapping
into `with-editor-finish` or `magit-commit` functions. But honestly, is that
worth your time?

Emacs is weird, it makes you want weird things. So many times I would find
myself irritated by "an issue" that I just stumbled on, I would write some
emacs lips to fix the problem (just because I can), only later to realize
there's no problem to begin with.

~~~
Myrmornis
There's no need to apologize! It's just two different possibilities for the
design of Magit. I already wrote the code this morning to do this as a quick
hack. It's just a few lines and I've been writing lots of emacs lisp recently,
so it didn't cost me much time. The question is whether it would be useful as
a setting for other magit users. Like I say, I can see arguments for this
(being able to update you commit in conjunction with working on the commit
message) but neither of us have suggested an advantage of the other model yet.

    
    
      (defun myrmornis--magit-commit-staged ()
        (interactive)
        (let ((commit-message (buffer-string)))
          (let ((with-editor-cancel-message ""))
            (with-editor-cancel nil))
          (with-temp-buffer
            (insert commit-message)
            (goto-char (point-min))
            (delete-matching-lines "^[ \t]*#") ;; hack
            (magit-run-git-with-input "commit" "-F" "-")))
        (magit-refresh-all))
    
      (use-package magit
        :bind (:map with-editor-mode-map
               ("C-c C-c" . myrmornis--magit-commit-staged))

~~~
iLemming
I apologized so it is clear that I'm not rejecting your idea due to my shallow
thinking. Maybe you are trying to convey a story that potentially opens wide-
range of possibilities and I just don't see it.

As I said, maybe there are people who'd find it extremely useful. Would you
mind sharing your "hack" in
[https://github.com/magit/magit](https://github.com/magit/magit) or
[https://gitter.im/magit/magit](https://gitter.im/magit/magit) ?

------
mark_l_watson
I have only briefly used Magic, but after reading your article, I am
committed. Thanks!

~~~
habnds
probably only "staged" at this point

------
amiga_500
Magit is amazing. When I use cmd line git now, I feel like a lesser primate.

------
mkesper
Very nice article. I was distracted by mentioning themes right at the
beginning, though.

------
Myrmornis
I still use the command line for log and show since they are slower in magit,
and this is noticeable in large repos.

~~~
iLemming
Do you limit number of commits? I set mine to 250, and even that is too big of
a number, I usually don't need to see that many commits at once. By not doing
it in Magit, you're missing many benefits.

Examples:
[https://twitter.com/iLemming/status/1193025618742349824](https://twitter.com/iLemming/status/1193025618742349824)
[https://twitter.com/iLemming/status/1058507342830923776](https://twitter.com/iLemming/status/1058507342830923776)

Also you can run any arbitrary git command from Magit dispatch, just press `!`

